| ... | ... | @@ -702,16 +702,50 @@ pub fn generateSymbol( |
| 702 | 702 | .ErrorUnion => { |
| 703 | 703 | const error_ty = typed_value.ty.errorUnionSet(); |
| 704 | 704 | const payload_ty = typed_value.ty.errorUnionPayload(); |
| 705 | |
| 706 | if (error_ty.errorSetCardinality() == .zero) { |
| 707 | const payload_val = typed_value.val.castTag(.eu_payload).?.data; |
| 708 | return generateSymbol(bin_file, src_loc, .{ |
| 709 | .ty = payload_ty, |
| 710 | .val = payload_val, |
| 711 | }, code, debug_output, reloc_info); |
| 712 | } |
| 713 | |
| 705 | 714 | const is_payload = typed_value.val.errorUnionIsPayload(); |
| 706 | 715 | |
| 716 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 717 | const err_val = if (!is_payload) typed_value.val else Value.initTag(.zero); |
| 718 | return generateSymbol(bin_file, src_loc, .{ |
| 719 | .ty = error_ty, |
| 720 | .val = err_val, |
| 721 | }, code, debug_output, reloc_info); |
| 722 | } |
| 723 | |
| 724 | const payload_align = payload_ty.abiAlignment(target); |
| 725 | const error_align = Type.anyerror.abiAlignment(target); |
| 707 | 726 | const abi_align = typed_value.ty.abiAlignment(target); |
| 708 | 727 | |
| 728 | // error value first when its type is larger than the error union's payload |
| 729 | if (error_align > payload_align) { |
| 730 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 731 | .ty = error_ty, |
| 732 | .val = if (is_payload) Value.initTag(.zero) else typed_value.val, |
| 733 | }, code, debug_output, reloc_info)) { |
| 734 | .appended => {}, |
| 735 | .externally_managed => |external_slice| { |
| 736 | code.appendSliceAssumeCapacity(external_slice); |
| 737 | }, |
| 738 | .fail => |em| return Result{ .fail = em }, |
| 739 | } |
| 740 | } |
| 741 | |
| 742 | // emit payload part of the error union |
| 709 | 743 | { |
| 710 | | const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero); |
| 711 | 744 | const begin = code.items.len; |
| 745 | const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef); |
| 712 | 746 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 713 | | .ty = error_ty, |
| 714 | | .val = error_val, |
| 747 | .ty = payload_ty, |
| 748 | .val = payload_val, |
| 715 | 749 | }, code, debug_output, reloc_info)) { |
| 716 | 750 | .appended => {}, |
| 717 | 751 | .externally_managed => |external_slice| { |
| ... | ... | @@ -728,12 +762,12 @@ pub fn generateSymbol( |
| 728 | 762 | } |
| 729 | 763 | } |
| 730 | 764 | |
| 731 | | if (payload_ty.hasRuntimeBits()) { |
| 765 | // Payload size is larger than error set, so emit our error set last |
| 766 | if (error_align < payload_align) { |
| 732 | 767 | const begin = code.items.len; |
| 733 | | const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef); |
| 734 | 768 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 735 | | .ty = payload_ty, |
| 736 | | .val = payload_val, |
| 769 | .ty = error_ty, |
| 770 | .val = if (is_payload) Value.initTag(.zero) else typed_value.val, |
| 737 | 771 | }, code, debug_output, reloc_info)) { |
| 738 | 772 | .appended => {}, |
| 739 | 773 | .externally_managed => |external_slice| { |