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 {...@@ -620,6 +620,14 @@ pub const Nav = struct {
620 };620 };
621 }621 }
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
623 /// Asserts that `status == .resolved`.631 /// Asserts that `status == .resolved`.
624 pub fn isThreadLocal(nav: Nav, ip: *const InternPool) bool {632 pub fn isThreadLocal(nav: Nav, ip: *const InternPool) bool {
625 const val = nav.status.resolved.val;633 const val = nav.status.resolved.val;
src/arch/wasm/Emit.zig+7-7
...@@ -30,7 +30,6 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -30,7 +30,6 @@ pub fn lowerToCode(emit: *Emit) Error!void {
30 const is_obj = comp.config.output_mode == .Obj;30 const is_obj = comp.config.output_mode == .Obj;
31 const target = &comp.root_mod.resolved_target.result;31 const target = &comp.root_mod.resolved_target.result;
32 const is_wasm32 = target.cpu.arch == .wasm32;32 const is_wasm32 = target.cpu.arch == .wasm32;
33 const function_imports_len: u32 = @intCast(wasm.function_imports.entries.len);
3433
35 const tags = mir.instruction_tags;34 const tags = mir.instruction_tags;
36 const datas = mir.instruction_datas;35 const datas = mir.instruction_datas;
...@@ -159,8 +158,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -159,8 +158,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
159 });158 });
160 code.appendNTimesAssumeCapacity(0, 5);159 code.appendNTimesAssumeCapacity(0, 5);
161 } else {160 } else {
162 const func_index = Wasm.FunctionIndex.fromIpNav(wasm, datas[inst].nav_index).?;161 appendOutputFunctionIndex(code, .fromIpNav(wasm, datas[inst].nav_index));
163 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
164 }162 }
165163
166 inst += 1;164 inst += 1;
...@@ -200,8 +198,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -200,8 +198,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
200 });198 });
201 code.appendNTimesAssumeCapacity(0, 5);199 code.appendNTimesAssumeCapacity(0, 5);
202 } else {200 } else {
203 const func_index = Wasm.FunctionIndex.fromTagNameType(wasm, datas[inst].ip_index).?;201 appendOutputFunctionIndex(code, .fromTagNameType(wasm, datas[inst].ip_index));
204 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
205 }202 }
206203
207 inst += 1;204 inst += 1;
...@@ -225,8 +222,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -225,8 +222,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
225 });222 });
226 code.appendNTimesAssumeCapacity(0, 5);223 code.appendNTimesAssumeCapacity(0, 5);
227 } else {224 } else {
228 const func_index = Wasm.FunctionIndex.fromSymbolName(wasm, symbol_name).?;225 appendOutputFunctionIndex(code, .fromSymbolName(wasm, symbol_name));
229 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
230 }226 }
231227
232 inst += 1;228 inst += 1;
...@@ -978,3 +974,7 @@ fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff...@@ -978,3 +974,7 @@ fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff
978 }974 }
979 }975 }
980}976}
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) {...@@ -283,10 +283,6 @@ pub const FunctionIndex = enum(u32) {
283 return &wasm.functions.keys()[@intFromEnum(index)];283 return &wasm.functions.keys()[@intFromEnum(index)];
284 }284 }
285285
286 pub fn toOutputFunctionIndex(index: FunctionIndex, wasm: *const Wasm) OutputFunctionIndex {
287 return @enumFromInt(wasm.function_imports.entries.len + @intFromEnum(index));
288 }
289
290 pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) ?FunctionIndex {286 pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) ?FunctionIndex {
291 return fromResolution(wasm, .fromIpNav(wasm, nav_index));287 return fromResolution(wasm, .fromIpNav(wasm, nav_index));
292 }288 }
...@@ -324,6 +320,31 @@ pub const GlobalExport = extern struct {...@@ -324,6 +320,31 @@ pub const GlobalExport = extern struct {
324/// `flush`.320/// `flush`.
325pub const OutputFunctionIndex = enum(u32) {321pub const OutputFunctionIndex = enum(u32) {
326 _,322 _,
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 }
327};348};
328349
329/// Index into `Wasm.globals`.350/// Index into `Wasm.globals`.
...@@ -788,6 +809,7 @@ pub const FunctionImport = extern struct {...@@ -788,6 +809,7 @@ pub const FunctionImport = extern struct {
788 const zcu = wasm.base.comp.zcu.?;809 const zcu = wasm.base.comp.zcu.?;
789 const ip = &zcu.intern_pool;810 const ip = &zcu.intern_pool;
790 const nav = ip.getNav(nav_index);811 const nav = ip.getNav(nav_index);
812 //log.debug("Resolution.fromIpNav {}({})", .{ nav.fqn.fmt(ip), nav_index });
791 return pack(wasm, .{813 return pack(wasm, .{
792 .zcu_func = @enumFromInt(wasm.zcu_funcs.getIndex(nav.status.resolved.val).?),814 .zcu_func = @enumFromInt(wasm.zcu_funcs.getIndex(nav.status.resolved.val).?),
793 });815 });