diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-01-27 19:24:15 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-01-27 19:24:15 +0100 |
| commit | b25efb86e1b1b2a9e8aa269bf83b717d54f7e276 (patch) | |
| tree | 774b958f096b5eb6363b0326b294ca8c9b57e4af /src | |
| parent | cc1d7a0e315ba63b0d8c0cd647b4c7e92a571bf2 (diff) | |
| download | zig-b25efb86e1b1b2a9e8aa269bf83b717d54f7e276.tar.gz zig-b25efb86e1b1b2a9e8aa269bf83b717d54f7e276.zip | |
wasm: migrate to new non-allocateDeclIndexes API
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 1 | ||||
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 13 | ||||
| -rw-r--r-- | src/link.zig | 2 | ||||
| -rw-r--r-- | src/link/Wasm.zig | 70 | ||||
| -rw-r--r-- | src/link/Wasm/Atom.zig | 11 |
5 files changed, 53 insertions, 44 deletions
diff --git a/src/Module.zig b/src/Module.zig index 360dd4d1ec..713680c5fa 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5328,6 +5328,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void { .elf, .macho, .c, + .wasm, => {}, // this linker backend has already migrated to the new API else => if (decl.has_tv) { diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index a7d90a8bf9..342d6b70cc 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -2120,22 +2120,28 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif const module = func.bin_file.base.options.module.?; if (func_val.castTag(.function)) |function| { - break :blk module.declPtr(function.data.owner_decl); + const decl = module.declPtr(function.data.owner_decl); + try decl.link.wasm.ensureInitialized(func.bin_file); + break :blk decl; } else if (func_val.castTag(.extern_fn)) |extern_fn| { const ext_decl = module.declPtr(extern_fn.data.owner_decl); const ext_info = ext_decl.ty.fnInfo(); var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type, func.target); defer func_type.deinit(func.gpa); + const atom = &ext_decl.link.wasm; + try atom.ensureInitialized(func.bin_file); ext_decl.fn_link.wasm.type_index = try func.bin_file.putOrGetFuncType(func_type); try func.bin_file.addOrUpdateImport( mem.sliceTo(ext_decl.name, 0), - ext_decl.link.wasm.sym_index, + atom.getSymbolIndex().?, ext_decl.getExternFn().?.lib_name, ext_decl.fn_link.wasm.type_index, ); break :blk ext_decl; } else if (func_val.castTag(.decl_ref)) |decl_ref| { - break :blk module.declPtr(decl_ref.data); + const decl = module.declPtr(decl_ref.data); + try decl.link.wasm.ensureInitialized(func.bin_file); + break :blk decl; } return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()}); }; @@ -2752,6 +2758,7 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind } module.markDeclAlive(decl); + try decl.link.wasm.ensureInitialized(func.bin_file); const target_sym_index = decl.link.wasm.sym_index; if (decl.ty.zigTypeTag() == .Fn) { diff --git a/src/link.zig b/src/link.zig index 9be5b9ca3a..f9081499a8 100644 --- a/src/link.zig +++ b/src/link.zig @@ -615,7 +615,6 @@ pub const File = struct { return; } switch (base.tag) { - .wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl_index), .plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl_index), .coff, @@ -624,6 +623,7 @@ pub const File = struct { .c, .spirv, .nvptx, + .wasm, => {}, } } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 7129722d16..31dfb87659 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -986,31 +986,23 @@ pub fn deinit(wasm: *Wasm) void { } } -pub fn allocateDeclIndexes(wasm: *Wasm, decl_index: Module.Decl.Index) !void { - if (wasm.llvm_object) |_| return; - const decl = wasm.base.options.module.?.declPtr(decl_index); - if (decl.link.wasm.sym_index != 0) return; - +/// Allocates a new symbol and returns its index. +/// Will re-use slots when a symbol was freed at an earlier stage. +pub fn allocateSymbol(wasm: *Wasm) !u32 { try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1); - try wasm.decls.putNoClobber(wasm.base.allocator, decl_index, {}); - - const atom = &decl.link.wasm; - var symbol: Symbol = .{ .name = undefined, // will be set after updateDecl .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL), .tag = undefined, // will be set after updateDecl .index = undefined, // will be set after updateDecl }; - if (wasm.symbols_free_list.popOrNull()) |index| { - atom.sym_index = index; wasm.symbols.items[index] = symbol; - } else { - atom.sym_index = @intCast(u32, wasm.symbols.items.len); - wasm.symbols.appendAssumeCapacity(symbol); + return index; } - try wasm.symbol_atom.putNoClobber(wasm.base.allocator, atom.symbolLoc(), atom); + const index = @intCast(u32, wasm.symbols.items.len); + wasm.symbols.appendAssumeCapacity(symbol); + return index; } pub 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 const decl_index = func.owner_decl; const decl = mod.declPtr(decl_index); - assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() - - decl.link.wasm.clear(); + const atom = &decl.link.wasm; + try atom.ensureInitialized(wasm); + const gop = try wasm.decls.getOrPut(wasm.base.allocator, decl_index); + if (gop.found_existing) { + atom.clear(); + } else gop.value_ptr.* = {}; var decl_state: ?Dwarf.DeclState = if (wasm.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl_index) else null; defer if (decl_state) |*ds| ds.deinit(); @@ -1083,16 +1078,19 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi defer tracy.end(); const decl = mod.declPtr(decl_index); - assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() - - decl.link.wasm.clear(); - if (decl.val.castTag(.function)) |_| { return; } else if (decl.val.castTag(.extern_fn)) |_| { return; } + const atom = &decl.link.wasm; + try atom.ensureInitialized(wasm); + const gop = try wasm.decls.getOrPut(wasm.base.allocator, decl_index); + if (gop.found_existing) { + atom.clear(); + } else gop.value_ptr.* = {}; + if (decl.isExtern()) { const variable = decl.getVariable().?; const name = mem.sliceTo(decl.name, 0); @@ -1148,8 +1146,8 @@ fn finishUpdateDecl(wasm: *Wasm, decl: *Module.Decl, code: []const u8) !void { try atom.code.appendSlice(wasm.base.allocator, code); try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {}); - if (code.len == 0) return; atom.size = @intCast(u32, code.len); + if (code.len == 0) return; atom.alignment = decl.ty.abiAlignment(wasm.base.options.target); } @@ -1211,28 +1209,19 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In defer wasm.base.allocator.free(fqdn); const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index }); defer wasm.base.allocator.free(name); - var symbol: Symbol = .{ - .name = try wasm.string_table.put(wasm.base.allocator, name), - .flags = 0, - .tag = .data, - .index = undefined, - }; - symbol.setFlag(.WASM_SYM_BINDING_LOCAL); const atom = try decl.link.wasm.locals.addOne(wasm.base.allocator); atom.* = Atom.empty; + try atom.ensureInitialized(wasm); atom.alignment = tv.ty.abiAlignment(wasm.base.options.target); - try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1); + wasm.symbols.items[atom.sym_index] = .{ + .name = try wasm.string_table.put(wasm.base.allocator, name), + .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL), + .tag = .data, + .index = undefined, + }; - if (wasm.symbols_free_list.popOrNull()) |index| { - atom.sym_index = index; - wasm.symbols.items[index] = symbol; - } else { - atom.sym_index = @intCast(u32, wasm.symbols.items.len); - wasm.symbols.appendAssumeCapacity(symbol); - } try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, atom.symbolLoc(), {}); - try wasm.symbol_atom.putNoClobber(wasm.base.allocator, atom.symbolLoc(), atom); var value_bytes = std.ArrayList(u8).init(wasm.base.allocator); defer value_bytes.deinit(); @@ -1304,8 +1293,8 @@ pub fn getDeclVAddr( ) !u64 { const mod = wasm.base.options.module.?; const decl = mod.declPtr(decl_index); + try decl.link.wasm.ensureInitialized(wasm); const target_symbol_index = decl.link.wasm.sym_index; - assert(target_symbol_index != 0); assert(reloc_info.parent_atom_index != 0); const atom = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?; const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32; @@ -1363,6 +1352,7 @@ pub fn updateDeclExports( } const decl = mod.declPtr(decl_index); + if (decl.link.wasm.getSymbolIndex() == null) return; // unititialized for (exports) |exp| { if (exp.options.section) |section| { diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index de9cefebdc..20f847e475 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -95,6 +95,17 @@ pub fn symbolLoc(atom: Atom) Wasm.SymbolLoc { return .{ .file = atom.file, .index = atom.sym_index }; } +pub fn ensureInitialized(atom: *Atom, wasm_bin: *Wasm) !void { + if (atom.getSymbolIndex() != null) return; // already initialized + atom.sym_index = try wasm_bin.allocateSymbol(); + try wasm_bin.symbol_atom.putNoClobber(wasm_bin.base.allocator, atom.symbolLoc(), atom); +} + +pub fn getSymbolIndex(atom: Atom) ?u32 { + if (atom.sym_index == 0) return null; + return atom.sym_index; +} + /// Returns the virtual address of the `Atom`. This is the address starting /// from the first entry within a section. pub fn getVA(atom: Atom, wasm: *const Wasm, symbol: *const Symbol) u32 { |
