| author | |
| committer | |
| log | 21a28885615dd9ea168c003caa65ff80a145eab7 |
| tree | dda19b3dabcfb3864d38e43abdb259a90dd34968 |
| parent | 5186c6c4ee520f7f1c87134d45cd7a33f8b2aaea |
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.4 files changed, 8 insertions(+), 19 deletions(-)
src/Zcu.zig-11| ... | @@ -4120,14 +4120,3 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) | ... | @@ -4120,14 +4120,3 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) |
| 4120 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); | 4120 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4121 | return error.CodegenFail; | 4121 | return error.CodegenFail; |
| 4122 | } | 4122 | } |
| 4123 | |||
| 4124 | /// Check if nav is an alias to a function, in which case we want to lower the | ||
| 4125 | /// actual nav, rather than the alias itself. | ||
| 4126 | pub fn chaseNav(zcu: *const Zcu, nav: InternPool.Nav.Index) InternPool.Nav.Index { | ||
| 4127 | return switch (zcu.intern_pool.indexToKey(zcu.navValue(nav).toIntern())) { | ||
| 4128 | .func => |f| f.owner_nav, | ||
| 4129 | .variable => |variable| variable.owner_nav, | ||
| 4130 | .@"extern" => |@"extern"| @"extern".owner_nav, | ||
| 4131 | else => nav, | ||
| 4132 | }; | ||
| 4133 | } |
src/arch/wasm/CodeGen.zig+5-5| ... | @@ -1025,10 +1025,9 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { | ... | @@ -1025,10 +1025,9 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 1025 | const comp = wasm.base.comp; | 1025 | const comp = wasm.base.comp; |
| 1026 | const zcu = comp.zcu.?; | 1026 | const zcu = comp.zcu.?; |
| 1027 | const ip = &zcu.intern_pool; | 1027 | const ip = &zcu.intern_pool; |
| 1028 | const ip_index = ip.getNav(nav_ref.nav_index).status.fully_resolved.val; | 1028 | if (ip.getNav(nav_ref.nav_index).isExternOrFn(ip)) { |
| 1029 | if (ip.isFunctionType(ip.typeOf(ip_index))) { | ||
| 1030 | assert(nav_ref.offset == 0); | 1029 | assert(nav_ref.offset == 0); |
| 1031 | const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, ip_index); | 1030 | const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, nav_ref.nav_index); |
| 1032 | if (!gop.found_existing) gop.value_ptr.* = {}; | 1031 | if (!gop.found_existing) gop.value_ptr.* = {}; |
| 1033 | try cg.addInst(.{ | 1032 | try cg.addInst(.{ |
| 1034 | .tag = .func_ref, | 1033 | .tag = .func_ref, |
| ... | @@ -1056,7 +1055,8 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { | ... | @@ -1056,7 +1055,8 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 1056 | const ip = &zcu.intern_pool; | 1055 | const ip = &zcu.intern_pool; |
| 1057 | if (ip.isFunctionType(ip.typeOf(uav.ip_index))) { | 1056 | if (ip.isFunctionType(ip.typeOf(uav.ip_index))) { |
| 1058 | assert(uav.offset == 0); | 1057 | assert(uav.offset == 0); |
| 1059 | const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, uav.ip_index); | 1058 | const owner_nav = ip.toFunc(uav.ip_index).owner_nav; |
| 1059 | const gop = try wasm.indirect_function_table.getOrPut(comp.gpa, owner_nav); | ||
| 1060 | if (!gop.found_existing) gop.value_ptr.* = {}; | 1060 | if (!gop.found_existing) gop.value_ptr.* = {}; |
| 1061 | try cg.addInst(.{ | 1061 | try cg.addInst(.{ |
| 1062 | .tag = .func_ref, | 1062 | .tag = .func_ref, |
| ... | @@ -3096,7 +3096,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro | ... | @@ -3096,7 +3096,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro |
| 3096 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; | 3096 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 3097 | const offset: u64 = prev_offset + ptr.byte_offset; | 3097 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 3098 | return switch (ptr.base_addr) { | 3098 | return switch (ptr.base_addr) { |
| 3099 | .nav => |nav| return .{ .nav_ref = .{ .nav_index = zcu.chaseNav(nav), .offset = @intCast(offset) } }, | 3099 | .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } }, |
| 3100 | .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset) } }, | 3100 | .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset) } }, |
| 3101 | .int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize), | 3101 | .int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize), |
| 3102 | .eu_payload => return cg.fail("Wasm TODO: lower error union payload pointer", .{}), | 3102 | .eu_payload => return cg.fail("Wasm TODO: lower error union payload pointer", .{}), |
src/link/Wasm.zig+1-1| ... | @@ -260,7 +260,7 @@ table_imports: std.AutoArrayHashMapUnmanaged(String, TableImport.Index) = .empty | ... | @@ -260,7 +260,7 @@ table_imports: std.AutoArrayHashMapUnmanaged(String, TableImport.Index) = .empty |
| 260 | 260 | ||
| 261 | /// All functions that have had their address taken and therefore might be | 261 | /// All functions that have had their address taken and therefore might be |
| 262 | /// called via a `call_indirect` function. | 262 | /// called via a `call_indirect` function. |
| 263 | indirect_function_table: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty, | 263 | indirect_function_table: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty, |
| 264 | 264 | ||
| 265 | error_name_table_ref_count: u32 = 0, | 265 | error_name_table_ref_count: u32 = 0, |
| 266 | 266 |
src/link/Wasm/Flush.zig+2-2| ... | @@ -651,8 +651,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -651,8 +651,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 651 | try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref | 651 | try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref |
| 652 | } | 652 | } |
| 653 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.indirect_function_table.entries.len))); | 653 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(wasm.indirect_function_table.entries.len))); |
| 654 | for (wasm.indirect_function_table.keys()) |ip_index| { | 654 | for (wasm.indirect_function_table.keys()) |nav_index| { |
| 655 | const func_index: Wasm.OutputFunctionIndex = .fromIpIndex(wasm, ip_index); | 655 | const func_index: Wasm.OutputFunctionIndex = .fromIpNav(wasm, nav_index); |
| 656 | try leb.writeUleb128(binary_writer, @intFromEnum(func_index)); | 656 | try leb.writeUleb128(binary_writer, @intFromEnum(func_index)); |
| 657 | } | 657 | } |
| 658 | 658 |