about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2011-06-29 18:44:38 -0700
committerMichael Sullivan <sully@msully.net>2011-07-14 18:45:01 -0500
commit759317ca8bf3d2997b5a0973679d9c7bae063e15 (patch)
treed0ce70066269d4c7699784bdac68e9dbe17e72e6 /src/comp
parent0957525cc67abd582cecf82486c9955268b3a9ec (diff)
downloadrust-759317ca8bf3d2997b5a0973679d9c7bae063e15.tar.gz
rust-759317ca8bf3d2997b5a0973679d9c7bae063e15.zip
Factor out closure construction from trans_for_each.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index bc1d756c8f9..958b9e4cb59 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -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.