Factor out closure construction from trans_for_each.

This commit is contained in:
Michael Sullivan 2011-06-29 18:44:38 -07:00
parent 0957525cc6
commit 759317ca8b

View file

@ -4768,20 +4768,10 @@ fn trans_for_each(&@block_ctxt cx, &@ast::local local, &@ast::expr seq,
// Step 3: Call iter passing [lliterbody, llenv], plus other args.
alt (seq.node) {
case (ast::expr_call(?f, ?args)) {
auto pair = alloca(cx, T_fn_pair(*lcx.ccx, iter_body_llty));
auto code_cell =
cx.build.GEP(pair, ~[C_int(0), C_int(abi::fn_field_code)]);
cx.build.Store(lliterbody, code_cell);
auto env_cell =
cx.build.GEP(pair, ~[C_int(0), C_int(abi::fn_field_box)]);
auto llenvblobptr =
cx.build.PointerCast(llenvptr,
T_opaque_closure_ptr(*lcx.ccx));
cx.build.Store(llenvblobptr, env_cell);
// log "lliterbody: " + val_str(lcx.ccx.tn, lliterbody);
r = trans_call(cx, f, some[ValueRef](cx.build.Load(pair)), args,
seq.id);
auto pair = create_real_fn_pair(cx, iter_body_llty,
lliterbody, llenvptr);
r = trans_call(cx, f, some[ValueRef](cx.build.Load(pair)),
args, seq.id);
ret rslt(r.bcx, C_nil());
}
}
@ -8714,6 +8704,26 @@ fn create_fn_pair(&@crate_ctxt cx, str ps, TypeRef llfnty, ValueRef llfn,
ret gvar;
}
// Create a /real/ closure: this is like create_fn_pair, but creates a
// a fn value on the stack with a specified environment (which need not be
// on the stack).
fn create_real_fn_pair(&@block_ctxt cx, TypeRef llfnty,
ValueRef llfn, ValueRef llenvptr) -> ValueRef {
auto lcx = cx.fcx.lcx;
auto pair = alloca(cx, T_fn_pair(*lcx.ccx, llfnty));
auto code_cell =
cx.build.GEP(pair, ~[C_int(0), C_int(abi::fn_field_code)]);
cx.build.Store(llfn, code_cell);
auto env_cell =
cx.build.GEP(pair, ~[C_int(0), C_int(abi::fn_field_box)]);
auto llenvblobptr =
cx.build.PointerCast(llenvptr,
T_opaque_closure_ptr(*lcx.ccx));
cx.build.Store(llenvblobptr, env_cell);
ret pair;
}
fn register_fn_pair(&@crate_ctxt cx, str ps, TypeRef llfnty, ValueRef llfn,
ast::node_id id) {
// FIXME: We should also hide the unexported pairs in crates.