mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
wasm linker: don't assume nav callees are fully resolved
codegen can be called which contains calls to navs which have only their type resolved. this means the indirect function table needs to track nav indexes not ip indexes.
This commit is contained in:
parent
5186c6c4ee
commit
21a2888561
11
src/Zcu.zig
11
src/Zcu.zig
@ -4120,14 +4120,3 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg)
|
||||
zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
/// Check if nav is an alias to a function, in which case we want to lower the
|
||||
/// actual nav, rather than the alias itself.
|
||||
pub fn chaseNav(zcu: *const Zcu, nav: InternPool.Nav.Index) InternPool.Nav.Index {
|
||||
return switch (zcu.intern_pool.indexToKey(zcu.navValue(nav).toIntern())) {
|
||||
.func => |f| f.owner_nav,
|
||||
.variable => |variable| variable.owner_nav,
|
||||
.@"extern" => |@"extern"| @"extern".owner_nav,
|
||||
else => nav,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1025,10 +1025,9 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {
|
||||
const comp = wasm.base.comp;
|
||||
const zcu = comp.zcu.?;
|
||||
const ip = &zcu.intern_pool;
|
||||
const ip_index = ip.getNav(nav_ref.nav_index).status.fully_resolved.val;
|
||||
if (ip.isFunctionType(ip.typeOf(ip_index))) {
|
||||
if (ip.getNav(nav_ref.nav_index).isExternOrFn(ip)) {
|
||||
assert(nav_ref.offset == 0);
|
||||
const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, ip_index);
|
||||
const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, nav_ref.nav_index);
|
||||
if (!gop.found_existing) gop.value_ptr.* = {};
|
||||
try cg.addInst(.{
|
||||
.tag = .func_ref,
|
||||
@ -1056,7 +1055,8 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {
|
||||
const ip = &zcu.intern_pool;
|
||||
if (ip.isFunctionType(ip.typeOf(uav.ip_index))) {
|
||||
assert(uav.offset == 0);
|
||||
const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, uav.ip_index);
|
||||
const owner_nav = ip.toFunc(uav.ip_index).owner_nav;
|
||||
const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, owner_nav);
|
||||
if (!gop.found_existing) gop.value_ptr.* = {};
|
||||
try cg.addInst(.{
|
||||
.tag = .func_ref,
|
||||
@ -3096,7 +3096,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
|
||||
const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
|
||||
const offset: u64 = prev_offset + ptr.byte_offset;
|
||||
return switch (ptr.base_addr) {
|
||||
.nav => |nav| return .{ .nav_ref = .{ .nav_index = zcu.chaseNav(nav), .offset = @intCast(offset) } },
|
||||
.nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },
|
||||
.uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset) } },
|
||||
.int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
|
||||
.eu_payload => return cg.fail("Wasm TODO: lower error union payload pointer", .{}),
|
||||
|
||||
@ -260,7 +260,7 @@ table_imports: std.AutoArrayHashMapUnmanaged(String, TableImport.Index) = .empty
|
||||
|
||||
/// All functions that have had their address taken and therefore might be
|
||||
/// called via a `call_indirect` function.
|
||||
indirect_function_table: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty,
|
||||
indirect_function_table: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty,
|
||||
|
||||
error_name_table_ref_count: u32 = 0,
|
||||
|
||||
|
||||
@ -651,8 +651,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
|
||||
try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref
|
||||
}
|
||||
try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.indirect_function_table.entries.len)));
|
||||
for (wasm.indirect_function_table.keys()) |ip_index| {
|
||||
const func_index: Wasm.OutputFunctionIndex = .fromIpIndex(wasm, ip_index);
|
||||
for (wasm.indirect_function_table.keys()) |nav_index| {
|
||||
const func_index: Wasm.OutputFunctionIndex = .fromIpNav(wasm, nav_index);
|
||||
try leb.writeUleb128(binary_writer, @intFromEnum(func_index));
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user