Skip to content

Commit 83250da

Browse files
committed
---
yaml --- r: 6696 b: refs/heads/master c: eaaa3c3 h: refs/heads/master v: v3
1 parent cbe2111 commit 83250da

File tree

3 files changed

+50
-26
lines changed

3 files changed

+50
-26
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: e51c29fab02c0315ebeef83acd4c01c135d32c46
2+
refs/heads/master: eaaa3c30bf132a3f67ac0a925853e5a2f6f6baf7

trunk/src/comp/middle/trans.rs

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,9 +2553,27 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
25532553
bound_values: [environment_value],
25542554
mode: closure_constr_mode) ->
25552555
{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+
25572576
let tcx = bcx_tcx(bcx);
2558-
// Synthesize a closure type.
25592577

25602578
// First, synthesize a tuple type containing the types of all the
25612579
// bound expressions.
@@ -2591,26 +2609,37 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
25912609
// Finally, synthesize a type for that whole vector.
25922610
let closure_ty: ty::t = ty::mk_tup(tcx, closure_tys);
25932611

2594-
let temp_cleanups = [], bcx = bcx;
2612+
let temp_cleanups = [];
2613+
25952614
// 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. {
25982624
let r = trans_malloc_boxed(bcx, closure_ty);
25992625
add_clean_free(bcx, r.box, false);
26002626
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)
26032637
}
26042638
for_block. {
2605-
// We need to dummy up a box on the stack
2639+
// Dummy up a box on the stack,
26062640
let ty = ty::mk_tup(tcx, [ty::mk_int(tcx), closure_ty]);
26072641
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)
26142643
}
26152644
};
26162645

@@ -2624,7 +2653,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
26242653
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
26252654
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
26262655
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);
26282658
}
26292659
for_block. {}
26302660
}
@@ -2675,15 +2705,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
26752705
i = 0u;
26762706
for td: ValueRef in lltydescs {
26772707
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);
26872710
i += 1u;
26882711
}
26892712

trunk/src/comp/middle/trans_uniq.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import trans::{
1515
dest
1616
};
1717

18-
export trans_uniq, make_free_glue, type_is_unique_box, autoderef, duplicate;
18+
export trans_uniq, make_free_glue, type_is_unique_box, autoderef, duplicate,
19+
alloc_uniq;
1920

2021
pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool {
2122
ty::type_is_unique_box(bcx_tcx(bcx), ty)

0 commit comments

Comments
 (0)