| ... | @@ -1613,6 +1613,7 @@ pub const DeclGen = struct { | ... | @@ -1613,6 +1613,7 @@ pub const DeclGen = struct { |
| 1613 | .unreach => return self.airUnreach(), | 1613 | .unreach => return self.airUnreach(), |
| 1614 | | 1614 | |
| 1615 | .unwrap_errunion_err => try self.airErrUnionErr(inst), | 1615 | .unwrap_errunion_err => try self.airErrUnionErr(inst), |
| | 1616 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 1616 | | 1617 | |
| 1617 | .assembly => try self.airAssembly(inst), | 1618 | .assembly => try self.airAssembly(inst), |
| 1618 | | 1619 | |
| ... | @@ -2561,6 +2562,42 @@ pub const DeclGen = struct { | ... | @@ -2561,6 +2562,42 @@ pub const DeclGen = struct { |
| 2561 | return try self.extractField(err_ty_ref, operand_id, eu_layout.errorFieldIndex()); | 2562 | return try self.extractField(err_ty_ref, operand_id, eu_layout.errorFieldIndex()); |
| 2562 | } | 2563 | } |
| 2563 | | 2564 | |
| | 2565 | fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| | 2566 | if (self.liveness.isUnused(inst)) return null; |
| | 2567 | |
| | 2568 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 2569 | const err_union_ty = self.air.typeOfIndex(inst); |
| | 2570 | const payload_ty = err_union_ty.errorUnionPayload(); |
| | 2571 | const operand_id = try self.resolve(ty_op.operand); |
| | 2572 | const eu_layout = self.errorUnionLayout(payload_ty); |
| | 2573 | |
| | 2574 | if (!eu_layout.payload_has_bits) { |
| | 2575 | return operand_id; |
| | 2576 | } |
| | 2577 | |
| | 2578 | const payload_ty_ref = try self.resolveType(payload_ty, .indirect); |
| | 2579 | var members = std.BoundedArray(IdRef, 2){}; |
| | 2580 | const payload_id = try self.constUndef(payload_ty_ref); |
| | 2581 | if (eu_layout.error_first) { |
| | 2582 | members.appendAssumeCapacity(operand_id); |
| | 2583 | members.appendAssumeCapacity(payload_id); |
| | 2584 | // TODO: ABI padding? |
| | 2585 | } else { |
| | 2586 | members.appendAssumeCapacity(payload_id); |
| | 2587 | members.appendAssumeCapacity(operand_id); |
| | 2588 | // TODO: ABI padding? |
| | 2589 | } |
| | 2590 | |
| | 2591 | const err_union_ty_ref = try self.resolveType(err_union_ty, .direct); |
| | 2592 | const result_id = self.spv.allocId(); |
| | 2593 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| | 2594 | .id_result_type = self.typeId(err_union_ty_ref), |
| | 2595 | .id_result = result_id, |
| | 2596 | .constituents = members.slice(), |
| | 2597 | }); |
| | 2598 | return result_id; |
| | 2599 | } |
| | 2600 | |
| 2564 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { | 2601 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 2565 | const target = self.getTarget(); | 2602 | const target = self.getTarget(); |
| 2566 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 2603 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |