@@ -950,7 +950,12 @@ const DeclGen = struct {
950
950
});
951
951
return result_id ;
952
952
},
953
- .field = > unreachable , // TODO
953
+ .field = > | field | {
954
+ const base_ptr_ty = mod .intern_pool .typeOf (field .base ).toType ();
955
+ const base_ptr = try self .constantPtr (base_ptr_ty , field .base .toValue ());
956
+ const field_index : u32 = @intCast (field .index );
957
+ return try self .structFieldPtr (ptr_ty , base_ptr_ty , base_ptr , field_index );
958
+ },
954
959
}
955
960
}
956
961
@@ -2021,6 +2026,7 @@ const DeclGen = struct {
2021
2026
.union_init = > try self .airUnionInit (inst ),
2022
2027
2023
2028
.struct_field_val = > try self .airStructFieldVal (inst ),
2029
+ .field_parent_ptr = > try self .airFieldParentPtr (inst ),
2024
2030
2025
2031
.struct_field_ptr_index_0 = > try self .airStructFieldPtrIndex (inst , 0 ),
2026
2032
.struct_field_ptr_index_1 = > try self .airStructFieldPtrIndex (inst , 1 ),
@@ -2918,13 +2924,8 @@ const DeclGen = struct {
2918
2924
return result_id ;
2919
2925
}
2920
2926
2921
- fn airIntFromPtr (self : * DeclGen , inst : Air.Inst.Index ) ! ? IdRef {
2922
- if (self .liveness .isUnused (inst )) return null ;
2923
-
2924
- const un_op = self .air .instructions .items (.data )[inst ].un_op ;
2925
- const operand_id = try self .resolve (un_op );
2927
+ fn intFromPtr (self : * DeclGen , operand_id : IdRef ) ! IdRef {
2926
2928
const result_type_id = try self .resolveTypeId (Type .usize );
2927
-
2928
2929
const result_id = self .spv .allocId ();
2929
2930
try self .func .body .emit (self .spv .gpa , .OpConvertPtrToU , .{
2930
2931
.id_result_type = result_type_id ,
@@ -2934,6 +2935,14 @@ const DeclGen = struct {
2934
2935
return result_id ;
2935
2936
}
2936
2937
2938
+ fn airIntFromPtr (self : * DeclGen , inst : Air.Inst.Index ) ! ? IdRef {
2939
+ if (self .liveness .isUnused (inst )) return null ;
2940
+
2941
+ const un_op = self .air .instructions .items (.data )[inst ].un_op ;
2942
+ const operand_id = try self .resolve (un_op );
2943
+ return try self .intFromPtr (operand_id );
2944
+ }
2945
+
2937
2946
fn airFloatFromInt (self : * DeclGen , inst : Air.Inst.Index ) ! ? IdRef {
2938
2947
if (self .liveness .isUnused (inst )) return null ;
2939
2948
@@ -3474,13 +3483,44 @@ const DeclGen = struct {
3474
3483
}
3475
3484
}
3476
3485
3486
+ fn airFieldParentPtr (self : * DeclGen , inst : Air.Inst.Index ) ! ? IdRef {
3487
+ const mod = self .module ;
3488
+ const ty_pl = self .air .instructions .items (.data )[inst ].ty_pl ;
3489
+ const extra = self .air .extraData (Air .FieldParentPtr , ty_pl .payload ).data ;
3490
+
3491
+ const parent_ty = self .air .getRefType (ty_pl .ty ).childType (mod );
3492
+ const res_ty = try self .resolveType (self .air .getRefType (ty_pl .ty ), .indirect );
3493
+ const usize_ty = Type .usize ;
3494
+ const usize_ty_ref = try self .resolveType (usize_ty , .direct );
3495
+
3496
+ const field_ptr = try self .resolve (extra .field_ptr );
3497
+ const field_ptr_int = try self .intFromPtr (field_ptr );
3498
+ const field_offset = parent_ty .structFieldOffset (extra .field_index , mod );
3499
+
3500
+ const base_ptr_int = base_ptr_int : {
3501
+ if (field_offset == 0 ) break :base_ptr_int field_ptr_int ;
3502
+
3503
+ const field_offset_id = try self .constInt (usize_ty_ref , field_offset );
3504
+ break :base_ptr_int try self .binOpSimple (usize_ty , field_ptr_int , field_offset_id , .OpISub );
3505
+ };
3506
+
3507
+ const base_ptr = self .spv .allocId ();
3508
+ try self .func .body .emit (self .spv .gpa , .OpConvertUToPtr , .{
3509
+ .id_result_type = self .spv .resultId (res_ty ),
3510
+ .id_result = base_ptr ,
3511
+ .integer_value = base_ptr_int ,
3512
+ });
3513
+
3514
+ return base_ptr ;
3515
+ }
3516
+
3477
3517
fn structFieldPtr (
3478
3518
self : * DeclGen ,
3479
3519
result_ptr_ty : Type ,
3480
3520
object_ptr_ty : Type ,
3481
3521
object_ptr : IdRef ,
3482
3522
field_index : u32 ,
3483
- ) ! ? IdRef {
3523
+ ) ! IdRef {
3484
3524
const result_ty_ref = try self .resolveType (result_ptr_ty , .direct );
3485
3525
3486
3526
const mod = self .module ;
0 commit comments