@@ -2553,9 +2553,27 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
2553
2553
bound_values : [ environment_value ] ,
2554
2554
mode : closure_constr_mode ) ->
2555
2555
{ ptr : ValueRef , ptrty : ty:: t , bcx : @block_ctxt } {
2556
- let ccx = bcx_ccx ( bcx) ;
2556
+
2557
+ fn dummy_environment_box ( bcx : @block_ctxt , r : result )
2558
+ -> ( @block_ctxt , ValueRef , ValueRef ) {
2559
+ // Prevent glue from trying to free this.
2560
+ let ccx = bcx_ccx ( bcx) ;
2561
+ let ref_cnt = GEPi ( bcx, r. val , [ 0 , abi:: box_rc_field_refcnt] ) ;
2562
+ Store ( r. bcx , C_int ( ccx, 2 ) , ref_cnt) ;
2563
+ let closure = GEPi ( r. bcx , r. val , [ 0 , abi:: box_rc_field_body] ) ;
2564
+ ( r. bcx , closure, r. val )
2565
+ }
2566
+
2567
+ fn clone_tydesc ( bcx : @block_ctxt ,
2568
+ mode : closure_constr_mode ,
2569
+ td : ValueRef ) -> ValueRef {
2570
+ ret alt mode {
2571
+ for_block. | for_closure. { td }
2572
+ for_send. { Call ( bcx, bcx_ccx ( bcx) . upcalls . clone_type_desc , [ td] ) }
2573
+ } ;
2574
+ }
2575
+
2557
2576
let tcx = bcx_tcx ( bcx) ;
2558
- // Synthesize a closure type.
2559
2577
2560
2578
// First, synthesize a tuple type containing the types of all the
2561
2579
// bound expressions.
@@ -2591,26 +2609,37 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
2591
2609
// Finally, synthesize a type for that whole vector.
2592
2610
let closure_ty: ty:: t = ty:: mk_tup ( tcx, closure_tys) ;
2593
2611
2594
- let temp_cleanups = [ ] , bcx = bcx;
2612
+ let temp_cleanups = [ ] ;
2613
+
2595
2614
// Allocate a box that can hold something closure-sized.
2596
- let ( closure, box) = alt mode {
2597
- for_closure. | for_send. {
2615
+ //
2616
+ // For now, no matter what kind of closure we have, we always allocate
2617
+ // space for a ref cnt in the closure. If the closure is a block or
2618
+ // unique closure, this ref count isn't really used: we initialize it to 2
2619
+ // so that it will never drop to zero. This is a hack and could go away
2620
+ // but then we'd have to modify the code to do the right thing when
2621
+ // casting from a shared closure to a block.
2622
+ let ( bcx, closure, box) = alt mode {
2623
+ for_closure. {
2598
2624
let r = trans_malloc_boxed ( bcx, closure_ty) ;
2599
2625
add_clean_free ( bcx, r. box , false ) ;
2600
2626
temp_cleanups += [ r. box ] ;
2601
- bcx = r. bcx ;
2602
- ( r. body , r. box )
2627
+ ( r. bcx , r. body , r. box )
2628
+ }
2629
+ for_send. {
2630
+ // Dummy up a box in the exchange heap.
2631
+ let tup_ty = ty:: mk_tup ( tcx, [ ty:: mk_int ( tcx) , closure_ty] ) ;
2632
+ let box_ty = ty:: mk_uniq ( tcx, { ty: tup_ty, mut: ast:: imm} ) ;
2633
+ check trans_uniq:: type_is_unique_box ( bcx, box_ty) ;
2634
+ let r = trans_uniq:: alloc_uniq ( bcx, box_ty) ;
2635
+ add_clean_free ( bcx, r. val , true ) ;
2636
+ dummy_environment_box ( bcx, r)
2603
2637
}
2604
2638
for_block. {
2605
- // We need to dummy up a box on the stack
2639
+ // Dummy up a box on the stack,
2606
2640
let ty = ty:: mk_tup ( tcx, [ ty:: mk_int ( tcx) , closure_ty] ) ;
2607
2641
let r = alloc_ty ( bcx, ty) ;
2608
- bcx = r. bcx ;
2609
- // Prevent glue from trying to free this.
2610
- Store ( bcx,
2611
- C_int ( ccx, 2 ) ,
2612
- GEPi ( bcx, r. val , [ 0 , abi:: box_rc_field_refcnt] ) ) ;
2613
- ( GEPi ( bcx, r. val , [ 0 , abi:: box_rc_field_body] ) , r. val )
2642
+ dummy_environment_box ( bcx, r)
2614
2643
}
2615
2644
} ;
2616
2645
@@ -2624,7 +2653,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
2624
2653
lazily_emit_tydesc_glue ( bcx, abi:: tydesc_field_drop_glue, ti) ;
2625
2654
lazily_emit_tydesc_glue ( bcx, abi:: tydesc_field_free_glue, ti) ;
2626
2655
bcx = bindings_tydesc. bcx ;
2627
- Store ( bcx, bindings_tydesc. val , bound_tydesc) ;
2656
+ let td = clone_tydesc ( bcx, mode, bindings_tydesc. val ) ;
2657
+ Store ( bcx, td, bound_tydesc) ;
2628
2658
}
2629
2659
for_block. { }
2630
2660
}
@@ -2675,15 +2705,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
2675
2705
i = 0 u;
2676
2706
for td: ValueRef in lltydescs {
2677
2707
let ty_param_slot = GEPi ( bcx, ty_params_slot. val , [ 0 , i as int ] ) ;
2678
- alt mode {
2679
- for_closure. | for_block. {
2680
- Store ( bcx, td, ty_param_slot) ;
2681
- }
2682
- for_send. {
2683
- let cloned_td = Call ( bcx, ccx. upcalls . clone_type_desc , [ td] ) ;
2684
- Store ( bcx, cloned_td, ty_param_slot) ;
2685
- }
2686
- }
2708
+ let cloned_td = clone_tydesc ( bcx, mode, td) ;
2709
+ Store ( bcx, cloned_td, ty_param_slot) ;
2687
2710
i += 1 u;
2688
2711
}
2689
2712
0 commit comments