@@ -387,6 +387,10 @@ fn T_closure_ptr(type_names tn,
387
387
TypeRef lltarget_ty ,
388
388
TypeRef llbindings_ty ,
389
389
uint n_ty_params ) -> TypeRef {
390
+
391
+ // NB: keep this in sync with code in trans_bind; we're making
392
+ // an LLVM typeref structure that has the same "shape" as the ty.t
393
+ // it constructs.
390
394
ret T_ptr ( T_box ( T_struct ( vec ( T_ptr ( T_tydesc ( tn) ) ,
391
395
lltarget_ty,
392
396
llbindings_ty,
@@ -3322,7 +3326,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
3322
3326
@ty. t incoming_fty,
3323
3327
@ty. t outgoing_fty,
3324
3328
vec[ option. t[ @ast. expr] ] args,
3325
- TypeRef llclosure_ty ,
3329
+ @ty . t closure_ty ,
3326
3330
vec[ @ty. t] bound_tys,
3327
3331
uint ty_param_count) -> ValueRef {
3328
3332
// Construct a thunk-call with signature incoming_fty, and that copies
@@ -3335,21 +3339,15 @@ fn trans_bind_thunk(@crate_ctxt cx,
3335
3339
auto fcx = new_fn_ctxt( cx, llthunk) ;
3336
3340
auto bcx = new_top_block_ctxt( fcx) ;
3337
3341
3338
- auto llclosure = bcx. build. PointerCast ( fcx. llenv, llclosure_ty) ;
3339
-
3340
- auto llbody = bcx. build. GEP ( llclosure,
3341
- vec( C_int ( 0 ) ,
3342
- C_int ( abi. box_rc_field_body) ) ) ;
3343
-
3344
- auto lltarget = bcx. build. GEP ( llbody,
3345
- vec( C_int ( 0 ) ,
3346
- C_int ( abi. closure_elt_target) ) ) ;
3347
-
3348
- auto llbound = bcx. build. GEP ( llbody,
3349
- vec( C_int ( 0 ) ,
3350
- C_int ( abi. closure_elt_bindings) ) ) ;
3342
+ auto llclosure_ptr_ty = type_of( cx, plain_ty( ty. ty_box( closure_ty) ) ) ;
3343
+ auto llclosure = bcx. build. PointerCast ( fcx. llenv, llclosure_ptr_ty) ;
3351
3344
3352
- auto lltargetclosure = bcx. build. GEP ( lltarget,
3345
+ auto lltarget = GEP_tup_like ( bcx, closure_ty, llclosure,
3346
+ vec( 0 ,
3347
+ abi. box_rc_field_body,
3348
+ abi. closure_elt_target) ) ;
3349
+ bcx = lltarget. bcx;
3350
+ auto lltargetclosure = bcx. build. GEP ( lltarget. val,
3353
3351
vec( C_int ( 0 ) ,
3354
3352
C_int ( abi. fn_field_box) ) ) ;
3355
3353
lltargetclosure = bcx. build. Load ( lltargetclosure) ;
@@ -3370,10 +3368,13 @@ fn trans_bind_thunk(@crate_ctxt cx,
3370
3368
let uint i = 0 u;
3371
3369
while ( i < ty_param_count) {
3372
3370
auto lltyparam_ptr =
3373
- bcx. build . GEP ( llbody, vec ( C_int ( 0 ) ,
3374
- C_int ( abi. closure_elt_ty_params ) ,
3375
- C_int ( i as int ) ) ) ;
3376
- llargs += vec ( bcx. build . Load ( lltyparam_ptr) ) ;
3371
+ GEP_tup_like ( bcx, closure_ty, llclosure,
3372
+ vec ( 0 ,
3373
+ abi. box_rc_field_body ,
3374
+ abi. closure_elt_ty_params ,
3375
+ ( i as int ) ) ) ;
3376
+ bcx = lltyparam_ptr. bcx ;
3377
+ llargs += vec ( bcx. build . Load ( lltyparam_ptr. val ) ) ;
3377
3378
i += 1 u;
3378
3379
}
3379
3380
@@ -3385,11 +3386,15 @@ fn trans_bind_thunk(@crate_ctxt cx,
3385
3386
3386
3387
// Arg provided at binding time; thunk copies it from closure.
3387
3388
case ( some[ @ast. expr] ( _) ) {
3388
- let ValueRef bound_arg = bcx. build. GEP ( llbound,
3389
- vec( C_int ( 0 ) ,
3390
- C_int ( b) ) ) ;
3389
+ auto bound_arg =
3390
+ GEP_tup_like ( bcx, closure_ty, llclosure,
3391
+ vec( 0 ,
3392
+ abi. box_rc_field_body,
3393
+ abi. closure_elt_bindings,
3394
+ b) ) ;
3391
3395
// FIXME: possibly support passing aliases someday.
3392
- llargs += bcx. build. Load ( bound_arg) ;
3396
+ bcx = bound_arg. bcx;
3397
+ llargs += bcx. build. Load ( bound_arg. val) ;
3393
3398
b += 1 ;
3394
3399
}
3395
3400
@@ -3412,7 +3417,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
3412
3417
}
3413
3418
3414
3419
// FIXME: turn this call + ret into a tail call.
3415
- auto lltargetfn = bcx. build. GEP ( lltarget,
3420
+ auto lltargetfn = bcx. build. GEP ( lltarget. val ,
3416
3421
vec( C_int ( 0 ) ,
3417
3422
C_int ( abi. fn_field_code) ) ) ;
3418
3423
lltargetfn = bcx. build. Load ( lltargetfn) ;
@@ -3479,21 +3484,26 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
3479
3484
i += 1 u;
3480
3485
}
3481
3486
3482
- // Get the type of the bound function.
3483
- let TypeRef lltarget_ty = type_of( bcx. fcx. ccx, outgoing_fty) ;
3484
-
3485
3487
// Synthesize a closure type.
3486
3488
let @ty. t bindings_ty = plain_ty( ty. ty_tup( bound_tys) ) ;
3487
- let TypeRef llbindings_ty = type_of( bcx. fcx. ccx, bindings_ty) ;
3488
- let TypeRef llclosure_ty = T_closure_ptr ( cx. fcx. ccx. tn,
3489
- lltarget_ty,
3490
- llbindings_ty,
3491
- ty_param_count) ;
3492
-
3493
- // Malloc a box for the body.
3494
- // FIXME: this isn't generic-safe
3495
- auto r = trans_raw_malloc( bcx, llclosure_ty,
3496
- llsize_of( llvm. LLVMGetElementType ( llclosure_ty) ) ) ;
3489
+
3490
+ // NB: keep this in sync with T_closure_ptr; we're making
3491
+ // a ty.t structure that has the same "shape" as the LLVM type
3492
+ // it constructs.
3493
+ let @ty. t tydesc_ty = plain_ty( ty. ty_type) ;
3494
+
3495
+ let vec[ @ty. t] captured_tys =
3496
+ _vec. init_elt[ @ty. t] ( tydesc_ty, ty_param_count) ;
3497
+
3498
+ let vec[ @ty. t] closure_tys =
3499
+ vec( tydesc_ty,
3500
+ outgoing_fty,
3501
+ bindings_ty,
3502
+ plain_ty( ty. ty_tup( captured_tys) ) ) ;
3503
+
3504
+ let @ty. t closure_ty = plain_ty( ty. ty_tup( closure_tys) ) ;
3505
+
3506
+ auto r = trans_malloc_boxed( bcx, closure_ty) ;
3497
3507
auto box = r. val;
3498
3508
bcx = r. bcx;
3499
3509
auto rc = bcx. build. GEP ( box,
@@ -3561,9 +3571,10 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
3561
3571
C_int ( abi. fn_field_code) ) ) ;
3562
3572
3563
3573
let @ty. t pair_ty = node_ann_type( cx. fcx. ccx, ann) ;
3574
+
3564
3575
let ValueRef llthunk =
3565
3576
trans_bind_thunk( cx. fcx. ccx, pair_ty, outgoing_fty,
3566
- args, llclosure_ty , bound_tys,
3577
+ args, closure_ty , bound_tys,
3567
3578
ty_param_count) ;
3568
3579
3569
3580
bcx. build. Store ( llthunk, pair_code) ;
0 commit comments