zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 21a28885615dd9ea168c003caa65ff80a145eab7 (tree)
parent 5186c6c4ee520f7f1c87134d45cd7a33f8b2aaea
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Wed,  8 Jan 2025 17:01:36 -0800

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.

Diffstat:
Msrc/Zcu.zig | 11-----------
Msrc/arch/wasm/CodeGen.zig | 10+++++-----
Msrc/link/Wasm.zig | 2+-
Msrc/link/Wasm/Flush.zig | 4++--
4 files changed, 8 insertions(+), 19 deletions(-)

diff --git 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 @@ -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 @@ -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 @@ -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)); }