@@ -5299,8 +5299,14 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
5299
5299
auto sub_cx = extend_path( cx. fcx. lcx, ccx. names. next( "anon") ) ;
5300
5300
auto s = mangle_internal_name_by_path( ccx, sub_cx. path) ;
5301
5301
auto llfn = decl_internal_fastcall_fn( ccx. llmod, s, llfnty) ;
5302
- trans_fn( sub_cx, e. span, f, llfn, none, ~[ ] , e. id) ;
5303
- ret rslt( cx, create_fn_pair( ccx, s, llfnty, llfn, false) ) ;
5302
+
5303
+ auto fn_res = trans_closure( some( cx) , some( llfnty) , sub_cx,
5304
+ e. span, f, llfn, none, ~[ ] , e. id) ;
5305
+ auto fn_pair = alt ( fn_res) {
5306
+ some( ?fn_pair) { fn_pair }
5307
+ none { create_fn_pair( ccx, s, llfnty, llfn, false) }
5308
+ } ;
5309
+ ret rslt( cx, fn_pair) ;
5304
5310
}
5305
5311
case ( ast:: expr_block( ?blk) ) {
5306
5312
auto sub_cx = new_scope_block_ctxt( cx, "block-expr body") ;
@@ -6592,10 +6598,16 @@ fn finish_fn(&@fn_ctxt fcx, BasicBlockRef lltop) {
6592
6598
new_builder( fcx. lldynamicallocas) . Br ( lltop) ;
6593
6599
}
6594
6600
6595
-
6596
- fn trans_fn_inner( @local_ctxt cx, & span sp, & ast:: _fn f, ValueRef llfndecl,
6597
- option:: t[ ty:: t] ty_self, & ast:: ty_param[ ] ty_params,
6598
- ast:: node_id id) {
6601
+ // trans_closure: Builds an LLVM function out of a source function.
6602
+ // If the function closes over its environment a closure will be
6603
+ // returned.
6604
+ fn trans_closure( & option:: t[ @block_ctxt] bcx_maybe,
6605
+ & option:: t[ TypeRef ] llfnty,
6606
+ @local_ctxt cx,
6607
+ & span sp, & ast:: _fn f, ValueRef llfndecl,
6608
+ option:: t[ ty:: t] ty_self,
6609
+ & ast:: ty_param[ ] ty_params, ast:: node_id id)
6610
+ -> option:: t[ ValueRef ] {
6599
6611
set_uwtable( llfndecl) ;
6600
6612
6601
6613
// Set up arguments to the function.
@@ -6605,12 +6617,34 @@ fn trans_fn_inner(@local_ctxt cx, &span sp, &ast::_fn f, ValueRef llfndecl,
6605
6617
f. decl. inputs, ty_params) ;
6606
6618
copy_any_self_to_alloca( fcx) ;
6607
6619
alt ( { fcx. llself } ) {
6608
- case ( some( ?llself) ) { populate_fn_ctxt_from_llself( fcx, llself) ; }
6609
- case ( _ ) { }
6620
+ some( ?llself) { populate_fn_ctxt_from_llself( fcx, llself) ; }
6621
+ _ { }
6610
6622
}
6611
6623
auto arg_tys = arg_tys_of_fn( fcx. lcx. ccx, id) ;
6612
6624
copy_args_to_allocas( fcx, f. decl. inputs, arg_tys) ;
6613
6625
6626
+ // Figure out if we need to build a closure and act accordingly
6627
+ auto closure = none;
6628
+ alt( f. proto) {
6629
+ ast:: proto_block {
6630
+ auto bcx = option:: get( bcx_maybe) ;
6631
+ auto upvars = get_freevars( cx. ccx. tcx, id) ;
6632
+
6633
+ auto llenv = build_environment( bcx, upvars) ;
6634
+
6635
+ // Generate code to load the environment out of the
6636
+ // environment pointer.
6637
+ load_environment( bcx, fcx, llenv. ptrty, upvars) ;
6638
+ // Build the closure.
6639
+ closure = some( create_real_fn_pair( bcx, option:: get( llfnty) ,
6640
+ llfndecl, llenv. ptr) ) ;
6641
+ }
6642
+ ast:: proto_closure {
6643
+ fail "copy capture not implemented yet";
6644
+ }
6645
+ _ { }
6646
+ }
6647
+
6614
6648
// Create the first basic block in the function and keep a handle on it to
6615
6649
// pass to finish_fn later.
6616
6650
auto bcx = new_top_block_ctxt( fcx) ;
@@ -6643,6 +6677,14 @@ fn trans_fn_inner(@local_ctxt cx, &span sp, &ast::_fn f, ValueRef llfndecl,
6643
6677
6644
6678
// Insert the mandatory first few basic blocks before lltop.
6645
6679
finish_fn( fcx, lltop) ;
6680
+
6681
+ ret closure;
6682
+ }
6683
+
6684
+ fn trans_fn_inner( @local_ctxt cx, & span sp, & ast:: _fn f, ValueRef llfndecl,
6685
+ option:: t[ ty:: t] ty_self, & ast:: ty_param[ ] ty_params,
6686
+ ast:: node_id id) {
6687
+ trans_closure( none, none, cx, sp, f, llfndecl, ty_self, ty_params, id) ;
6646
6688
}
6647
6689
6648
6690
0 commit comments