@@ -4212,7 +4212,9 @@ fn trans_cast(cx: &@block_ctxt, e: &@ast::expr, id: ast::node_id) -> result {
4212
4212
fn trans_bind_thunk ( cx : & @local_ctxt , sp : & span , incoming_fty : & ty:: t ,
4213
4213
outgoing_fty : & ty:: t , args : & [ option:: t[ @ast:: expr ] ] ,
4214
4214
env_ty : & ty:: t , bound_tys : & [ ty:: t ] ,
4215
- ty_param_count : uint ) -> { val : ValueRef , ty: TypeRef } {
4215
+ ty_param_count : uint ,
4216
+ target_fn : & option:: t [ ValueRef ] ) ->
4217
+ { val : ValueRef , ty: TypeRef } {
4216
4218
4217
4219
// Here we're not necessarily constructing a thunk in the sense of
4218
4220
// "function with no arguments". The result of compiling 'bind f(foo,
@@ -4270,16 +4272,22 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
4270
4272
// creating. (In our running example, target is the function f.) Pick
4271
4273
// out the pointer to the target function from the environment. The
4272
4274
// target function lives in the first binding spot.
4273
- let lltarget =
4274
- GEP_tup_like ( bcx, closure_ty, llclosure,
4275
- ~[ 0 , abi:: box_rc_field_body,
4276
- abi:: closure_elt_bindings, 0 ] ) ;
4277
- bcx = lltarget. bcx ;
4275
+ let ( lltarget, starting_idx) = alt target_fn {
4276
+ some( lltarget) { ( lltarget, 0 ) }
4277
+ none. {
4278
+ let lltarget =
4279
+ GEP_tup_like ( bcx, closure_ty, llclosure,
4280
+ ~[ 0 , abi:: box_rc_field_body,
4281
+ abi:: closure_elt_bindings, 0 ] ) ;
4282
+ bcx = lltarget. bcx ;
4283
+ ( lltarget. val , 1 )
4284
+ }
4285
+ } ;
4278
4286
4279
4287
// And then, pick out the target function's own environment. That's what
4280
4288
// we'll use as the environment the thunk gets.
4281
4289
let lltargetclosure =
4282
- bcx. build . GEP ( lltarget. val , ~[ C_int ( 0 ) , C_int ( abi:: fn_field_box) ] ) ;
4290
+ bcx. build . GEP ( lltarget, ~[ C_int ( 0 ) , C_int ( abi:: fn_field_box) ] ) ;
4283
4291
lltargetclosure = bcx. build . Load ( lltargetclosure) ;
4284
4292
4285
4293
// Get f's return type, which will also be the return type of the entire
@@ -4315,7 +4323,7 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
4315
4323
}
4316
4324
4317
4325
let a: uint = 3 u; // retptr, task ptr, env come first
4318
- let b: int = 1 ;
4326
+ let b: int = starting_idx ;
4319
4327
let outgoing_arg_index: uint = 0 u;
4320
4328
let llout_arg_tys: [ TypeRef ] =
4321
4329
type_of_explicit_args ( cx. ccx , sp, outgoing_args) ;
@@ -4377,7 +4385,7 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
4377
4385
}
4378
4386
4379
4387
let lltargetfn =
4380
- bcx. build . GEP ( lltarget. val , ~[ C_int ( 0 ) , C_int ( abi:: fn_field_code) ] ) ;
4388
+ bcx. build . GEP ( lltarget, ~[ C_int ( 0 ) , C_int ( abi:: fn_field_code) ] ) ;
4381
4389
4382
4390
// Cast the outgoing function to the appropriate type.
4383
4391
// This is necessary because the type of the function that we have
@@ -4427,16 +4435,21 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
4427
4435
}
4428
4436
let bcx = f_res. res . bcx ;
4429
4437
4430
- // Cast the function we are binding to be the type that the closure
4431
- // will expect it to have. The type the closure knows about has the
4432
- // type parameters substituted with the real types.
4433
- let llclosurety = T_ptr ( type_of ( bcx_ccx ( cx) , cx. sp , outgoing_fty) ) ;
4434
- let src_loc = bcx. build . PointerCast ( f_res. res . val , llclosurety) ;
4435
- let bound_f = { res : { bcx : bcx, val : src_loc} with f_res} ;
4436
4438
4437
- // Arrange for the bound function to live in the first binding spot.
4438
- let bound_tys: [ ty:: t ] = ~[ outgoing_fty] ;
4439
- let bound_vals: [ lval_result ] = ~[ bound_f] ;
4439
+ // Arrange for the bound function to live in the first binding spot
4440
+ // if the function is not statically known.
4441
+ let ( bound_tys, bound_vals, target_res) = if f_res. is_mem {
4442
+ // Cast the function we are binding to be the type that the closure
4443
+ // will expect it to have. The type the closure knows about has the
4444
+ // type parameters substituted with the real types.
4445
+ let llclosurety = T_ptr ( type_of ( bcx_ccx ( cx) , cx. sp , outgoing_fty) ) ;
4446
+ let src_loc = bcx. build . PointerCast ( f_res. res . val , llclosurety) ;
4447
+ let bound_f = { res : { bcx : bcx, val : src_loc} with f_res} ;
4448
+ ( ~[ outgoing_fty] , ~[ bound_f] , none)
4449
+ } else {
4450
+ ( ~[ ] , ~[ ] , some ( f_res. res . val ) )
4451
+ } ;
4452
+
4440
4453
// Translate the bound expressions.
4441
4454
for e: @ast:: expr in bound {
4442
4455
let lv = trans_lval ( bcx, e) ;
@@ -4455,7 +4468,8 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
4455
4468
let pair_ty = node_id_type ( bcx_ccx ( cx) , id) ;
4456
4469
let llthunk =
4457
4470
trans_bind_thunk ( cx. fcx . lcx , cx. sp , pair_ty, outgoing_fty_real,
4458
- args, closure. ptrty , bound_tys, ty_param_count) ;
4471
+ args, closure. ptrty , bound_tys, ty_param_count,
4472
+ target_res) ;
4459
4473
4460
4474
// Construct the function pair
4461
4475
let pair_v = create_real_fn_pair ( bcx, llthunk. ty , llthunk. val ,
0 commit comments