authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-27 12:11:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:51-07:00
log02119362d70bb16ae6ab00124928bde89834c83f
tree8fc933f9cba5df08252b091bc40ef40ad310bfea
parent6ccb53bff130a473f9d2cc3d0c1ad3a8c6399b2d

wasm linking: handle unreachable call_indirect

The compiler crashed when we tried to call a function pointer for which the type signature does not match any function body or function import in the entire wasm executable, because there is no way to create a reference to a function without it being in the function table or import table. Solution is to make this instruction lower to unreachable.

1 files changed, 14 insertions(+), 2 deletions(-)

src/codegen/wasm/Emit.zig+14-2
......@@ -188,8 +188,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
188188 .fromInterned(fn_info.return_type),
189189 target,
190190 ).?;
191 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect));
192191 if (is_obj) {
192 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect));
193193 try wasm.out_relocs.append(gpa, .{
194194 .offset = @intCast(code.items.len),
195195 .pointee = .{ .type_index = func_ty_index },
......@@ -198,7 +198,19 @@ pub fn lowerToCode(emit: *Emit) Error!void {
198198 });
199199 code.appendNTimesAssumeCapacity(0, 5);
200200 } else {
201 const index: Wasm.Flush.FuncTypeIndex = .fromTypeIndex(func_ty_index, &wasm.flush_buffer);
201 const index: Wasm.Flush.FuncTypeIndex = @enumFromInt(wasm.flush_buffer.func_types.getIndex(func_ty_index) orelse {
202 // In this case we tried to call a function pointer for
203 // which the type signature does not match any function
204 // body or function import in the entire wasm executable.
205 //
206 // Since there is no way to create a reference to a
207 // function without it being in the function table or
208 // import table, this instruction is unreachable.
209 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.@"unreachable"));
210 inst += 1;
211 continue :loop tags[inst];
212 });
213 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect));
202214 writeUleb128(code, @intFromEnum(index));
203215 }
204216 writeUleb128(code, @as(u32, 0)); // table index