| ... | @@ -1333,6 +1333,10 @@ pub fn deinit(wasm: *Wasm) void { | ... | @@ -1333,6 +1333,10 @@ pub fn deinit(wasm: *Wasm) void { |
| 1333 | atom.deinit(gpa); | 1333 | atom.deinit(gpa); |
| 1334 | } | 1334 | } |
| 1335 | } | 1335 | } |
| | 1336 | for (wasm.synthetic_functions.items) |atom_index| { |
| | 1337 | const atom = wasm.getAtomPtr(atom_index); |
| | 1338 | atom.deinit(gpa); |
| | 1339 | } |
| 1336 | | 1340 | |
| 1337 | wasm.decls.deinit(gpa); | 1341 | wasm.decls.deinit(gpa); |
| 1338 | wasm.anon_decls.deinit(gpa); | 1342 | wasm.anon_decls.deinit(gpa); |
| ... | @@ -1364,10 +1368,6 @@ pub fn deinit(wasm: *Wasm) void { | ... | @@ -1364,10 +1368,6 @@ pub fn deinit(wasm: *Wasm) void { |
| 1364 | wasm.exports.deinit(gpa); | 1368 | wasm.exports.deinit(gpa); |
| 1365 | | 1369 | |
| 1366 | wasm.string_table.deinit(gpa); | 1370 | wasm.string_table.deinit(gpa); |
| 1367 | for (wasm.synthetic_functions.items) |atom_index| { | | |
| 1368 | const atom = wasm.getAtomPtr(atom_index); | | |
| 1369 | atom.deinit(gpa); | | |
| 1370 | } | | |
| 1371 | wasm.synthetic_functions.deinit(gpa); | 1371 | wasm.synthetic_functions.deinit(gpa); |
| 1372 | | 1372 | |
| 1373 | if (wasm.dwarf) |*dwarf| { | 1373 | if (wasm.dwarf) |*dwarf| { |
| ... | @@ -2134,9 +2134,13 @@ const Kind = union(enum) { | ... | @@ -2134,9 +2134,13 @@ const Kind = union(enum) { |
| 2134 | fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | 2134 | fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2135 | const atom = wasm.getAtomPtr(atom_index); | 2135 | const atom = wasm.getAtomPtr(atom_index); |
| 2136 | const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm); | 2136 | const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm); |
| | 2137 | if (symbol.isDead()) { |
| | 2138 | // Prevent unreferenced symbols from being parsed. |
| | 2139 | return; |
| | 2140 | } |
| 2137 | const final_index: u32 = switch (kind) { | 2141 | const final_index: u32 = switch (kind) { |
| 2138 | .function => result: { | 2142 | .function => result: { |
| 2139 | const index = @as(u32, @intCast(wasm.functions.count() + wasm.imported_functions_count)); | 2143 | const index: u32 = @intCast(wasm.functions.count() + wasm.imported_functions_count); |
| 2140 | const type_index = wasm.atom_types.get(atom_index).?; | 2144 | const type_index = wasm.atom_types.get(atom_index).?; |
| 2141 | try wasm.functions.putNoClobber( | 2145 | try wasm.functions.putNoClobber( |
| 2142 | wasm.base.allocator, | 2146 | wasm.base.allocator, |
| ... | @@ -2147,7 +2151,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | ... | @@ -2147,7 +2151,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2147 | symbol.index = index; | 2151 | symbol.index = index; |
| 2148 | | 2152 | |
| 2149 | if (wasm.code_section_index == null) { | 2153 | if (wasm.code_section_index == null) { |
| 2150 | wasm.code_section_index = @as(u32, @intCast(wasm.segments.items.len)); | 2154 | wasm.code_section_index = @intCast(wasm.segments.items.len); |
| 2151 | try wasm.segments.append(wasm.base.allocator, .{ | 2155 | try wasm.segments.append(wasm.base.allocator, .{ |
| 2152 | .alignment = atom.alignment, | 2156 | .alignment = atom.alignment, |
| 2153 | .size = atom.size, | 2157 | .size = atom.size, |
| ... | @@ -2185,12 +2189,12 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | ... | @@ -2185,12 +2189,12 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2185 | const index = gop.value_ptr.*; | 2189 | const index = gop.value_ptr.*; |
| 2186 | wasm.segments.items[index].size += atom.size; | 2190 | wasm.segments.items[index].size += atom.size; |
| 2187 | | 2191 | |
| 2188 | symbol.index = @as(u32, @intCast(wasm.segment_info.getIndex(index).?)); | 2192 | symbol.index = @intCast(wasm.segment_info.getIndex(index).?); |
| 2189 | // segment info already exists, so free its memory | 2193 | // segment info already exists, so free its memory |
| 2190 | wasm.base.allocator.free(segment_name); | 2194 | wasm.base.allocator.free(segment_name); |
| 2191 | break :result index; | 2195 | break :result index; |
| 2192 | } else { | 2196 | } else { |
| 2193 | const index = @as(u32, @intCast(wasm.segments.items.len)); | 2197 | const index: u32 = @intCast(wasm.segments.items.len); |
| 2194 | var flags: u32 = 0; | 2198 | var flags: u32 = 0; |
| 2195 | if (wasm.base.options.shared_memory) { | 2199 | if (wasm.base.options.shared_memory) { |
| 2196 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); | 2200 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); |
| ... | @@ -2203,7 +2207,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { | ... | @@ -2203,7 +2207,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2203 | }); | 2207 | }); |
| 2204 | gop.value_ptr.* = index; | 2208 | gop.value_ptr.* = index; |
| 2205 | | 2209 | |
| 2206 | const info_index = @as(u32, @intCast(wasm.segment_info.count())); | 2210 | const info_index: u32 = @intCast(wasm.segment_info.count()); |
| 2207 | try wasm.segment_info.put(wasm.base.allocator, index, segment_info); | 2211 | try wasm.segment_info.put(wasm.base.allocator, index, segment_info); |
| 2208 | symbol.index = info_index; | 2212 | symbol.index = info_index; |
| 2209 | break :result index; | 2213 | break :result index; |
| ... | @@ -2318,8 +2322,10 @@ fn allocateAtoms(wasm: *Wasm) !void { | ... | @@ -2318,8 +2322,10 @@ fn allocateAtoms(wasm: *Wasm) !void { |
| 2318 | fn allocateVirtualAddresses(wasm: *Wasm) void { | 2322 | fn allocateVirtualAddresses(wasm: *Wasm) void { |
| 2319 | for (wasm.resolved_symbols.keys()) |loc| { | 2323 | for (wasm.resolved_symbols.keys()) |loc| { |
| 2320 | const symbol = loc.getSymbol(wasm); | 2324 | const symbol = loc.getSymbol(wasm); |
| 2321 | if (symbol.tag != .data) { | 2325 | if (symbol.tag != .data or symbol.isDead()) { |
| 2322 | continue; // only data symbols have virtual addresses | 2326 | // Only data symbols have virtual addresses. |
| | 2327 | // Dead symbols do not get allocated, so we don't need to set their virtual address either. |
| | 2328 | continue; |
| 2323 | } | 2329 | } |
| 2324 | const atom_index = wasm.symbol_atom.get(loc) orelse { | 2330 | const atom_index = wasm.symbol_atom.get(loc) orelse { |
| 2325 | // synthetic symbol that does not contain an atom | 2331 | // synthetic symbol that does not contain an atom |
| ... | @@ -2681,10 +2687,10 @@ fn setupImports(wasm: *Wasm) !void { | ... | @@ -2681,10 +2687,10 @@ fn setupImports(wasm: *Wasm) !void { |
| 2681 | } | 2687 | } |
| 2682 | | 2688 | |
| 2683 | for (wasm.resolved_symbols.keys()) |symbol_loc| { | 2689 | for (wasm.resolved_symbols.keys()) |symbol_loc| { |
| 2684 | if (symbol_loc.file == null) { | 2690 | const file_index = symbol_loc.file orelse { |
| 2685 | // imports generated by Zig code are already in the `import` section | 2691 | // imports generated by Zig code are already in the `import` section |
| 2686 | continue; | 2692 | continue; |
| 2687 | } | 2693 | }; |
| 2688 | | 2694 | |
| 2689 | const symbol = symbol_loc.getSymbol(wasm); | 2695 | const symbol = symbol_loc.getSymbol(wasm); |
| 2690 | if (symbol.isDead() or | 2696 | if (symbol.isDead() or |
| ... | @@ -2695,7 +2701,7 @@ fn setupImports(wasm: *Wasm) !void { | ... | @@ -2695,7 +2701,7 @@ fn setupImports(wasm: *Wasm) !void { |
| 2695 | } | 2701 | } |
| 2696 | | 2702 | |
| 2697 | log.debug("Symbol '{s}' will be imported from the host", .{symbol_loc.getName(wasm)}); | 2703 | log.debug("Symbol '{s}' will be imported from the host", .{symbol_loc.getName(wasm)}); |
| 2698 | const object = wasm.objects.items[symbol_loc.file.?]; | 2704 | const object = wasm.objects.items[file_index]; |
| 2699 | const import = object.findImport(symbol.tag.externalType(), symbol.index); | 2705 | const import = object.findImport(symbol.tag.externalType(), symbol.index); |
| 2700 | | 2706 | |
| 2701 | // We copy the import to a new import to ensure the names contain references | 2707 | // We copy the import to a new import to ensure the names contain references |
| ... | @@ -3092,6 +3098,11 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3 | ... | @@ -3092,6 +3098,11 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3 |
| 3092 | .offset = 0, | 3098 | .offset = 0, |
| 3093 | .flags = flags, | 3099 | .flags = flags, |
| 3094 | }); | 3100 | }); |
| | 3101 | try wasm.segment_info.putNoClobber(wasm.base.allocator, index, .{ |
| | 3102 | .name = try wasm.base.allocator.dupe(u8, segment_info.name), |
| | 3103 | .alignment = segment_info.alignment, |
| | 3104 | .flags = segment_info.flags, |
| | 3105 | }); |
| 3095 | return index; | 3106 | return index; |
| 3096 | } else return result.value_ptr.*; | 3107 | } else return result.value_ptr.*; |
| 3097 | }, | 3108 | }, |
| ... | @@ -3198,6 +3209,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { | ... | @@ -3198,6 +3209,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { |
| 3198 | .virtual_address = undefined, | 3209 | .virtual_address = undefined, |
| 3199 | }; | 3210 | }; |
| 3200 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); | 3211 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| | 3212 | symbol.mark(); |
| 3201 | | 3213 | |
| 3202 | try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {}); | 3214 | try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {}); |
| 3203 | | 3215 | |
| ... | @@ -3230,6 +3242,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { | ... | @@ -3230,6 +3242,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3230 | .virtual_address = undefined, | 3242 | .virtual_address = undefined, |
| 3231 | }; | 3243 | }; |
| 3232 | names_symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); | 3244 | names_symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| | 3245 | names_symbol.mark(); |
| 3233 | | 3246 | |
| 3234 | log.debug("Populating error names", .{}); | 3247 | log.debug("Populating error names", .{}); |
| 3235 | | 3248 | |
| ... | @@ -3606,9 +3619,9 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -3606,9 +3619,9 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3606 | // So we can rebuild the binary file on each incremental update | 3619 | // So we can rebuild the binary file on each incremental update |
| 3607 | defer wasm.resetState(); | 3620 | defer wasm.resetState(); |
| 3608 | try wasm.setupInitFunctions(); | 3621 | try wasm.setupInitFunctions(); |
| 3609 | try wasm.setupErrorsLen(); | | |
| 3610 | try wasm.setupStart(); | 3622 | try wasm.setupStart(); |
| 3611 | try wasm.markReferences(); | 3623 | try wasm.markReferences(); |
| | 3624 | try wasm.setupErrorsLen(); |
| 3612 | try wasm.setupImports(); | 3625 | try wasm.setupImports(); |
| 3613 | if (wasm.base.options.module) |mod| { | 3626 | if (wasm.base.options.module) |mod| { |
| 3614 | var decl_it = wasm.decls.iterator(); | 3627 | var decl_it = wasm.decls.iterator(); |
| ... | @@ -5152,14 +5165,15 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void { | ... | @@ -5152,14 +5165,15 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void { |
| 5152 | return; | 5165 | return; |
| 5153 | } | 5166 | } |
| 5154 | | 5167 | |
| 5155 | const file = loc.file orelse return; // Marking synthetic and Zig symbols is done seperately | 5168 | const atom_index = if (loc.file) |file_index| idx: { |
| 5156 | const object = &wasm.objects.items[file]; | 5169 | const object = &wasm.objects.items[file_index]; |
| 5157 | const atom_index = try Object.parseSymbolIntoAtom(object, file, loc.index, wasm); | 5170 | const atom_index = try object.parseSymbolIntoAtom(file_index, loc.index, wasm); |
| | 5171 | break :idx atom_index; |
| | 5172 | } else wasm.symbol_atom.get(loc) orelse return; |
| 5158 | | 5173 | |
| 5159 | const atom = wasm.getAtom(atom_index); | 5174 | const atom = wasm.getAtom(atom_index); |
| 5160 | const relocations: []const types.Relocation = atom.relocs.items; | 5175 | for (atom.relocs.items) |reloc| { |
| 5161 | for (relocations) |reloc| { | 5176 | const target_loc: SymbolLoc = .{ .index = reloc.index, .file = loc.file }; |
| 5162 | const target_loc: SymbolLoc = .{ .index = reloc.index, .file = file }; | | |
| 5163 | try wasm.mark(target_loc.finalLoc(wasm)); | 5177 | try wasm.mark(target_loc.finalLoc(wasm)); |
| 5164 | } | 5178 | } |
| 5165 | } | 5179 | } |