authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-24 17:24:58+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:23:04+01:00
logfde8c2f41a76f6bc56d733a8cb6aae90f8e3f41b
tree742d36a6ee82580107b0e1f7f8e5fa9fbe225863
parent8f96e7eec1b2af005e17bf21f91fc91add92d7dd
signaturelock-open Commit is signed but in an unrecognized format.

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.

2 files changed, 40 insertions(+), 8 deletions(-)

src/link/Wasm.zig+1-2
......@@ -1534,9 +1534,8 @@ pub fn deleteDeclExport(
15341534 decl_index: InternPool.DeclIndex,
15351535 name: InternPool.NullTerminatedString,
15361536) void {
1537 _ = name;
15381537 if (wasm.llvm_object) |_| return;
1539 return wasm.zigObjectPtr().?.deleteDeclExport(wasm, decl_index);
1538 return wasm.zigObjectPtr().?.deleteDeclExport(wasm, decl_index, name);
15401539}
15411540
15421541pub fn updateExports(
src/link/Wasm/ZigObject.zig+39-6
......@@ -98,6 +98,16 @@ const DeclInfo = struct {
9898 fn appendExport(di: *DeclInfo, gpa: std.mem.Allocator, sym_index: u32) !void {
9999 return di.exports.append(gpa, sym_index);
100100 }
101
102 fn deleteExport(di: *DeclInfo, sym_index: u32) void {
103 for (di.exports.items, 0..) |idx, index| {
104 if (idx == sym_index) {
105 _ = di.exports.swapRemove(index);
106 return;
107 }
108 }
109 unreachable; // invalid sym_index
110 }
101111};
102112
103113/// Initializes the `ZigObject` with initial symbols.
......@@ -800,12 +810,23 @@ pub fn deleteDeclExport(
800810 zig_object: *ZigObject,
801811 wasm_file: *Wasm,
802812 decl_index: InternPool.DeclIndex,
813 name: InternPool.NullTerminatedString,
803814) void {
804 const decl_info = zig_object.decls_map.get(decl_index) orelse return;
805 const sym_index = wasm_file.getAtom(decl_info.atom).sym_index;
806 const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = sym_index };
807 const sym = loc.getSymbol(wasm_file);
808 std.debug.assert(zig_object.global_syms.remove(sym.name));
815 const mod = wasm_file.base.comp.module.?;
816 const decl_info = zig_object.decls_map.getPtr(decl_index) orelse return;
817 const export_name = mod.intern_pool.stringToSlice(name);
818 if (decl_info.@"export"(zig_object, export_name)) |sym_index| {
819 const sym = zig_object.symbol(sym_index);
820 decl_info.deleteExport(sym_index);
821 std.debug.assert(zig_object.global_syms.remove(sym.name));
822 std.debug.assert(wasm_file.symbol_atom.remove(.{ .file = zig_object.index, .index = sym_index }));
823 zig_object.symbols_free_list.append(wasm_file.base.comp.gpa, sym_index) catch {};
824
825 if (sym.tag == .function) {
826 std.debug.assert(zig_object.functions.remove(sym_index));
827 }
828 sym.tag = .dead;
829 }
809830}
810831
811832pub fn updateExports(
......@@ -846,6 +867,17 @@ pub fn updateExports(
846867 else index: {
847868 const sym_index = try zig_object.allocateSymbol(gpa);
848869 try decl_info.appendExport(gpa, sym_index);
870
871 // For functions, we also need to put the alias in the function section.
872 // We simply copy the aliased function.
873 // The final linakge will deduplicate these functions.
874 if (decl.ty.zigTypeTag(mod) == .Fn) {
875 try zig_object.functions.putNoClobber(
876 gpa,
877 sym_index,
878 zig_object.functions.get(atom.sym_index).?,
879 );
880 }
849881 break :index sym_index;
850882 };
851883
......@@ -879,6 +911,7 @@ pub fn updateExports(
879911 sym.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
880912 }
881913 try zig_object.global_syms.put(gpa, export_name, sym_index);
914 try wasm_file.symbol_atom.put(gpa, .{ .file = zig_object.index, .index = sym_index }, atom_index);
882915 }
883916}
884917
......@@ -1145,8 +1178,8 @@ pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index:
11451178pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) !Atom.Index {
11461179 const gpa = wasm_file.base.comp.gpa;
11471180 const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = index };
1148 const final_index = try wasm_file.getMatchingSegment(zig_object.index, index);
11491181 const atom_index = wasm_file.symbol_atom.get(loc).?;
1182 const final_index = try wasm_file.getMatchingSegment(zig_object.index, index);
11501183 try wasm_file.appendAtomAtIndex(final_index, atom_index);
11511184 const atom = wasm_file.getAtom(atom_index);
11521185 for (atom.relocs.items) |reloc| {