@@ -401,20 +401,19 @@ fn T_captured_tydescs(type_names tn, uint n) -> TypeRef {
401
401
ret T_struct ( _vec. init_elt [ TypeRef ] ( T_ptr ( T_tydesc ( tn) ) , n) ) ;
402
402
}
403
403
404
- fn T_obj ( type_names tn, uint n_captured_tydescs ,
405
- TypeRef llfields_ty ) -> TypeRef {
406
- ret T_struct ( vec ( T_ptr ( T_tydesc ( tn) ) ,
407
- T_captured_tydescs ( tn, n_captured_tydescs) ,
408
- llfields_ty) ) ;
409
- }
404
+ fn T_obj_ptr ( type_names tn, uint n_captured_tydescs ) -> TypeRef {
405
+ // This function is not publicly exposed because it returns an incomplete
406
+ // type. The dynamically-sized fields follow the captured tydescs.
407
+ fn T_obj ( type_names tn, uint n_captured_tydescs ) -> TypeRef {
408
+ ret T_struct ( vec ( T_ptr ( T_tydesc ( tn) ) ,
409
+ T_captured_tydescs ( tn, n_captured_tydescs) ) ) ;
410
+ }
410
411
411
- fn T_obj_ptr ( type_names tn, uint n_captured_tydescs ,
412
- TypeRef llfields_ty ) -> TypeRef {
413
- ret T_ptr ( T_box ( T_obj ( tn, n_captured_tydescs, llfields_ty) ) ) ;
412
+ ret T_ptr ( T_box ( T_obj ( tn, n_captured_tydescs) ) ) ;
414
413
}
415
414
416
415
fn T_opaque_obj_ptr ( type_names tn) -> TypeRef {
417
- ret T_obj_ptr ( tn, 0 u, T_nil ( ) ) ;
416
+ ret T_obj_ptr ( tn, 0 u) ;
418
417
}
419
418
420
419
@@ -4265,56 +4264,73 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
4265
4264
ret ret_ty_of_fn_ty( ty. ann_to_type( ann) ) ;
4266
4265
}
4267
4266
4268
- fn populate_fn_ctxt_from_llself( @block_ctxt cx, ValueRef llself) {
4267
+ fn populate_fn_ctxt_from_llself( @block_ctxt cx, ValueRef llself) -> result {
4268
+ auto bcx = cx;
4269
4269
4270
- let vec[ TypeRef ] llfield_tys = vec( ) ;
4270
+ let vec[ @ty . t ] field_tys = vec( ) ;
4271
4271
4272
- for ( ast. obj_field f in cx . fcx. ccx. obj_fields) {
4273
- llfield_tys += node_type ( cx . fcx. ccx, f. ann) ;
4272
+ for ( ast. obj_field f in bcx . fcx. ccx. obj_fields) {
4273
+ field_tys += vec ( node_ann_type ( bcx . fcx. ccx, f. ann) ) ;
4274
4274
}
4275
4275
4276
- auto n_typarams = _vec. len[ ast. ty_param] ( cx. fcx. ccx. obj_typarams) ;
4277
- let TypeRef llobj_box_ty = T_obj_ptr ( cx. fcx. ccx. tn, n_typarams,
4278
- T_struct ( llfield_tys) ) ;
4276
+ // Synthesize a tuple type for the fields so that GEP_tup_like() can work
4277
+ // its magic.
4278
+ auto fields_tup_ty = ty. plain_ty( ty. ty_tup( field_tys) ) ;
4279
+
4280
+ auto n_typarams = _vec. len[ ast. ty_param] ( bcx. fcx. ccx. obj_typarams) ;
4281
+ let TypeRef llobj_box_ty = T_obj_ptr ( bcx. fcx. ccx. tn, n_typarams) ;
4279
4282
4280
4283
auto box_cell =
4281
- cx . build. GEP ( llself,
4282
- vec( C_int ( 0 ) ,
4283
- C_int ( abi. obj_field_box) ) ) ;
4284
+ bcx . build. GEP ( llself,
4285
+ vec( C_int ( 0 ) ,
4286
+ C_int ( abi. obj_field_box) ) ) ;
4284
4287
4285
- auto box_ptr = cx . build. Load ( box_cell) ;
4288
+ auto box_ptr = bcx . build. Load ( box_cell) ;
4286
4289
4287
- box_ptr = cx . build. PointerCast ( box_ptr, llobj_box_ty) ;
4290
+ box_ptr = bcx . build. PointerCast ( box_ptr, llobj_box_ty) ;
4288
4291
4289
- auto obj_typarams = cx . build. GEP ( box_ptr,
4292
+ auto obj_typarams = bcx . build. GEP ( box_ptr,
4290
4293
vec( C_int ( 0 ) ,
4291
4294
C_int ( abi. box_rc_field_body) ,
4292
4295
C_int ( abi. obj_body_elt_typarams) ) ) ;
4293
4296
4294
- auto obj_fields = cx. build. GEP ( box_ptr,
4295
- vec( C_int ( 0 ) ,
4296
- C_int ( abi. box_rc_field_body) ,
4297
- C_int ( abi. obj_body_elt_fields) ) ) ;
4297
+ // The object fields immediately follow the type parameters, so we skip
4298
+ // over them to get the pointer.
4299
+ auto obj_fields = bcx. build. Add ( vp2i( bcx, obj_typarams) ,
4300
+ llsize_of( llvm. LLVMGetElementType ( val_ty( obj_typarams) ) ) ) ;
4301
+
4302
+ // If we can (i.e. the type is statically sized), then cast the resulting
4303
+ // fields pointer to the appropriate LLVM type. If not, just leave it as
4304
+ // i8 *.
4305
+ if ( !ty. type_has_dynamic_size( fields_tup_ty) ) {
4306
+ auto llfields_ty = type_of( bcx. fcx. ccx, fields_tup_ty) ;
4307
+ obj_fields = vi2p( bcx, obj_fields, T_ptr ( llfields_ty) ) ;
4308
+ } else {
4309
+ obj_fields = vi2p( bcx, obj_fields, T_ptr ( T_i8 ( ) ) ) ;
4310
+ }
4311
+
4298
4312
4299
4313
let int i = 0 ;
4300
4314
4301
- for ( ast. ty_param p in cx . fcx. ccx. obj_typarams) {
4302
- let ValueRef lltyparam = cx . build. GEP ( obj_typarams,
4303
- vec( C_int ( 0 ) ,
4304
- C_int ( i) ) ) ;
4305
- lltyparam = cx . build. Load ( lltyparam) ;
4306
- cx . fcx. lltydescs. insert( p. id, lltyparam) ;
4315
+ for ( ast. ty_param p in bcx . fcx. ccx. obj_typarams) {
4316
+ let ValueRef lltyparam = bcx . build. GEP ( obj_typarams,
4317
+ vec( C_int ( 0 ) ,
4318
+ C_int ( i) ) ) ;
4319
+ lltyparam = bcx . build. Load ( lltyparam) ;
4320
+ bcx . fcx. lltydescs. insert( p. id, lltyparam) ;
4307
4321
i += 1 ;
4308
4322
}
4309
4323
4310
4324
i = 0 ;
4311
- for ( ast. obj_field f in cx . fcx. ccx. obj_fields) {
4312
- let ValueRef llfield = cx . build . GEP ( obj_fields,
4313
- vec ( C_int ( 0 ) ,
4314
- C_int ( i ) ) ) ;
4325
+ for ( ast. obj_field f in bcx . fcx. ccx. obj_fields) {
4326
+ auto rslt = GEP_tup_like ( bcx , fields_tup_ty , obj_fields, vec ( 0 , i ) ) ;
4327
+ bcx = rslt . bcx ;
4328
+ auto llfield = rslt . val ;
4315
4329
cx. fcx. llobjfields. insert( f. id, llfield) ;
4316
4330
i += 1 ;
4317
4331
}
4332
+
4333
+ ret res( bcx, C_nil ( ) ) ;
4318
4334
}
4319
4335
4320
4336
fn trans_fn( @crate_ctxt cx, & ast. _fn f, ast. def_id fid,
@@ -4335,7 +4351,7 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
4335
4351
4336
4352
alt ( fcx. llself) {
4337
4353
case ( some[ ValueRef ] ( ?llself) ) {
4338
- populate_fn_ctxt_from_llself( bcx, llself) ;
4354
+ bcx = populate_fn_ctxt_from_llself( bcx, llself) . bcx ;
4339
4355
}
4340
4356
case ( _) {
4341
4357
}
0 commit comments