authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-18 16:43:14-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:35-08:00
log91efc5c98bb32f3b1d42895362d5ae5a175a1345
tree43b1ce691421c7be95044e93f66ef9ef04958729
parent1a58ae2ed6d38a2a73cacb8b97f2885685505838

wasm linker: fix calling imported functions

and more disciplined type safety for output function indexes

3 files changed, 41 insertions(+), 11 deletions(-)

src/InternPool.zig+8
......@@ -620,6 +620,14 @@ pub const Nav = struct {
620620 };
621621 }
622622
623 /// Asserts that `status == .resolved`.
624 pub fn toExtern(nav: *const Nav, ip: *const InternPool) ?Key.Extern {
625 return switch (ip.indexToKey(nav.status.resolved.val)) {
626 .@"extern" => |ext| ext,
627 else => null,
628 };
629 }
630
623631 /// Asserts that `status == .resolved`.
624632 pub fn isThreadLocal(nav: Nav, ip: *const InternPool) bool {
625633 const val = nav.status.resolved.val;
src/arch/wasm/Emit.zig+7-7
......@@ -30,7 +30,6 @@ pub fn lowerToCode(emit: *Emit) Error!void {
3030 const is_obj = comp.config.output_mode == .Obj;
3131 const target = &comp.root_mod.resolved_target.result;
3232 const is_wasm32 = target.cpu.arch == .wasm32;
33 const function_imports_len: u32 = @intCast(wasm.function_imports.entries.len);
3433
3534 const tags = mir.instruction_tags;
3635 const datas = mir.instruction_datas;
......@@ -159,8 +158,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
159158 });
160159 code.appendNTimesAssumeCapacity(0, 5);
161160 } else {
162 const func_index = Wasm.FunctionIndex.fromIpNav(wasm, datas[inst].nav_index).?;
163 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
161 appendOutputFunctionIndex(code, .fromIpNav(wasm, datas[inst].nav_index));
164162 }
165163
166164 inst += 1;
......@@ -200,8 +198,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
200198 });
201199 code.appendNTimesAssumeCapacity(0, 5);
202200 } else {
203 const func_index = Wasm.FunctionIndex.fromTagNameType(wasm, datas[inst].ip_index).?;
204 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
201 appendOutputFunctionIndex(code, .fromTagNameType(wasm, datas[inst].ip_index));
205202 }
206203
207204 inst += 1;
......@@ -225,8 +222,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
225222 });
226223 code.appendNTimesAssumeCapacity(0, 5);
227224 } else {
228 const func_index = Wasm.FunctionIndex.fromSymbolName(wasm, symbol_name).?;
229 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
225 appendOutputFunctionIndex(code, .fromSymbolName(wasm, symbol_name));
230226 }
231227
232228 inst += 1;
......@@ -978,3 +974,7 @@ fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff
978974 }
979975 }
980976}
977
978fn appendOutputFunctionIndex(code: *std.ArrayListUnmanaged(u8), i: Wasm.OutputFunctionIndex) void {
979 leb.writeUleb128(code.fixedWriter(), @intFromEnum(i)) catch unreachable;
980}
src/link/Wasm.zig+26-4
......@@ -283,10 +283,6 @@ pub const FunctionIndex = enum(u32) {
283283 return &wasm.functions.keys()[@intFromEnum(index)];
284284 }
285285
286 pub fn toOutputFunctionIndex(index: FunctionIndex, wasm: *const Wasm) OutputFunctionIndex {
287 return @enumFromInt(wasm.function_imports.entries.len + @intFromEnum(index));
288 }
289
290286 pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) ?FunctionIndex {
291287 return fromResolution(wasm, .fromIpNav(wasm, nav_index));
292288 }
......@@ -324,6 +320,31 @@ pub const GlobalExport = extern struct {
324320/// `flush`.
325321pub const OutputFunctionIndex = enum(u32) {
326322 _,
323
324 pub fn fromFunctionIndex(wasm: *const Wasm, index: FunctionIndex) OutputFunctionIndex {
325 return @enumFromInt(wasm.function_imports.entries.len + @intFromEnum(index));
326 }
327
328 pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) OutputFunctionIndex {
329 const zcu = wasm.base.comp.zcu.?;
330 const ip = &zcu.intern_pool;
331 const nav = ip.getNav(nav_index);
332 if (nav.toExtern(ip)) |ext| {
333 const name = wasm.getExistingString(ext.name.toSlice(ip)).?;
334 if (wasm.function_imports.getIndex(name)) |i| return @enumFromInt(i);
335 return fromFunctionIndex(wasm, FunctionIndex.fromSymbolName(wasm, name).?);
336 } else {
337 return fromFunctionIndex(wasm, FunctionIndex.fromIpNav(wasm, nav_index).?);
338 }
339 }
340
341 pub fn fromTagNameType(wasm: *const Wasm, tag_type: InternPool.Index) OutputFunctionIndex {
342 return fromFunctionIndex(wasm, FunctionIndex.fromTagNameType(wasm, tag_type).?);
343 }
344
345 pub fn fromSymbolName(wasm: *const Wasm, name: String) OutputFunctionIndex {
346 return fromFunctionIndex(wasm, FunctionIndex.fromSymbolName(wasm, name).?);
347 }
327348};
328349
329350/// Index into `Wasm.globals`.
......@@ -788,6 +809,7 @@ pub const FunctionImport = extern struct {
788809 const zcu = wasm.base.comp.zcu.?;
789810 const ip = &zcu.intern_pool;
790811 const nav = ip.getNav(nav_index);
812 //log.debug("Resolution.fromIpNav {}({})", .{ nav.fqn.fmt(ip), nav_index });
791813 return pack(wasm, .{
792814 .zcu_func = @enumFromInt(wasm.zcu_funcs.getIndex(nav.status.resolved.val).?),
793815 });