wasm: migrate to new non-allocateDeclIndexes API
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
=> {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user