| ... | @@ -491,6 +491,7 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { | ... | @@ -491,6 +491,7 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { |
| 491 | return error.SymbolCollision; | 491 | return error.SymbolCollision; |
| 492 | } | 492 | } |
| 493 | | 493 | |
| | 494 | try self.discarded.put(self.base.allocator, location, existing_loc); |
| 494 | continue; // Do not overwrite defined symbols with undefined symbols | 495 | continue; // Do not overwrite defined symbols with undefined symbols |
| 495 | } | 496 | } |
| 496 | | 497 | |
| ... | @@ -503,6 +504,7 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { | ... | @@ -503,6 +504,7 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { |
| 503 | | 504 | |
| 504 | // when both symbols are weak, we skip overwriting | 505 | // when both symbols are weak, we skip overwriting |
| 505 | if (existing_sym.isWeak() and symbol.isWeak()) { | 506 | if (existing_sym.isWeak() and symbol.isWeak()) { |
| | 507 | try self.discarded.put(self.base.allocator, location, existing_loc); |
| 506 | continue; | 508 | continue; |
| 507 | } | 509 | } |
| 508 | | 510 | |
| ... | @@ -510,15 +512,13 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { | ... | @@ -510,15 +512,13 @@ fn resolveSymbolsInObject(self: *Wasm, object_index: u16) !void { |
| 510 | log.debug("Overwriting symbol '{s}'", .{sym_name}); | 512 | log.debug("Overwriting symbol '{s}'", .{sym_name}); |
| 511 | log.debug(" old definition in '{s}'", .{existing_file_path}); | 513 | log.debug(" old definition in '{s}'", .{existing_file_path}); |
| 512 | log.debug(" new definition in '{s}'", .{object.name}); | 514 | log.debug(" new definition in '{s}'", .{object.name}); |
| 513 | try self.discarded.putNoClobber(self.base.allocator, maybe_existing.value_ptr.*, location); | 515 | try self.discarded.putNoClobber(self.base.allocator, existing_loc, location); |
| 514 | maybe_existing.value_ptr.* = location; | 516 | maybe_existing.value_ptr.* = location; |
| 515 | try self.globals.put(self.base.allocator, sym_name_index, location); | 517 | try self.globals.put(self.base.allocator, sym_name_index, location); |
| 516 | try self.resolved_symbols.put(self.base.allocator, location, {}); | 518 | try self.resolved_symbols.put(self.base.allocator, location, {}); |
| 517 | assert(self.resolved_symbols.swapRemove(existing_loc)); | 519 | assert(self.resolved_symbols.swapRemove(existing_loc)); |
| 518 | if (existing_sym.isUndefined()) { | 520 | if (existing_sym.isUndefined()) { |
| 519 | // ensure order remains intact in case we later | 521 | assert(self.undefs.swapRemove(sym_name)); |
| 520 | // resolve symbols again in a loop | | |
| 521 | assert(self.undefs.orderedRemove(sym_name)); | | |
| 522 | } | 522 | } |
| 523 | } | 523 | } |
| 524 | } | 524 | } |
| ... | @@ -1004,7 +1004,6 @@ pub fn updateDeclExports( | ... | @@ -1004,7 +1004,6 @@ pub fn updateDeclExports( |
| 1004 | switch (exp.options.linkage) { | 1004 | switch (exp.options.linkage) { |
| 1005 | .Internal => { | 1005 | .Internal => { |
| 1006 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); | 1006 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 1007 | symbol.setFlag(.WASM_SYM_BINDING_WEAK); | | |
| 1008 | }, | 1007 | }, |
| 1009 | .Weak => { | 1008 | .Weak => { |
| 1010 | symbol.setFlag(.WASM_SYM_BINDING_WEAK); | 1009 | symbol.setFlag(.WASM_SYM_BINDING_WEAK); |
| ... | @@ -1026,6 +1025,7 @@ pub fn updateDeclExports( | ... | @@ -1026,6 +1025,7 @@ pub fn updateDeclExports( |
| 1026 | } | 1025 | } |
| 1027 | | 1026 | |
| 1028 | symbol.setGlobal(true); | 1027 | symbol.setGlobal(true); |
| | 1028 | symbol.setUndefined(false); |
| 1029 | try self.globals.put( | 1029 | try self.globals.put( |
| 1030 | self.base.allocator, | 1030 | self.base.allocator, |
| 1031 | export_name, | 1031 | export_name, |
| ... | @@ -1034,6 +1034,7 @@ pub fn updateDeclExports( | ... | @@ -1034,6 +1034,7 @@ pub fn updateDeclExports( |
| 1034 | | 1034 | |
| 1035 | // if the symbol was previously undefined, remove it as an import | 1035 | // if the symbol was previously undefined, remove it as an import |
| 1036 | _ = self.imports.remove(sym_loc); | 1036 | _ = self.imports.remove(sym_loc); |
| | 1037 | _ = self.undefs.swapRemove(exp.options.name); |
| 1037 | exp.link.wasm.sym_index = sym_index; | 1038 | exp.link.wasm.sym_index = sym_index; |
| 1038 | } | 1039 | } |
| 1039 | } | 1040 | } |
| ... | @@ -1103,11 +1104,13 @@ pub fn addOrUpdateImport( | ... | @@ -1103,11 +1104,13 @@ pub fn addOrUpdateImport( |
| 1103 | /// is asserted instead. | 1104 | /// is asserted instead. |
| 1104 | type_index: ?u32, | 1105 | type_index: ?u32, |
| 1105 | ) !void { | 1106 | ) !void { |
| | 1107 | assert(symbol_index != 0); |
| 1106 | // For the import name itself, we use the decl's name, rather than the fully qualified name | 1108 | // For the import name itself, we use the decl's name, rather than the fully qualified name |
| 1107 | const decl_name_index = try self.string_table.put(self.base.allocator, name); | 1109 | const decl_name_index = try self.string_table.put(self.base.allocator, name); |
| 1108 | const symbol: *Symbol = &self.symbols.items[symbol_index]; | 1110 | const symbol: *Symbol = &self.symbols.items[symbol_index]; |
| 1109 | symbol.setUndefined(true); | 1111 | symbol.setUndefined(true); |
| 1110 | symbol.setGlobal(true); | 1112 | symbol.setGlobal(true); |
| | 1113 | symbol.name = decl_name_index; |
| 1111 | const global_gop = try self.globals.getOrPut(self.base.allocator, decl_name_index); | 1114 | const global_gop = try self.globals.getOrPut(self.base.allocator, decl_name_index); |
| 1112 | if (!global_gop.found_existing) { | 1115 | if (!global_gop.found_existing) { |
| 1113 | const loc: SymbolLoc = .{ .file = null, .index = symbol_index }; | 1116 | const loc: SymbolLoc = .{ .file = null, .index = symbol_index }; |
| ... | @@ -2113,7 +2116,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -2113,7 +2116,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2113 | | 2116 | |
| 2114 | while (true) { | 2117 | while (true) { |
| 2115 | if (!is_obj) { | 2118 | if (!is_obj) { |
| 2116 | try atom.resolveRelocs(self); | 2119 | atom.resolveRelocs(self); |
| 2117 | } | 2120 | } |
| 2118 | sorted_atoms.appendAssumeCapacity(atom); | 2121 | sorted_atoms.appendAssumeCapacity(atom); |
| 2119 | atom = atom.next orelse break; | 2122 | atom = atom.next orelse break; |
| ... | @@ -2172,7 +2175,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -2172,7 +2175,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2172 | var current_offset: u32 = 0; | 2175 | var current_offset: u32 = 0; |
| 2173 | while (true) { | 2176 | while (true) { |
| 2174 | if (!is_obj) { | 2177 | if (!is_obj) { |
| 2175 | try atom.resolveRelocs(self); | 2178 | atom.resolveRelocs(self); |
| 2176 | } | 2179 | } |
| 2177 | | 2180 | |
| 2178 | // Pad with zeroes to ensure all segments are aligned | 2181 | // Pad with zeroes to ensure all segments are aligned |