diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index d19810df54..3ce64d4e89 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1200,6 +1200,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .optional_payload => self.airOptionalPayload(inst), .optional_payload_ptr => self.airOptionalPayload(inst), .optional_payload_ptr_set => self.airOptionalPayloadPtrSet(inst), + .ptrtoint => self.airPtrToInt(inst), .ret => self.airRet(inst), .ret_ptr => self.airRetPtr(inst), .ret_load => self.airRetLoad(inst), @@ -1729,6 +1730,8 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void { } else { try self.addLabel(.memory_address, decl.link.wasm.sym_index); } + } else if (val.castTag(.int_u64)) |int_ptr| { + try self.addImm32(@bitCast(i32, @intCast(u32, int_ptr.data))); } else return self.fail("Wasm TODO: emitConstant for other const pointer tag {s}", .{val.tag()}); }, .Void => {}, @@ -2601,3 +2604,9 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) InnerError!WValue { return slice_local; } + +fn airPtrToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { + if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; + const un_op = self.air.instructions.items(.data)[inst].un_op; + return self.resolveInst(un_op); +} diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 346ba1b6a0..d17ad8234d 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -284,10 +284,12 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { } fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void { - const label = emit.mir.instructions.items(.data)[inst].label; + const type_index = emit.mir.instructions.items(.data)[inst].label; try emit.code.append(std.wasm.opcode(.call_indirect)); + // NOTE: If we remove unused function types in the future for incremental + // linking, we must also emit a relocation for this `type_index` + try leb128.writeULEB128(emit.code.writer(), type_index); try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index - try leb128.writeULEB128(emit.code.writer(), label); } fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 6ec4113ad3..1ae50e8e33 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -646,7 +646,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { .kind = .{ .table = .{ .limits = .{ - .min = @intCast(u32, self.imports.count()), + .min = @intCast(u32, self.function_table.count()), .max = null, }, .reftype = .funcref, @@ -678,7 +678,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void { header_offset, .import, @intCast(u32, (try file.getPos()) - header_offset - header_size), - @intCast(u32, self.imports.count() + @boolToInt(import_memory)), + @intCast(u32, self.imports.count() + @boolToInt(import_memory) + @boolToInt(import_table)), ); } diff --git a/test/behavior.zig b/test/behavior.zig index 8d27103077..76f6032216 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -26,10 +26,15 @@ test { _ = @import("behavior/defer.zig"); _ = @import("behavior/enum.zig"); _ = @import("behavior/error.zig"); + _ = @import("behavior/fn_in_struct_in_comptime.zig"); _ = @import("behavior/hasdecl.zig"); _ = @import("behavior/hasfield.zig"); _ = @import("behavior/import.zig"); + _ = @import("behavior/incomplete_struct_param_tld.zig"); + _ = @import("behavior/inttoptr.zig"); + _ = @import("behavior/ptrcast.zig"); _ = @import("behavior/pub_enum.zig"); + _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); _ = @import("behavior/slice_sentinel_comptime.zig"); _ = @import("behavior/truncate.zig"); _ = @import("behavior/type.zig"); @@ -57,19 +62,14 @@ test { _ = @import("behavior/for.zig"); _ = @import("behavior/generics.zig"); _ = @import("behavior/if.zig"); - _ = @import("behavior/incomplete_struct_param_tld.zig"); _ = @import("behavior/int128.zig"); - _ = @import("behavior/inttoptr.zig"); _ = @import("behavior/member_func.zig"); _ = @import("behavior/null.zig"); _ = @import("behavior/optional.zig"); _ = @import("behavior/pointers.zig"); - _ = @import("behavior/ptrcast.zig"); - _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); _ = @import("behavior/struct.zig"); _ = @import("behavior/this.zig"); _ = @import("behavior/translate_c_macros.zig"); - _ = @import("behavior/underscore.zig"); _ = @import("behavior/while.zig"); _ = @import("behavior/void.zig");