| ... | ... | @@ -1277,6 +1277,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1277 | 1277 | .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), |
| 1278 | 1278 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), |
| 1279 | 1279 | .wrap_errunion_err => self.airWrapErrUnionErr(inst), |
| 1280 | .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst), |
| 1280 | 1281 | |
| 1281 | 1282 | .wasm_memory_size => self.airWasmMemorySize(inst), |
| 1282 | 1283 | .wasm_memory_grow => self.airWasmMemoryGrow(inst), |
| ... | ... | @@ -1333,7 +1334,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1333 | 1334 | .atomic_rmw, |
| 1334 | 1335 | .tag_name, |
| 1335 | 1336 | .error_name, |
| 1336 | | .errunion_payload_ptr_set, |
| 1337 | 1337 | .field_parent_ptr, |
| 1338 | 1338 | .mul_add, |
| 1339 | 1339 | |
| ... | ... | @@ -1372,7 +1372,10 @@ fn airRet(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1372 | 1372 | |
| 1373 | 1373 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1374 | 1374 | const child_type = self.air.typeOfIndex(inst).childType(); |
| 1375 | | if (child_type.abiSize(self.target) == 0) return WValue{ .none = {} }; |
| 1375 | |
| 1376 | if (!child_type.isFnOrHasRuntimeBits()) { |
| 1377 | return self.allocStack(Type.usize); // create pointer to void |
| 1378 | } |
| 1376 | 1379 | |
| 1377 | 1380 | if (isByRef(child_type, self.target)) { |
| 1378 | 1381 | return self.return_value; |
| ... | ... | @@ -3226,3 +3229,26 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3226 | 3229 | return self.fail("TODO: Implement 'fptrunc' for floats with bitsize: {d}", .{dest_bits}); |
| 3227 | 3230 | } |
| 3228 | 3231 | } |
| 3232 | |
| 3233 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3234 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3235 | const err_set_ty = self.air.typeOf(ty_op.operand).childType(); |
| 3236 | const err_ty = err_set_ty.errorUnionSet(); |
| 3237 | const payload_ty = err_set_ty.errorUnionPayload(); |
| 3238 | const operand = try self.resolveInst(ty_op.operand); |
| 3239 | |
| 3240 | // set error-tag to '0' to annotate error union is non-error |
| 3241 | try self.store(operand, .{ .imm32 = 0 }, err_ty, 0); |
| 3242 | |
| 3243 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 3244 | |
| 3245 | if (!payload_ty.hasRuntimeBits()) { |
| 3246 | return operand; |
| 3247 | } |
| 3248 | |
| 3249 | const err_align = err_set_ty.abiAlignment(self.target); |
| 3250 | const set_size = err_ty.abiSize(self.target); |
| 3251 | const offset = mem.alignForwardGeneric(u64, set_size, err_align); |
| 3252 | |
| 3253 | return self.buildPointerOffset(operand, @intCast(u32, offset), .new); |
| 3254 | } |