mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
wasm: Only generate import when referenced
Rather than creating an import for externs on updateDecl, we now generate them when they're referenced. This is required so using @TypeOf(extern_fn()) will not emit the import into the binary (causing an incorrect function type index as it won't be fully analyzed).
This commit is contained in:
parent
af844931b2
commit
97448e4d5f
@ -64,7 +64,7 @@ const WValue = union(enum) {
|
||||
/// loads and stores without requiring checks everywhere.
|
||||
fn offset(self: WValue) u32 {
|
||||
switch (self) {
|
||||
.stack_offset => |offset| return offset,
|
||||
.stack_offset => |stack_offset| return stack_offset,
|
||||
else => return 0,
|
||||
}
|
||||
}
|
||||
@ -1549,6 +1549,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
|
||||
var func_type = try genFunctype(self.gpa, ext_decl.ty, self.target);
|
||||
defer func_type.deinit(self.gpa);
|
||||
ext_decl.fn_link.wasm.type_index = try self.bin_file.putOrGetFuncType(func_type);
|
||||
try self.bin_file.addOrUpdateImport(ext_decl);
|
||||
break :blk ext_decl;
|
||||
} else if (func_val.castTag(.decl_ref)) |decl_ref| {
|
||||
break :blk decl_ref.data;
|
||||
@ -1939,6 +1940,10 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
|
||||
const decl = decl_ref.data;
|
||||
return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);
|
||||
}
|
||||
if (val.castTag(.decl_ref_mut)) |decl_ref| {
|
||||
const decl = decl_ref.data.decl;
|
||||
return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);
|
||||
}
|
||||
|
||||
const target = self.target;
|
||||
|
||||
|
||||
@ -496,8 +496,6 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
|
||||
atom.sym_index = @intCast(u32, self.symbols.items.len);
|
||||
self.symbols.appendAssumeCapacity(symbol);
|
||||
}
|
||||
|
||||
try self.resolved_symbols.putNoClobber(self.base.allocator, atom.symbolLoc(), {});
|
||||
try self.symbol_atom.putNoClobber(self.base.allocator, atom.symbolLoc(), atom);
|
||||
}
|
||||
|
||||
@ -552,7 +550,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
|
||||
decl.link.wasm.clear();
|
||||
|
||||
if (decl.isExtern()) {
|
||||
return self.addOrUpdateImport(decl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (decl.val.castTag(.function)) |_| {
|
||||
@ -588,10 +586,6 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
|
||||
}
|
||||
|
||||
fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {
|
||||
if (decl.isExtern()) {
|
||||
return self.addOrUpdateImport(decl);
|
||||
}
|
||||
|
||||
if (code.len == 0) return;
|
||||
const atom: *Atom = &decl.link.wasm;
|
||||
atom.size = @intCast(u32, code.len);
|
||||
@ -602,6 +596,8 @@ fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {
|
||||
defer self.base.allocator.free(full_name);
|
||||
symbol.name = try self.string_table.put(self.base.allocator, full_name);
|
||||
try atom.code.appendSlice(self.base.allocator, code);
|
||||
|
||||
try self.resolved_symbols.put(self.base.allocator, atom.symbolLoc(), {});
|
||||
}
|
||||
|
||||
/// Lowers a constant typed value to a local symbol and atom.
|
||||
@ -831,10 +827,10 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {
|
||||
}
|
||||
|
||||
if (decl.isExtern()) {
|
||||
assert(self.imports.remove(atom.symbolLoc()));
|
||||
_ = self.imports.remove(atom.symbolLoc());
|
||||
}
|
||||
assert(self.resolved_symbols.swapRemove(atom.symbolLoc()));
|
||||
_ = self.symbol_atom.remove(atom.symbolLoc()); // not all decl's exist in symbol_atom
|
||||
_ = self.resolved_symbols.swapRemove(atom.symbolLoc());
|
||||
_ = self.symbol_atom.remove(atom.symbolLoc());
|
||||
atom.deinit(self.base.allocator);
|
||||
}
|
||||
|
||||
@ -855,19 +851,19 @@ fn mapFunctionTable(self: *Wasm) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn addOrUpdateImport(self: *Wasm, decl: *Module.Decl) !void {
|
||||
pub fn addOrUpdateImport(self: *Wasm, decl: *Module.Decl) !void {
|
||||
// For the import name itself, we use the decl's name, rather than the fully qualified name
|
||||
const decl_name_index = try self.string_table.put(self.base.allocator, mem.sliceTo(decl.name, 0));
|
||||
const symbol_index = decl.link.wasm.sym_index;
|
||||
const symbol: *Symbol = &self.symbols.items[symbol_index];
|
||||
symbol.setUndefined(true);
|
||||
symbol.setGlobal(true);
|
||||
try self.globals.putNoClobber(
|
||||
self.base.allocator,
|
||||
decl_name_index,
|
||||
.{ .file = null, .index = symbol_index },
|
||||
);
|
||||
try self.resolved_symbols.put(self.base.allocator, .{ .file = null, .index = symbol_index }, {});
|
||||
const global_gop = try self.globals.getOrPut(self.base.allocator, decl_name_index);
|
||||
if (!global_gop.found_existing) {
|
||||
const loc: SymbolLoc = .{ .file = null, .index = symbol_index };
|
||||
global_gop.value_ptr.* = loc;
|
||||
try self.resolved_symbols.put(self.base.allocator, loc, {});
|
||||
}
|
||||
|
||||
switch (decl.ty.zigTypeTag()) {
|
||||
.Fn => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user