| ... | ... | @@ -3154,19 +3154,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro |
| 3154 | 3154 | .@"extern", .@"packed" => unreachable, |
| 3155 | 3155 | }, |
| 3156 | 3156 | .@"union" => switch (base_ty.containerLayout(zcu)) { |
| 3157 | | .auto => off: { |
| 3158 | | // Keep in sync with the `un` case of `generateSymbol`. |
| 3159 | | const layout = base_ty.unionGetLayout(zcu); |
| 3160 | | if (layout.payload_size == 0) break :off 0; |
| 3161 | | if (layout.tag_size == 0) break :off 0; |
| 3162 | | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| 3163 | | // Tag first. |
| 3164 | | break :off layout.tag_size; |
| 3165 | | } else { |
| 3166 | | // Payload first. |
| 3167 | | break :off 0; |
| 3168 | | } |
| 3169 | | }, |
| 3157 | .auto => base_ty.structFieldOffset(@intCast(field.index), zcu), |
| 3170 | 3158 | .@"extern", .@"packed" => unreachable, |
| 3171 | 3159 | }, |
| 3172 | 3160 | else => unreachable, |
| ... | ... | @@ -3312,16 +3300,16 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3312 | 3300 | }, |
| 3313 | 3301 | else => unreachable, |
| 3314 | 3302 | }, |
| 3315 | | .un => |un| { |
| 3316 | | // in this case we have a packed union which will not be passed by reference. |
| 3317 | | const constant_ty = if (un.tag == .none) |
| 3318 | | try ty.unionBackingType(pt) |
| 3319 | | else field_ty: { |
| 3320 | | const union_obj = zcu.typeToUnion(ty).?; |
| 3321 | | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; |
| 3322 | | break :field_ty Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 3323 | | }; |
| 3324 | | return cg.lowerConstant(Value.fromInterned(un.val), constant_ty); |
| 3303 | .un => { |
| 3304 | const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu))); |
| 3305 | |
| 3306 | var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer |
| 3307 | val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable; |
| 3308 | const int_val = try pt.intValue( |
| 3309 | int_type, |
| 3310 | mem.readInt(u64, &buf, .little), |
| 3311 | ); |
| 3312 | return cg.lowerConstant(int_val, int_type); |
| 3325 | 3313 | }, |
| 3326 | 3314 | .memoized_call => unreachable, |
| 3327 | 3315 | } |
| ... | ... | @@ -3369,6 +3357,14 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 3369 | 3357 | const packed_struct = zcu.typeToPackedStruct(ty).?; |
| 3370 | 3358 | return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip))); |
| 3371 | 3359 | }, |
| 3360 | .@"union" => switch (ty.containerLayout(zcu)) { |
| 3361 | .@"packed" => switch (ty.bitSize(zcu)) { |
| 3362 | 0...32 => return .{ .imm32 = 0xaaaaaaaa }, |
| 3363 | 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa }, |
| 3364 | else => unreachable, |
| 3365 | }, |
| 3366 | else => unreachable, |
| 3367 | }, |
| 3372 | 3368 | else => return cg.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(zcu)}), |
| 3373 | 3369 | } |
| 3374 | 3370 | } |
| ... | ... | @@ -4211,7 +4207,6 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) |
| 4211 | 4207 | assert(isByRef(eu_ty, zcu, cg.target)); |
| 4212 | 4208 | break :result try cg.load(operand, payload_ty, pl_offset); |
| 4213 | 4209 | } |
| 4214 | | |
| 4215 | 4210 | }; |
| 4216 | 4211 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 4217 | 4212 | } |
| ... | ... | @@ -5691,13 +5686,25 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 5691 | 5686 | } |
| 5692 | 5687 | |
| 5693 | 5688 | fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5694 | | const zcu = cg.pt.zcu; |
| 5689 | const pt = cg.pt; |
| 5690 | const zcu = pt.zcu; |
| 5695 | 5691 | const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5696 | 5692 | const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5697 | 5693 | |
| 5698 | 5694 | const field_ptr = try cg.resolveInst(extra.field_ptr); |
| 5699 | | const parent_ty = ty_pl.ty.toType().childType(zcu); |
| 5700 | | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); |
| 5695 | const parent_ptr_ty = cg.typeOfIndex(inst); |
| 5696 | const parent_ty = parent_ptr_ty.childType(zcu); |
| 5697 | const field_ptr_ty = cg.typeOf(extra.field_ptr); |
| 5698 | const field_index = extra.field_index; |
| 5699 | const field_offset = switch (parent_ty.containerLayout(zcu)) { |
| 5700 | .auto, .@"extern" => parent_ty.structFieldOffset(field_index, zcu), |
| 5701 | .@"packed" => offset: { |
| 5702 | const parent_ptr_offset = parent_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset; |
| 5703 | const field_offset = if (zcu.typeToStruct(parent_ty)) |loaded_struct| pt.structPackedFieldBitOffset(loaded_struct, field_index) else 0; |
| 5704 | const field_ptr_offset = field_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset; |
| 5705 | break :offset @divExact(parent_ptr_offset + field_offset - field_ptr_offset, 8); |
| 5706 | }, |
| 5707 | }; |
| 5701 | 5708 | |
| 5702 | 5709 | const result = if (field_offset != 0) result: { |
| 5703 | 5710 | const base = try cg.buildPointerOffset(field_ptr, 0, .new); |