diff options
| author | Luuk de Gram <luuk@degram.dev> | 2024-01-24 17:24:58 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2024-02-29 15:23:04 +0100 |
| commit | fde8c2f41a76f6bc56d733a8cb6aae90f8e3f41b (patch) | |
| tree | 742d36a6ee82580107b0e1f7f8e5fa9fbe225863 /src/link | |
| parent | 8f96e7eec1b2af005e17bf21f91fc91add92d7dd (diff) | |
| download | zig-fde8c2f41a76f6bc56d733a8cb6aae90f8e3f41b.tar.gz zig-fde8c2f41a76f6bc56d733a8cb6aae90f8e3f41b.zip | |
wasm: reimplement `deleteDeclExport`
Removes the symbol from the decl's list of exports, marks it as dead,
as well as appends it to the symbol free list. Also removes it from
the list of global symbols as all exports are global.
In the future we should perhaps use a map for the export list to prevent
linear lookups. But this requires a benchmark as having more than 1
export for the same decl is very rare.
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Wasm.zig | 3 | ||||
| -rw-r--r-- | src/link/Wasm/ZigObject.zig | 45 |
2 files changed, 40 insertions, 8 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 82fa7a9439..98ace9e4ac 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1534,9 +1534,8 @@ pub fn deleteDeclExport( decl_index: InternPool.DeclIndex, name: InternPool.NullTerminatedString, ) void { - _ = name; if (wasm.llvm_object) |_| return; - return wasm.zigObjectPtr().?.deleteDeclExport(wasm, decl_index); + return wasm.zigObjectPtr().?.deleteDeclExport(wasm, decl_index, name); } pub fn updateExports( diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index 01f253d9b1..9a306fa80c 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -98,6 +98,16 @@ const DeclInfo = struct { fn appendExport(di: *DeclInfo, gpa: std.mem.Allocator, sym_index: u32) !void { return di.exports.append(gpa, sym_index); } + + fn deleteExport(di: *DeclInfo, sym_index: u32) void { + for (di.exports.items, 0..) |idx, index| { + if (idx == sym_index) { + _ = di.exports.swapRemove(index); + return; + } + } + unreachable; // invalid sym_index + } }; /// Initializes the `ZigObject` with initial symbols. @@ -800,12 +810,23 @@ pub fn deleteDeclExport( zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool.DeclIndex, + name: InternPool.NullTerminatedString, ) void { - const decl_info = zig_object.decls_map.get(decl_index) orelse return; - const sym_index = wasm_file.getAtom(decl_info.atom).sym_index; - const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = sym_index }; - const sym = loc.getSymbol(wasm_file); - std.debug.assert(zig_object.global_syms.remove(sym.name)); + const mod = wasm_file.base.comp.module.?; + const decl_info = zig_object.decls_map.getPtr(decl_index) orelse return; + const export_name = mod.intern_pool.stringToSlice(name); + if (decl_info.@"export"(zig_object, export_name)) |sym_index| { + const sym = zig_object.symbol(sym_index); + decl_info.deleteExport(sym_index); + std.debug.assert(zig_object.global_syms.remove(sym.name)); + std.debug.assert(wasm_file.symbol_atom.remove(.{ .file = zig_object.index, .index = sym_index })); + zig_object.symbols_free_list.append(wasm_file.base.comp.gpa, sym_index) catch {}; + + if (sym.tag == .function) { + std.debug.assert(zig_object.functions.remove(sym_index)); + } + sym.tag = .dead; + } } pub fn updateExports( @@ -846,6 +867,17 @@ pub fn updateExports( else index: { const sym_index = try zig_object.allocateSymbol(gpa); try decl_info.appendExport(gpa, sym_index); + + // For functions, we also need to put the alias in the function section. + // We simply copy the aliased function. + // The final linakge will deduplicate these functions. + if (decl.ty.zigTypeTag(mod) == .Fn) { + try zig_object.functions.putNoClobber( + gpa, + sym_index, + zig_object.functions.get(atom.sym_index).?, + ); + } break :index sym_index; }; @@ -879,6 +911,7 @@ pub fn updateExports( sym.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); } try zig_object.global_syms.put(gpa, export_name, sym_index); + try wasm_file.symbol_atom.put(gpa, .{ .file = zig_object.index, .index = sym_index }, atom_index); } } @@ -1145,8 +1178,8 @@ pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index: pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) !Atom.Index { const gpa = wasm_file.base.comp.gpa; const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = index }; - const final_index = try wasm_file.getMatchingSegment(zig_object.index, index); const atom_index = wasm_file.symbol_atom.get(loc).?; + const final_index = try wasm_file.getMatchingSegment(zig_object.index, index); try wasm_file.appendAtomAtIndex(final_index, atom_index); const atom = wasm_file.getAtom(atom_index); for (atom.relocs.items) |reloc| { |
