| ... | ... | @@ -4982,26 +4982,52 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4982 | 4982 | const result = result: { |
| 4983 | 4983 | const union_ty = func.air.typeOfIndex(inst); |
| 4984 | 4984 | const layout = union_ty.unionGetLayout(func.target); |
| 4985 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 4986 | const field = union_obj.fields.values()[extra.field_index]; |
| 4987 | const field_name = union_obj.fields.keys()[extra.field_index]; |
| 4988 | |
| 4989 | const tag_int = blk: { |
| 4990 | const tag_ty = union_ty.unionTagTypeHypothetical(); |
| 4991 | const enum_field_index = tag_ty.enumFieldIndex(field_name).?; |
| 4992 | var tag_val_payload: Value.Payload.U32 = .{ |
| 4993 | .base = .{ .tag = .enum_field_index }, |
| 4994 | .data = @intCast(u32, enum_field_index), |
| 4995 | }; |
| 4996 | const tag_val = Value.initPayload(&tag_val_payload.base); |
| 4997 | break :blk try func.lowerConstant(tag_val, tag_ty); |
| 4998 | }; |
| 4985 | 4999 | if (layout.payload_size == 0) { |
| 4986 | 5000 | if (layout.tag_size == 0) { |
| 4987 | 5001 | break :result WValue{ .none = {} }; |
| 4988 | 5002 | } |
| 4989 | 5003 | assert(!isByRef(union_ty, func.target)); |
| 4990 | | break :result WValue{ .imm32 = extra.field_index }; |
| 5004 | break :result tag_int; |
| 4991 | 5005 | } |
| 4992 | 5006 | assert(isByRef(union_ty, func.target)); |
| 4993 | 5007 | |
| 4994 | 5008 | const result_ptr = try func.allocStack(union_ty); |
| 4995 | 5009 | const payload = try func.resolveInst(extra.init); |
| 4996 | | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 4997 | | assert(union_obj.haveFieldTypes()); |
| 4998 | | const field = union_obj.fields.values()[extra.field_index]; |
| 4999 | | |
| 5000 | 5010 | if (layout.tag_align >= layout.payload_align) { |
| 5001 | | const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new); |
| 5002 | | try func.store(payload_ptr, payload, field.ty, 0); |
| 5011 | if (isByRef(field.ty, func.target)) { |
| 5012 | const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new); |
| 5013 | try func.store(payload_ptr, payload, field.ty, 0); |
| 5014 | } else { |
| 5015 | try func.store(result_ptr, payload, field.ty, @intCast(u32, layout.tag_size)); |
| 5016 | } |
| 5017 | |
| 5018 | if (layout.tag_size > 0) { |
| 5019 | try func.store(result_ptr, tag_int, union_obj.tag_ty, 0); |
| 5020 | } |
| 5003 | 5021 | } else { |
| 5004 | 5022 | try func.store(result_ptr, payload, field.ty, 0); |
| 5023 | if (layout.tag_size > 0) { |
| 5024 | try func.store( |
| 5025 | result_ptr, |
| 5026 | tag_int, |
| 5027 | union_obj.tag_ty, |
| 5028 | @intCast(u32, layout.payload_size), |
| 5029 | ); |
| 5030 | } |
| 5005 | 5031 | } |
| 5006 | 5032 | break :result result_ptr; |
| 5007 | 5033 | }; |