@@ -75,6 +75,7 @@ state type crate_ctxt = rec(session.session sess,
75
75
hashmap[ ast. def_id , ValueRef ] consts,
76
76
hashmap[ ast. def_id , ( ) ] obj_methods,
77
77
hashmap[ @ty. t , ValueRef ] tydescs,
78
+ vec[ ast. ty_param ] obj_typarams,
78
79
vec[ ast. obj_field ] obj_fields,
79
80
@glue_fns glues,
80
81
namegen names,
@@ -327,6 +328,24 @@ fn T_opaque_closure_ptr() -> TypeRef {
327
328
T_nil ( ) ) ;
328
329
}
329
330
331
+ fn T_captured_tydescs ( uint n) -> TypeRef {
332
+ ret T_struct ( _vec. init_elt [ TypeRef ] ( T_ptr ( T_tydesc ( ) ) , n) ) ;
333
+ }
334
+
335
+ fn T_obj ( uint n_captured_tydescs , TypeRef llfields_ty ) -> TypeRef {
336
+ ret T_struct ( vec ( T_ptr ( T_tydesc ( ) ) ,
337
+ T_captured_tydescs ( n_captured_tydescs) ,
338
+ llfields_ty) ) ;
339
+ }
340
+
341
+ fn T_obj_ptr ( uint n_captured_tydescs , TypeRef llfields_ty ) -> TypeRef {
342
+ ret T_ptr ( T_box ( T_obj ( n_captured_tydescs, llfields_ty) ) ) ;
343
+ }
344
+
345
+ fn T_opaque_obj_ptr ( ) -> TypeRef {
346
+ ret T_obj_ptr ( 0 u, T_nil ( ) ) ;
347
+ }
348
+
330
349
331
350
fn type_of ( @crate_ctxt cx , @ty. t t ) -> TypeRef {
332
351
let TypeRef llty = type_of_inner ( cx, t) ;
@@ -455,11 +474,9 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
455
474
mtys += T_ptr ( mty) ;
456
475
}
457
476
let TypeRef vtbl = T_struct ( mtys) ;
458
- let TypeRef body = T_struct ( vec ( T_ptr ( T_tydesc ( ) ) ,
459
- T_nil ( ) ) ) ;
460
- let TypeRef pair =
461
- T_struct ( vec ( T_ptr ( vtbl) ,
462
- T_ptr ( T_box ( body) ) ) ) ;
477
+ let TypeRef pair = T_struct ( vec ( T_ptr ( vtbl) ,
478
+ T_opaque_obj_ptr ( ) ) ) ;
479
+
463
480
auto abs_pair = llvm. LLVMResolveTypeHandle ( th. llth ) ;
464
481
llvm. LLVMRefineType ( abs_pair, pair) ;
465
482
abs_pair = llvm. LLVMResolveTypeHandle ( th. llth ) ;
@@ -963,6 +980,7 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
963
980
// Is the supplied type a type param? If so, return the passed-in tydesc.
964
981
alt ( ty. type_param ( t) ) {
965
982
case ( some[ ast. def_id ] ( ?id) ) {
983
+ check ( cx. fcx . lltydescs . contains_key ( id) ) ;
966
984
ret res( cx, cx. fcx . lltydescs . get ( id) ) ;
967
985
}
968
986
case ( none[ ast. def_id ] ) { /* fall through */ }
@@ -3474,19 +3492,17 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
3474
3492
ret ret_ty_of_fn_ty( ty. ann_to_type( ann) ) ;
3475
3493
}
3476
3494
3477
- fn create_llobjfields_for_fields ( @block_ctxt cx, ValueRef llself) {
3495
+ fn populate_fn_ctxt_from_llself ( @block_ctxt cx, ValueRef llself) {
3478
3496
3479
3497
let vec[ TypeRef ] llfield_tys = vec( ) ;
3480
3498
3481
3499
for ( ast. obj_field f in cx. fcx . ccx . obj_fields ) {
3482
3500
llfield_tys += node_type ( cx. fcx . ccx , f. ann ) ;
3483
3501
}
3484
3502
3485
- let TypeRef llfields_ty = T_struct ( llfield_tys) ;
3486
- let TypeRef lltydesc_ty = T_ptr ( T_tydesc ( ) ) ;
3487
- let TypeRef llobj_body_ty = T_struct ( vec ( lltydesc_ty,
3488
- llfields_ty) ) ;
3489
- let TypeRef llobj_box_ty = T_ptr ( T_box ( llobj_body_ty) ) ;
3503
+ auto n_typarams = _vec. len [ ast. ty_param ] ( cx. fcx . ccx . obj_typarams ) ;
3504
+ let TypeRef llobj_box_ty = T_obj_ptr ( n_typarams,
3505
+ T_struct ( llfield_tys) ) ;
3490
3506
3491
3507
auto box_cell =
3492
3508
cx. build . GEP ( llself,
@@ -3497,12 +3513,28 @@ fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
3497
3513
3498
3514
box_ptr = cx. build . PointerCast ( box_ptr, llobj_box_ty) ;
3499
3515
3516
+ auto obj_typarams = cx. build . GEP ( box_ptr,
3517
+ vec ( C_int ( 0 ) ,
3518
+ C_int ( abi. box_rc_field_body ) ,
3519
+ C_int ( abi. obj_body_elt_typarams ) ) ) ;
3520
+
3500
3521
auto obj_fields = cx. build . GEP ( box_ptr,
3501
3522
vec ( C_int ( 0 ) ,
3502
3523
C_int ( abi. box_rc_field_body ) ,
3503
3524
C_int ( abi. obj_body_elt_fields ) ) ) ;
3504
3525
3505
3526
let int i = 0 ;
3527
+
3528
+ for ( ast. ty_param p in cx. fcx. ccx. obj_typarams) {
3529
+ let ValueRef lltyparam = cx. build . GEP ( obj_typarams,
3530
+ vec ( C_int ( 0 ) ,
3531
+ C_int ( i) ) ) ;
3532
+ lltyparam = cx. build . Load ( lltyparam) ;
3533
+ cx. fcx . lltydescs . insert ( p. id , lltyparam) ;
3534
+ i += 1 ;
3535
+ }
3536
+
3537
+ i = 0 ;
3506
3538
for ( ast. obj_field f in cx. fcx. ccx. obj_fields) {
3507
3539
let ValueRef llfield = cx. build . GEP ( obj_fields,
3508
3540
vec ( C_int ( 0 ) ,
@@ -3529,7 +3561,7 @@ fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
3529
3561
3530
3562
alt ( fcx. llself ) {
3531
3563
case ( some[ ValueRef ] ( ?llself) ) {
3532
- create_llobjfields_for_fields ( bcx, llself) ;
3564
+ populate_fn_ctxt_from_llself ( bcx, llself) ;
3533
3565
}
3534
3566
case ( _) {
3535
3567
}
@@ -3623,10 +3655,11 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
3623
3655
C_int ( abi. obj_field_box) ) ) ;
3624
3656
bcx. build. Store ( vtbl, pair_vtbl) ;
3625
3657
3626
- let TypeRef llbox_ty = T_ptr ( T_box ( T_struct ( vec( T_ptr ( T_tydesc ( ) ) ,
3627
- T_nil ( ) ) ) ) ) ;
3628
- if ( _vec. len[ ty. arg] ( arg_tys) == 0 u) {
3629
- // Store null into pair, if no args.
3658
+ let TypeRef llbox_ty = T_opaque_obj_ptr ( ) ;
3659
+
3660
+ if ( _vec. len[ ast. ty_param] ( ty_params) == 0 u &&
3661
+ _vec. len[ ty. arg] ( arg_tys) == 0 u) {
3662
+ // Store null into pair, if no args or typarams.
3630
3663
bcx. build. Store ( C_null ( llbox_ty) , pair_box) ;
3631
3664
} else {
3632
3665
// Malloc a box for the body and copy args in.
@@ -3636,8 +3669,16 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
3636
3669
}
3637
3670
3638
3671
// Synthesize an obj body type.
3672
+ auto tydesc_ty = plain_ty( ty. ty_type) ;
3673
+ let vec[ @ty. t] tps = vec( ) ;
3674
+ for ( ast. ty_param tp in ty_params) {
3675
+ append[ @ty. t] ( tps, tydesc_ty) ;
3676
+ }
3677
+
3678
+ let @ty. t typarams_ty = plain_ty( ty. ty_tup( tps) ) ;
3639
3679
let @ty. t fields_ty = plain_ty( ty. ty_tup( obj_fields) ) ;
3640
- let @ty. t body_ty = plain_ty( ty. ty_tup( vec( plain_ty( ty. ty_type) ,
3680
+ let @ty. t body_ty = plain_ty( ty. ty_tup( vec( tydesc_ty,
3681
+ typarams_ty,
3641
3682
fields_ty) ) ) ;
3642
3683
let @ty. t boxed_body_ty = plain_ty( ty. ty_box( body_ty) ) ;
3643
3684
@@ -3664,13 +3705,28 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
3664
3705
bcx = body_td. bcx;
3665
3706
bcx. build. Store ( body_td. val, body_tydesc. val) ;
3666
3707
3708
+ // Copy typarams into captured typarams.
3709
+ auto body_typarams =
3710
+ GEP_tup_like ( bcx, body_ty, body. val,
3711
+ vec( 0 , abi. obj_body_elt_typarams) ) ;
3712
+ bcx = body_typarams. bcx;
3713
+ let int i = 0 ;
3714
+ for ( ast. ty_param tp in ty_params) {
3715
+ auto typaram = bcx. fcx. lltydescs. get( tp. id) ;
3716
+ auto capture = GEP_tup_like ( bcx, typarams_ty, body_typarams. val,
3717
+ vec( 0 , i) ) ;
3718
+ bcx = capture. bcx;
3719
+ bcx = copy_ty( bcx, INIT , capture. val, typaram, tydesc_ty) . bcx;
3720
+ i += 1 ;
3721
+ }
3722
+
3667
3723
// Copy args into body fields.
3668
3724
auto body_fields =
3669
3725
GEP_tup_like ( bcx, body_ty, body. val,
3670
3726
vec( 0 , abi. obj_body_elt_fields) ) ;
3671
3727
bcx = body_fields. bcx;
3672
3728
3673
- let int i = 0 ;
3729
+ i = 0 ;
3674
3730
for ( ast. obj_field f in ob. fields) {
3675
3731
auto arg = bcx. fcx. llargs. get( f. id) ;
3676
3732
arg = load_scalar_or_boxed( bcx, arg, arg_tys. ( i) . ty) ;
@@ -3792,6 +3848,7 @@ fn trans_item(@crate_ctxt cx, &ast.item item) {
3792
3848
}
3793
3849
case ( ast. item_obj( ?name, ?ob, ?tps, ?oid, ?ann) ) {
3794
3850
auto sub_cx = @rec( path=cx. path + "." + name,
3851
+ obj_typarams=tps,
3795
3852
obj_fields=ob. fields with * cx) ;
3796
3853
trans_obj( sub_cx, ob, oid, tps, ann) ;
3797
3854
}
@@ -4353,6 +4410,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
4353
4410
auto hasher = ty. hash_ty ;
4354
4411
auto eqer = ty. eq_ty ;
4355
4412
auto tydescs = map. mk_hashmap [ @ty. t , ValueRef ] ( hasher, eqer) ;
4413
+ let vec[ ast. ty_param ] obj_typarams = vec ( ) ;
4356
4414
let vec[ ast. obj_field ] obj_fields = vec ( ) ;
4357
4415
4358
4416
auto cx = @rec ( sess = sess,
@@ -4369,6 +4427,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
4369
4427
consts = new_def_hash[ ValueRef ] ( ) ,
4370
4428
obj_methods = new_def_hash[ ( ) ] ( ) ,
4371
4429
tydescs = tydescs,
4430
+ obj_typarams = obj_typarams,
4372
4431
obj_fields = obj_fields,
4373
4432
glues = glues,
4374
4433
names = namegen ( 0 ) ,
0 commit comments