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
signaturelock-open 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 {...@@ -1200,6 +1200,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1200 .optional_payload => self.airOptionalPayload(inst),1200 .optional_payload => self.airOptionalPayload(inst),
1201 .optional_payload_ptr => self.airOptionalPayload(inst),1201 .optional_payload_ptr => self.airOptionalPayload(inst),
1202 .optional_payload_ptr_set => self.airOptionalPayloadPtrSet(inst),1202 .optional_payload_ptr_set => self.airOptionalPayloadPtrSet(inst),
1203 .ptrtoint => self.airPtrToInt(inst),
1203 .ret => self.airRet(inst),1204 .ret => self.airRet(inst),
1204 .ret_ptr => self.airRetPtr(inst),1205 .ret_ptr => self.airRetPtr(inst),
1205 .ret_load => self.airRetLoad(inst),1206 .ret_load => self.airRetLoad(inst),
...@@ -1729,6 +1730,8 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {...@@ -1729,6 +1730,8 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
1729 } else {1730 } else {
1730 try self.addLabel(.memory_address, decl.link.wasm.sym_index);1731 try self.addLabel(.memory_address, decl.link.wasm.sym_index);
1731 }1732 }
1733 } else if (val.castTag(.int_u64)) |int_ptr| {
1734 try self.addImm32(@bitCast(i32, @intCast(u32, int_ptr.data)));
1732 } else return self.fail("Wasm TODO: emitConstant for other const pointer tag {s}", .{val.tag()});1735 } else return self.fail("Wasm TODO: emitConstant for other const pointer tag {s}", .{val.tag()});
1733 },1736 },
1734 .Void => {},1737 .Void => {},
...@@ -2601,3 +2604,9 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2601,3 +2604,9 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
26012604
2602 return slice_local;2605 return slice_local;
2603}2606}
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 {...@@ -284,10 +284,12 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
284}284}
285285
286fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {286fn 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;
288 try emit.code.append(std.wasm.opcode(.call_indirect));288 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);
289 try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index292 try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index
290 try leb128.writeULEB128(emit.code.writer(), label);
291}293}
292294
293fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {295fn 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 {...@@ -646,7 +646,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
646 .kind = .{646 .kind = .{
647 .table = .{647 .table = .{
648 .limits = .{648 .limits = .{
649 .min = @intCast(u32, self.imports.count()),649 .min = @intCast(u32, self.function_table.count()),
650 .max = null,650 .max = null,
651 },651 },
652 .reftype = .funcref,652 .reftype = .funcref,
...@@ -678,7 +678,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {...@@ -678,7 +678,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
678 header_offset,678 header_offset,
679 .import,679 .import,
680 @intCast(u32, (try file.getPos()) - header_offset - header_size),680 @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)),
682 );682 );
683 }683 }
684684
test/behavior.zig+5-5
...@@ -26,10 +26,15 @@ test {...@@ -26,10 +26,15 @@ test {
26 _ = @import("behavior/defer.zig");26 _ = @import("behavior/defer.zig");
27 _ = @import("behavior/enum.zig");27 _ = @import("behavior/enum.zig");
28 _ = @import("behavior/error.zig");28 _ = @import("behavior/error.zig");
29 _ = @import("behavior/fn_in_struct_in_comptime.zig");
29 _ = @import("behavior/hasdecl.zig");30 _ = @import("behavior/hasdecl.zig");
30 _ = @import("behavior/hasfield.zig");31 _ = @import("behavior/hasfield.zig");
31 _ = @import("behavior/import.zig");32 _ = @import("behavior/import.zig");
33 _ = @import("behavior/incomplete_struct_param_tld.zig");
34 _ = @import("behavior/inttoptr.zig");
35 _ = @import("behavior/ptrcast.zig");
32 _ = @import("behavior/pub_enum.zig");36 _ = @import("behavior/pub_enum.zig");
37 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
33 _ = @import("behavior/slice_sentinel_comptime.zig");38 _ = @import("behavior/slice_sentinel_comptime.zig");
34 _ = @import("behavior/truncate.zig");39 _ = @import("behavior/truncate.zig");
35 _ = @import("behavior/type.zig");40 _ = @import("behavior/type.zig");
...@@ -57,19 +62,14 @@ test {...@@ -57,19 +62,14 @@ test {
57 _ = @import("behavior/for.zig");62 _ = @import("behavior/for.zig");
58 _ = @import("behavior/generics.zig");63 _ = @import("behavior/generics.zig");
59 _ = @import("behavior/if.zig");64 _ = @import("behavior/if.zig");
60 _ = @import("behavior/incomplete_struct_param_tld.zig");
61 _ = @import("behavior/int128.zig");65 _ = @import("behavior/int128.zig");
62 _ = @import("behavior/inttoptr.zig");
63 _ = @import("behavior/member_func.zig");66 _ = @import("behavior/member_func.zig");
64 _ = @import("behavior/null.zig");67 _ = @import("behavior/null.zig");
65 _ = @import("behavior/optional.zig");68 _ = @import("behavior/optional.zig");
66 _ = @import("behavior/pointers.zig");69 _ = @import("behavior/pointers.zig");
67 _ = @import("behavior/ptrcast.zig");
68 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
69 _ = @import("behavior/struct.zig");70 _ = @import("behavior/struct.zig");
70 _ = @import("behavior/this.zig");71 _ = @import("behavior/this.zig");
71 _ = @import("behavior/translate_c_macros.zig");72 _ = @import("behavior/translate_c_macros.zig");
72 _ = @import("behavior/underscore.zig");
73 _ = @import("behavior/while.zig");73 _ = @import("behavior/while.zig");
74 _ = @import("behavior/void.zig");74 _ = @import("behavior/void.zig");
7575