@@ -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 );
0 commit comments