authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-01-27 19:24:15+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-01-27 19:24:15+01:00
logb25efb86e1b1b2a9e8aa269bf83b717d54f7e276
tree774b958f096b5eb6363b0326b294ca8c9b57e4af
parentcc1d7a0e315ba63b0d8c0cd647b4c7e92a571bf2
signaturelock-open Commit is signed but in an unrecognized format.

wasm: migrate to new non-allocateDeclIndexes API


5 files changed, 53 insertions(+), 44 deletions(-)

src/Module.zig+1
...@@ -5328,6 +5328,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {...@@ -5328,6 +5328,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
5328 .elf,5328 .elf,
5329 .macho,5329 .macho,
5330 .c,5330 .c,
5331 .wasm,
5331 => {}, // this linker backend has already migrated to the new API5332 => {}, // this linker backend has already migrated to the new API
53325333
5333 else => if (decl.has_tv) {5334 else => if (decl.has_tv) {
src/arch/wasm/CodeGen.zig+10-3
...@@ -2120,22 +2120,28 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2120,22 +2120,28 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2120 const module = func.bin_file.base.options.module.?;2120 const module = func.bin_file.base.options.module.?;
21212121
2122 if (func_val.castTag(.function)) |function| {2122 if (func_val.castTag(.function)) |function| {
2123 break :blk module.declPtr(function.data.owner_decl);2123 const decl = module.declPtr(function.data.owner_decl);
2124 try decl.link.wasm.ensureInitialized(func.bin_file);
2125 break :blk decl;
2124 } else if (func_val.castTag(.extern_fn)) |extern_fn| {2126 } else if (func_val.castTag(.extern_fn)) |extern_fn| {
2125 const ext_decl = module.declPtr(extern_fn.data.owner_decl);2127 const ext_decl = module.declPtr(extern_fn.data.owner_decl);
2126 const ext_info = ext_decl.ty.fnInfo();2128 const ext_info = ext_decl.ty.fnInfo();
2127 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type, func.target);2129 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type, func.target);
2128 defer func_type.deinit(func.gpa);2130 defer func_type.deinit(func.gpa);
2131 const atom = &ext_decl.link.wasm;
2132 try atom.ensureInitialized(func.bin_file);
2129 ext_decl.fn_link.wasm.type_index = try func.bin_file.putOrGetFuncType(func_type);2133 ext_decl.fn_link.wasm.type_index = try func.bin_file.putOrGetFuncType(func_type);
2130 try func.bin_file.addOrUpdateImport(2134 try func.bin_file.addOrUpdateImport(
2131 mem.sliceTo(ext_decl.name, 0),2135 mem.sliceTo(ext_decl.name, 0),
2132 ext_decl.link.wasm.sym_index,2136 atom.getSymbolIndex().?,
2133 ext_decl.getExternFn().?.lib_name,2137 ext_decl.getExternFn().?.lib_name,
2134 ext_decl.fn_link.wasm.type_index,2138 ext_decl.fn_link.wasm.type_index,
2135 );2139 );
2136 break :blk ext_decl;2140 break :blk ext_decl;
2137 } else if (func_val.castTag(.decl_ref)) |decl_ref| {2141 } else if (func_val.castTag(.decl_ref)) |decl_ref| {
2138 break :blk module.declPtr(decl_ref.data);2142 const decl = module.declPtr(decl_ref.data);
2143 try decl.link.wasm.ensureInitialized(func.bin_file);
2144 break :blk decl;
2139 }2145 }
2140 return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()});2146 return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()});
2141 };2147 };
...@@ -2752,6 +2758,7 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind...@@ -2752,6 +2758,7 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind
2752 }2758 }
27532759
2754 module.markDeclAlive(decl);2760 module.markDeclAlive(decl);
2761 try decl.link.wasm.ensureInitialized(func.bin_file);
27552762
2756 const target_sym_index = decl.link.wasm.sym_index;2763 const target_sym_index = decl.link.wasm.sym_index;
2757 if (decl.ty.zigTypeTag() == .Fn) {2764 if (decl.ty.zigTypeTag() == .Fn) {
src/link.zig+1-1
...@@ -615,7 +615,6 @@ pub const File = struct {...@@ -615,7 +615,6 @@ pub const File = struct {
615 return;615 return;
616 }616 }
617 switch (base.tag) {617 switch (base.tag) {
618 .wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl_index),
619 .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl_index),618 .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl_index),
620619
621 .coff,620 .coff,
...@@ -624,6 +623,7 @@ pub const File = struct {...@@ -624,6 +623,7 @@ pub const File = struct {
624 .c,623 .c,
625 .spirv,624 .spirv,
626 .nvptx,625 .nvptx,
626 .wasm,
627 => {},627 => {},
628 }628 }
629 }629 }
src/link/Wasm.zig+30-40
...@@ -986,31 +986,23 @@ pub fn deinit(wasm: *Wasm) void {...@@ -986,31 +986,23 @@ pub fn deinit(wasm: *Wasm) void {
986 }986 }
987}987}
988988
989pub fn allocateDeclIndexes(wasm: *Wasm, decl_index: Module.Decl.Index) !void {989/// Allocates a new symbol and returns its index.
990 if (wasm.llvm_object) |_| return;990/// Will re-use slots when a symbol was freed at an earlier stage.
991 const decl = wasm.base.options.module.?.declPtr(decl_index);991pub fn allocateSymbol(wasm: *Wasm) !u32 {
992 if (decl.link.wasm.sym_index != 0) return;
993
994 try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1);992 try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1);
995 try wasm.decls.putNoClobber(wasm.base.allocator, decl_index, {});
996
997 const atom = &decl.link.wasm;
998
999 var symbol: Symbol = .{993 var symbol: Symbol = .{
1000 .name = undefined, // will be set after updateDecl994 .name = undefined, // will be set after updateDecl
1001 .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL),995 .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
1002 .tag = undefined, // will be set after updateDecl996 .tag = undefined, // will be set after updateDecl
1003 .index = undefined, // will be set after updateDecl997 .index = undefined, // will be set after updateDecl
1004 };998 };
1005
1006 if (wasm.symbols_free_list.popOrNull()) |index| {999 if (wasm.symbols_free_list.popOrNull()) |index| {
1007 atom.sym_index = index;
1008 wasm.symbols.items[index] = symbol;1000 wasm.symbols.items[index] = symbol;
1009 } else {1001 return index;
1010 atom.sym_index = @intCast(u32, wasm.symbols.items.len);
1011 wasm.symbols.appendAssumeCapacity(symbol);
1012 }1002 }
1013 try wasm.symbol_atom.putNoClobber(wasm.base.allocator, atom.symbolLoc(), atom);1003 const index = @intCast(u32, wasm.symbols.items.len);
1004 wasm.symbols.appendAssumeCapacity(symbol);
1005 return index;
1014}1006}
10151007
1016pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {1008pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void {
...@@ -1026,9 +1018,12 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes...@@ -1026,9 +1018,12 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes
10261018
1027 const decl_index = func.owner_decl;1019 const decl_index = func.owner_decl;
1028 const decl = mod.declPtr(decl_index);1020 const decl = mod.declPtr(decl_index);
1029 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()1021 const atom = &decl.link.wasm;
10301022 try atom.ensureInitialized(wasm);
1031 decl.link.wasm.clear();1023 const gop = try wasm.decls.getOrPut(wasm.base.allocator, decl_index);
1024 if (gop.found_existing) {
1025 atom.clear();
1026 } else gop.value_ptr.* = {};
10321027
1033 var decl_state: ?Dwarf.DeclState = if (wasm.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl_index) else null;1028 var decl_state: ?Dwarf.DeclState = if (wasm.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl_index) else null;
1034 defer if (decl_state) |*ds| ds.deinit();1029 defer if (decl_state) |*ds| ds.deinit();
...@@ -1083,16 +1078,19 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi...@@ -1083,16 +1078,19 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
1083 defer tracy.end();1078 defer tracy.end();
10841079
1085 const decl = mod.declPtr(decl_index);1080 const decl = mod.declPtr(decl_index);
1086 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()
1087
1088 decl.link.wasm.clear();
1089
1090 if (decl.val.castTag(.function)) |_| {1081 if (decl.val.castTag(.function)) |_| {
1091 return;1082 return;
1092 } else if (decl.val.castTag(.extern_fn)) |_| {1083 } else if (decl.val.castTag(.extern_fn)) |_| {
1093 return;1084 return;
1094 }1085 }
10951086
1087 const atom = &decl.link.wasm;
1088 try atom.ensureInitialized(wasm);
1089 const gop = try wasm.decls.getOrPut(wasm.base.allocator, decl_index);
1090 if (gop.found_existing) {
1091 atom.clear();
1092 } else gop.value_ptr.* = {};
1093
1096 if (decl.isExtern()) {1094 if (decl.isExtern()) {
1097 const variable = decl.getVariable().?;1095 const variable = decl.getVariable().?;
1098 const name = mem.sliceTo(decl.name, 0);1096 const name = mem.sliceTo(decl.name, 0);
...@@ -1148,8 +1146,8 @@ fn finishUpdateDecl(wasm: *Wasm, decl: *Module.Decl, code: []const u8) !void {...@@ -1148,8 +1146,8 @@ fn finishUpdateDecl(wasm: *Wasm, decl: *Module.Decl, code: []const u8) !void {
1148 try atom.code.appendSlice(wasm.base.allocator, code);1146 try atom.code.appendSlice(wasm.base.allocator, code);
1149 try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});1147 try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});
11501148
1151 if (code.len == 0) return;
1152 atom.size = @intCast(u32, code.len);1149 atom.size = @intCast(u32, code.len);
1150 if (code.len == 0) return;
1153 atom.alignment = decl.ty.abiAlignment(wasm.base.options.target);1151 atom.alignment = decl.ty.abiAlignment(wasm.base.options.target);
1154}1152}
11551153
...@@ -1211,28 +1209,19 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In...@@ -1211,28 +1209,19 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
1211 defer wasm.base.allocator.free(fqdn);1209 defer wasm.base.allocator.free(fqdn);
1212 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });1210 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });
1213 defer wasm.base.allocator.free(name);1211 defer wasm.base.allocator.free(name);
1214 var symbol: Symbol = .{
1215 .name = try wasm.string_table.put(wasm.base.allocator, name),
1216 .flags = 0,
1217 .tag = .data,
1218 .index = undefined,
1219 };
1220 symbol.setFlag(.WASM_SYM_BINDING_LOCAL);
12211212
1222 const atom = try decl.link.wasm.locals.addOne(wasm.base.allocator);1213 const atom = try decl.link.wasm.locals.addOne(wasm.base.allocator);
1223 atom.* = Atom.empty;1214 atom.* = Atom.empty;
1215 try atom.ensureInitialized(wasm);
1224 atom.alignment = tv.ty.abiAlignment(wasm.base.options.target);1216 atom.alignment = tv.ty.abiAlignment(wasm.base.options.target);
1225 try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1);1217 wasm.symbols.items[atom.sym_index] = .{
1218 .name = try wasm.string_table.put(wasm.base.allocator, name),
1219 .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
1220 .tag = .data,
1221 .index = undefined,
1222 };
12261223
1227 if (wasm.symbols_free_list.popOrNull()) |index| {
1228 atom.sym_index = index;
1229 wasm.symbols.items[index] = symbol;
1230 } else {
1231 atom.sym_index = @intCast(u32, wasm.symbols.items.len);
1232 wasm.symbols.appendAssumeCapacity(symbol);
1233 }
1234 try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, atom.symbolLoc(), {});1224 try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, atom.symbolLoc(), {});
1235 try wasm.symbol_atom.putNoClobber(wasm.base.allocator, atom.symbolLoc(), atom);
12361225
1237 var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);1226 var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);
1238 defer value_bytes.deinit();1227 defer value_bytes.deinit();
...@@ -1304,8 +1293,8 @@ pub fn getDeclVAddr(...@@ -1304,8 +1293,8 @@ pub fn getDeclVAddr(
1304) !u64 {1293) !u64 {
1305 const mod = wasm.base.options.module.?;1294 const mod = wasm.base.options.module.?;
1306 const decl = mod.declPtr(decl_index);1295 const decl = mod.declPtr(decl_index);
1296 try decl.link.wasm.ensureInitialized(wasm);
1307 const target_symbol_index = decl.link.wasm.sym_index;1297 const target_symbol_index = decl.link.wasm.sym_index;
1308 assert(target_symbol_index != 0);
1309 assert(reloc_info.parent_atom_index != 0);1298 assert(reloc_info.parent_atom_index != 0);
1310 const atom = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;1299 const atom = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
1311 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;1300 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
...@@ -1363,6 +1352,7 @@ pub fn updateDeclExports(...@@ -1363,6 +1352,7 @@ pub fn updateDeclExports(
1363 }1352 }
13641353
1365 const decl = mod.declPtr(decl_index);1354 const decl = mod.declPtr(decl_index);
1355 if (decl.link.wasm.getSymbolIndex() == null) return; // unititialized
13661356
1367 for (exports) |exp| {1357 for (exports) |exp| {
1368 if (exp.options.section) |section| {1358 if (exp.options.section) |section| {
src/link/Wasm/Atom.zig+11
...@@ -95,6 +95,17 @@ pub fn symbolLoc(atom: Atom) Wasm.SymbolLoc {...@@ -95,6 +95,17 @@ pub fn symbolLoc(atom: Atom) Wasm.SymbolLoc {
95 return .{ .file = atom.file, .index = atom.sym_index };95 return .{ .file = atom.file, .index = atom.sym_index };
96}96}
9797
98pub fn ensureInitialized(atom: *Atom, wasm_bin: *Wasm) !void {
99 if (atom.getSymbolIndex() != null) return; // already initialized
100 atom.sym_index = try wasm_bin.allocateSymbol();
101 try wasm_bin.symbol_atom.putNoClobber(wasm_bin.base.allocator, atom.symbolLoc(), atom);
102}
103
104pub fn getSymbolIndex(atom: Atom) ?u32 {
105 if (atom.sym_index == 0) return null;
106 return atom.sym_index;
107}
108
98/// Returns the virtual address of the `Atom`. This is the address starting109/// Returns the virtual address of the `Atom`. This is the address starting
99/// from the first entry within a section.110/// from the first entry within a section.
100pub fn getVA(atom: Atom, wasm: *const Wasm, symbol: *const Symbol) u32 {111pub fn getVA(atom: Atom, wasm: *const Wasm, symbol: *const Symbol) u32 {