From 21a28885615dd9ea168c003caa65ff80a145eab7 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 Jan 2025 17:01:36 -0800 Subject: [PATCH] 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. --- src/Zcu.zig | 11 ----------- src/arch/wasm/CodeGen.zig | 10 +++++----- src/link/Wasm.zig | 2 +- src/link/Wasm/Flush.zig | 4 ++-- 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/Zcu.zig b/src/Zcu.zig index 48c7e3f131e68b929c7b234fa73bb417dbb65453..166dc5ec9106430e2671024067e1431daa6076df 100644 --- a/src/Zcu.zig +++ b/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, - }; -} diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 8be3e429ab42514fb362d143262951bdf4340cff..8d70103d1f0b0fe32bfc875fcf6556f8b58468f9 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -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", .{}), diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 2f8689bb1b7bd9f16634eee0a4e38736c8327b73..60e721ba07077c21347f8d235f4a8aea3c472ecd 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -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, diff --git a/src/link/Wasm/Flush.zig b/src/link/Wasm/Flush.zig index 1e4f256a8f10febf7b5a81507197aebdebb42aaa..7b2ddf5846d23a95d51a5cec5535cb2b340e202e 100644 --- a/src/link/Wasm/Flush.zig +++ b/src/link/Wasm/Flush.zig @@ -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)); } -- 2.54.0