diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-03-08 20:04:49 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-09 13:53:10 -0700 |
| commit | f931c0638da6b0935de31044be93c8ab1387e04e (patch) | |
| tree | 1d27b6e8b1dafd02bcffbb36ce8fc478f8504627 /src | |
| parent | d01bfa032dd21a2464ca6be850053f68387acea8 (diff) | |
| download | zig-f931c0638da6b0935de31044be93c8ab1387e04e.tar.gz zig-f931c0638da6b0935de31044be93c8ab1387e04e.zip | |
wasm: Implement `errunion_payload_ptr_set`
This also fixes `ret_ptr` where the pointee type is zero-sized.
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index ce05a9652d..ae4b1d30b6 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1277,6 +1277,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), .wrap_errunion_err => self.airWrapErrUnionErr(inst), + .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst), .wasm_memory_size => self.airWasmMemorySize(inst), .wasm_memory_grow => self.airWasmMemoryGrow(inst), @@ -1333,7 +1334,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .atomic_rmw, .tag_name, .error_name, - .errunion_payload_ptr_set, .field_parent_ptr, .mul_add, @@ -1372,7 +1372,10 @@ fn airRet(self: *Self, inst: Air.Inst.Index) InnerError!WValue { fn airRetPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue { const child_type = self.air.typeOfIndex(inst).childType(); - if (child_type.abiSize(self.target) == 0) return WValue{ .none = {} }; + + if (!child_type.isFnOrHasRuntimeBits()) { + return self.allocStack(Type.usize); // create pointer to void + } if (isByRef(child_type, self.target)) { return self.return_value; @@ -3226,3 +3229,26 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue { return self.fail("TODO: Implement 'fptrunc' for floats with bitsize: {d}", .{dest_bits}); } } + +fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const err_set_ty = self.air.typeOf(ty_op.operand).childType(); + const err_ty = err_set_ty.errorUnionSet(); + const payload_ty = err_set_ty.errorUnionPayload(); + const operand = try self.resolveInst(ty_op.operand); + + // set error-tag to '0' to annotate error union is non-error + try self.store(operand, .{ .imm32 = 0 }, err_ty, 0); + + if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; + + if (!payload_ty.hasRuntimeBits()) { + return operand; + } + + const err_align = err_set_ty.abiAlignment(self.target); + const set_size = err_ty.abiSize(self.target); + const offset = mem.alignForwardGeneric(u64, set_size, err_align); + + return self.buildPointerOffset(operand, @intCast(u32, offset), .new); +} |
