authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-12-29 22:28:18+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-01 12:59:43+01:00
logb9a0401e2368894e135b1d1e870219c6b1543af2
tree108527ce39611ed0218ebb42b22aa68063825096
parentf644c8b0478126484ce2780eb98336c2b4ff0177
signature Commit is signed but in an unrecognized format.

wasm: Implement @ptrToInt and fix indirect function call

- Previously the table index and function type index were switched. This commit swaps them. - This also emits the correct indirect function calls count when importing the function table

4 files changed, 20 insertions(+), 9 deletions(-)

src/arch/wasm/CodeGen.zig+9
......@@ -1200,6 +1200,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
12001200 .optional_payload => self.airOptionalPayload(inst),
12011201 .optional_payload_ptr => self.airOptionalPayload(inst),
12021202 .optional_payload_ptr_set => self.airOptionalPayloadPtrSet(inst),
1203 .ptrtoint => self.airPtrToInt(inst),
12031204 .ret => self.airRet(inst),
12041205 .ret_ptr => self.airRetPtr(inst),
12051206 .ret_load => self.airRetLoad(inst),
......@@ -1729,6 +1730,8 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
17291730 } else {
17301731 try self.addLabel(.memory_address, decl.link.wasm.sym_index);
17311732 }
1733 } else if (val.castTag(.int_u64)) |int_ptr| {
1734 try self.addImm32(@bitCast(i32, @intCast(u32, int_ptr.data)));
17321735 } else return self.fail("Wasm TODO: emitConstant for other const pointer tag {s}", .{val.tag()});
17331736 },
17341737 .Void => {},
......@@ -2601,3 +2604,9 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
26012604
26022605 return slice_local;
26032606}
2607
2608fn airPtrToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2609 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
2610 const un_op = self.air.instructions.items(.data)[inst].un_op;
2611 return self.resolveInst(un_op);
2612}
src/arch/wasm/Emit.zig+4-2
......@@ -284,10 +284,12 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
284284}
285285
286286fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
287 const label = emit.mir.instructions.items(.data)[inst].label;
287 const type_index = emit.mir.instructions.items(.data)[inst].label;
288288 try emit.code.append(std.wasm.opcode(.call_indirect));
289 // NOTE: If we remove unused function types in the future for incremental
290 // linking, we must also emit a relocation for this `type_index`
291 try leb128.writeULEB128(emit.code.writer(), type_index);
289292 try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index
290 try leb128.writeULEB128(emit.code.writer(), label);
291293}
292294
293295fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
src/link/Wasm.zig+2-2
......@@ -646,7 +646,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
646646 .kind = .{
647647 .table = .{
648648 .limits = .{
649 .min = @intCast(u32, self.imports.count()),
649 .min = @intCast(u32, self.function_table.count()),
650650 .max = null,
651651 },
652652 .reftype = .funcref,
......@@ -678,7 +678,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
678678 header_offset,
679679 .import,
680680 @intCast(u32, (try file.getPos()) - header_offset - header_size),
681 @intCast(u32, self.imports.count() + @boolToInt(import_memory)),
681 @intCast(u32, self.imports.count() + @boolToInt(import_memory) + @boolToInt(import_table)),
682682 );
683683 }
684684
test/behavior.zig+5-5
......@@ -26,10 +26,15 @@ test {
2626 _ = @import("behavior/defer.zig");
2727 _ = @import("behavior/enum.zig");
2828 _ = @import("behavior/error.zig");
29 _ = @import("behavior/fn_in_struct_in_comptime.zig");
2930 _ = @import("behavior/hasdecl.zig");
3031 _ = @import("behavior/hasfield.zig");
3132 _ = @import("behavior/import.zig");
33 _ = @import("behavior/incomplete_struct_param_tld.zig");
34 _ = @import("behavior/inttoptr.zig");
35 _ = @import("behavior/ptrcast.zig");
3236 _ = @import("behavior/pub_enum.zig");
37 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
3338 _ = @import("behavior/slice_sentinel_comptime.zig");
3439 _ = @import("behavior/truncate.zig");
3540 _ = @import("behavior/type.zig");
......@@ -57,19 +62,14 @@ test {
5762 _ = @import("behavior/for.zig");
5863 _ = @import("behavior/generics.zig");
5964 _ = @import("behavior/if.zig");
60 _ = @import("behavior/incomplete_struct_param_tld.zig");
6165 _ = @import("behavior/int128.zig");
62 _ = @import("behavior/inttoptr.zig");
6366 _ = @import("behavior/member_func.zig");
6467 _ = @import("behavior/null.zig");
6568 _ = @import("behavior/optional.zig");
6669 _ = @import("behavior/pointers.zig");
67 _ = @import("behavior/ptrcast.zig");
68 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
6970 _ = @import("behavior/struct.zig");
7071 _ = @import("behavior/this.zig");
7172 _ = @import("behavior/translate_c_macros.zig");
72 _ = @import("behavior/underscore.zig");
7373 _ = @import("behavior/while.zig");
7474 _ = @import("behavior/void.zig");
7575