@@ -4268,6 +4268,53 @@ fn build_environment(&@block_ctxt cx, &vec[ast::node_id] upvars) ->
4268
4268
ret tup( llenvptr, llenvptrty) ;
4269
4269
}
4270
4270
4271
+ // Given an enclosing block context, a new function context, a closure type,
4272
+ // and a list of upvars, generate code to load and populate the environment
4273
+ // with the upvars and type descriptors.
4274
+ fn load_environment( & @block_ctxt cx, & @fn_ctxt fcx,
4275
+ TypeRef llenvptrty, & vec[ ast:: node_id] upvars)
4276
+ {
4277
+ auto upvar_count = vec:: len( upvars) ;
4278
+ auto copy_args_bcx = new_raw_block_ctxt( fcx, fcx. llcopyargs) ;
4279
+
4280
+ // Populate the upvars from the environment.
4281
+ auto llremoteenvptr =
4282
+ copy_args_bcx. build. PointerCast ( fcx. llenv, llenvptrty) ;
4283
+ auto llremotebindingsptrptr =
4284
+ copy_args_bcx. build. GEP ( llremoteenvptr,
4285
+ [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ,
4286
+ C_int ( abi:: closure_elt_bindings) ] ) ;
4287
+ auto llremotebindingsptr =
4288
+ copy_args_bcx. build. Load ( llremotebindingsptrptr) ;
4289
+ auto i = 0 u;
4290
+ while ( i < upvar_count) {
4291
+ auto upvar_id = upvars. ( i) ;
4292
+ auto llupvarptrptr =
4293
+ copy_args_bcx. build. GEP ( llremotebindingsptr,
4294
+ [ C_int ( 0 ) , C_int ( i as int) ] ) ;
4295
+ auto llupvarptr = copy_args_bcx. build. Load ( llupvarptrptr) ;
4296
+ fcx. llupvars. insert( upvar_id, llupvarptr) ;
4297
+ i += 1 u;
4298
+ }
4299
+
4300
+ // Populate the type parameters from the environment.
4301
+ auto llremotetydescsptr =
4302
+ copy_args_bcx. build. GEP ( llremoteenvptr,
4303
+ [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ,
4304
+ C_int ( abi:: closure_elt_ty_params) ] ) ;
4305
+ auto tydesc_count = vec:: len( cx. fcx. lltydescs) ;
4306
+ i = 0 u;
4307
+ while ( i < tydesc_count) {
4308
+ auto llremotetydescptr =
4309
+ copy_args_bcx. build. GEP ( llremotetydescsptr,
4310
+ [ C_int ( 0 ) , C_int ( i as int) ] ) ;
4311
+ auto llremotetydesc = copy_args_bcx. build. Load ( llremotetydescptr) ;
4312
+ fcx. lltydescs += [ llremotetydesc] ;
4313
+ i += 1 u;
4314
+ }
4315
+
4316
+ }
4317
+
4271
4318
fn trans_for_each( & @block_ctxt cx, & @ast:: local local, & @ast:: expr seq,
4272
4319
& ast:: block body) -> result {
4273
4320
/*
@@ -4323,43 +4370,10 @@ fn trans_for_each(&@block_ctxt cx, &@ast::local local, &@ast::expr seq,
4323
4370
let ValueRef lliterbody =
4324
4371
decl_internal_fastcall_fn( lcx. ccx. llmod, s, iter_body_llty) ;
4325
4372
auto fcx = new_fn_ctxt( lcx, cx. sp, lliterbody) ;
4326
- auto copy_args_bcx = new_raw_block_ctxt( fcx, fcx. llcopyargs) ;
4327
-
4328
- // Populate the upvars from the environment.
4329
- auto llremoteenvptr =
4330
- copy_args_bcx. build. PointerCast ( fcx. llenv, llenvptrty) ;
4331
- auto llremotebindingsptrptr =
4332
- copy_args_bcx. build. GEP ( llremoteenvptr,
4333
- [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ,
4334
- C_int ( abi:: closure_elt_bindings) ] ) ;
4335
- auto llremotebindingsptr =
4336
- copy_args_bcx. build. Load ( llremotebindingsptrptr) ;
4337
- auto i = 0 u;
4338
- while ( i < upvar_count) {
4339
- auto upvar_id = upvars. ( i) ;
4340
- auto llupvarptrptr =
4341
- copy_args_bcx. build. GEP ( llremotebindingsptr,
4342
- [ C_int ( 0 ) , C_int ( i as int) ] ) ;
4343
- auto llupvarptr = copy_args_bcx. build. Load ( llupvarptrptr) ;
4344
- fcx. llupvars. insert( upvar_id, llupvarptr) ;
4345
- i += 1 u;
4346
- }
4347
4373
4348
- // Populate the type parameters from the environment.
4349
- auto llremotetydescsptr =
4350
- copy_args_bcx. build. GEP ( llremoteenvptr,
4351
- [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ,
4352
- C_int ( abi:: closure_elt_ty_params) ] ) ;
4353
- auto tydesc_count = vec:: len[ ValueRef ] ( cx. fcx. lltydescs) ;
4354
- i = 0 u;
4355
- while ( i < tydesc_count) {
4356
- auto llremotetydescptr =
4357
- copy_args_bcx. build. GEP ( llremotetydescsptr,
4358
- [ C_int ( 0 ) , C_int ( i as int) ] ) ;
4359
- auto llremotetydesc = copy_args_bcx. build. Load ( llremotetydescptr) ;
4360
- fcx. lltydescs += [ llremotetydesc] ;
4361
- i += 1 u;
4362
- }
4374
+ // Generate code to load the environment out of the
4375
+ // environment pointer.
4376
+ load_environment( cx, fcx, llenvptrty, upvars) ;
4363
4377
4364
4378
// Add an upvar for the loop variable alias.
4365
4379
fcx. llupvars. insert( decl_id, llvm:: LLVMGetParam ( fcx. llfn, 3 u) ) ;
0 commit comments