| ... | @@ -112,6 +112,8 @@ func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{}, | ... | @@ -112,6 +112,8 @@ func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{}, |
| 112 | functions: std.AutoArrayHashMapUnmanaged(struct { file: ?u16, index: u32 }, std.wasm.Func) = .{}, | 112 | functions: std.AutoArrayHashMapUnmanaged(struct { file: ?u16, index: u32 }, std.wasm.Func) = .{}, |
| 113 | /// Output global section | 113 | /// Output global section |
| 114 | wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{}, | 114 | wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{}, |
| | 115 | /// Global symbols for exported data symbols |
| | 116 | address_globals: std.ArrayListUnmanaged(SymbolLoc) = .{}, |
| 115 | /// Memory section | 117 | /// Memory section |
| 116 | memories: std.wasm.Memory = .{ .limits = .{ .min = 0, .max = null } }, | 118 | memories: std.wasm.Memory = .{ .limits = .{ .min = 0, .max = null } }, |
| 117 | /// Output table section | 119 | /// Output table section |
| ... | @@ -839,6 +841,7 @@ pub fn deinit(wasm: *Wasm) void { | ... | @@ -839,6 +841,7 @@ pub fn deinit(wasm: *Wasm) void { |
| 839 | wasm.func_types.deinit(gpa); | 841 | wasm.func_types.deinit(gpa); |
| 840 | wasm.functions.deinit(gpa); | 842 | wasm.functions.deinit(gpa); |
| 841 | wasm.wasm_globals.deinit(gpa); | 843 | wasm.wasm_globals.deinit(gpa); |
| | 844 | wasm.address_globals.deinit(gpa); |
| 842 | wasm.function_table.deinit(gpa); | 845 | wasm.function_table.deinit(gpa); |
| 843 | wasm.tables.deinit(gpa); | 846 | wasm.tables.deinit(gpa); |
| 844 | wasm.exports.deinit(gpa); | 847 | wasm.exports.deinit(gpa); |
| ... | @@ -1804,7 +1807,15 @@ fn setupExports(wasm: *Wasm) !void { | ... | @@ -1804,7 +1807,15 @@ fn setupExports(wasm: *Wasm) !void { |
| 1804 | if (sym_loc.file == null) break :blk symbol.name; | 1807 | if (sym_loc.file == null) break :blk symbol.name; |
| 1805 | break :blk try wasm.string_table.put(wasm.base.allocator, sym_name); | 1808 | break :blk try wasm.string_table.put(wasm.base.allocator, sym_name); |
| 1806 | }; | 1809 | }; |
| 1807 | const exp: types.Export = .{ | 1810 | const exp: types.Export = if (symbol.tag == .data) exp: { |
| | 1811 | const global_index = @intCast(u32, wasm.wasm_globals.items.len + wasm.address_globals.items.len); |
| | 1812 | try wasm.address_globals.append(wasm.base.allocator, sym_loc); |
| | 1813 | break :exp .{ |
| | 1814 | .name = export_name, |
| | 1815 | .kind = .global, |
| | 1816 | .index = global_index, |
| | 1817 | }; |
| | 1818 | } else .{ |
| 1808 | .name = export_name, | 1819 | .name = export_name, |
| 1809 | .kind = symbol.tag.externalType(), | 1820 | .kind = symbol.tag.externalType(), |
| 1810 | .index = symbol.index, | 1821 | .index = symbol.index, |
| ... | @@ -2473,10 +2484,22 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -2473,10 +2484,22 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 2473 | if (wasm.wasm_globals.items.len > 0) { | 2484 | if (wasm.wasm_globals.items.len > 0) { |
| 2474 | const header_offset = try reserveVecSectionHeader(&binary_bytes); | 2485 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 2475 | | 2486 | |
| | 2487 | var global_count: u32 = 0; |
| 2476 | for (wasm.wasm_globals.items) |global| { | 2488 | for (wasm.wasm_globals.items) |global| { |
| 2477 | try binary_writer.writeByte(std.wasm.valtype(global.global_type.valtype)); | 2489 | try binary_writer.writeByte(std.wasm.valtype(global.global_type.valtype)); |
| 2478 | try binary_writer.writeByte(@boolToInt(global.global_type.mutable)); | 2490 | try binary_writer.writeByte(@boolToInt(global.global_type.mutable)); |
| 2479 | try emitInit(binary_writer, global.init); | 2491 | try emitInit(binary_writer, global.init); |
| | 2492 | global_count += 1; |
| | 2493 | } |
| | 2494 | |
| | 2495 | for (wasm.address_globals.items) |sym_loc| { |
| | 2496 | const atom = wasm.symbol_atom.get(sym_loc).?; |
| | 2497 | try binary_writer.writeByte(std.wasm.valtype(.i32)); |
| | 2498 | try binary_writer.writeByte(0); // immutable |
| | 2499 | try emitInit(binary_writer, .{ |
| | 2500 | .i32_const = @bitCast(i32, atom.offset), |
| | 2501 | }); |
| | 2502 | global_count += 1; |
| 2480 | } | 2503 | } |
| 2481 | | 2504 | |
| 2482 | try writeVecSectionHeader( | 2505 | try writeVecSectionHeader( |
| ... | @@ -2484,7 +2507,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -2484,7 +2507,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 2484 | header_offset, | 2507 | header_offset, |
| 2485 | .global, | 2508 | .global, |
| 2486 | @intCast(u32, binary_bytes.items.len - header_offset - header_size), | 2509 | @intCast(u32, binary_bytes.items.len - header_offset - header_size), |
| 2487 | @intCast(u32, wasm.wasm_globals.items.len), | 2510 | @intCast(u32, global_count), |
| 2488 | ); | 2511 | ); |
| 2489 | section_count += 1; | 2512 | section_count += 1; |
| 2490 | } | 2513 | } |
| ... | @@ -2990,10 +3013,22 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -2990,10 +3013,22 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2990 | if (wasm.wasm_globals.items.len > 0) { | 3013 | if (wasm.wasm_globals.items.len > 0) { |
| 2991 | const header_offset = try reserveVecSectionHeader(&binary_bytes); | 3014 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 2992 | | 3015 | |
| | 3016 | var global_count: u32 = 0; |
| 2993 | for (wasm.wasm_globals.items) |global| { | 3017 | for (wasm.wasm_globals.items) |global| { |
| 2994 | try binary_writer.writeByte(std.wasm.valtype(global.global_type.valtype)); | 3018 | try binary_writer.writeByte(std.wasm.valtype(global.global_type.valtype)); |
| 2995 | try binary_writer.writeByte(@boolToInt(global.global_type.mutable)); | 3019 | try binary_writer.writeByte(@boolToInt(global.global_type.mutable)); |
| 2996 | try emitInit(binary_writer, global.init); | 3020 | try emitInit(binary_writer, global.init); |
| | 3021 | global_count += 1; |
| | 3022 | } |
| | 3023 | |
| | 3024 | for (wasm.address_globals.items) |sym_loc| { |
| | 3025 | const atom = wasm.symbol_atom.get(sym_loc).?; |
| | 3026 | try binary_writer.writeByte(std.wasm.valtype(.i32)); |
| | 3027 | try binary_writer.writeByte(0); // immutable |
| | 3028 | try emitInit(binary_writer, .{ |
| | 3029 | .i32_const = @bitCast(i32, atom.offset), |
| | 3030 | }); |
| | 3031 | global_count += 1; |
| 2997 | } | 3032 | } |
| 2998 | | 3033 | |
| 2999 | try writeVecSectionHeader( | 3034 | try writeVecSectionHeader( |
| ... | @@ -3001,7 +3036,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -3001,7 +3036,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3001 | header_offset, | 3036 | header_offset, |
| 3002 | .global, | 3037 | .global, |
| 3003 | @intCast(u32, binary_bytes.items.len - header_offset - header_size), | 3038 | @intCast(u32, binary_bytes.items.len - header_offset - header_size), |
| 3004 | @intCast(u32, wasm.wasm_globals.items.len), | 3039 | @intCast(u32, global_count), |
| 3005 | ); | 3040 | ); |
| 3006 | section_count += 1; | 3041 | section_count += 1; |
| 3007 | } | 3042 | } |