about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-06-17 14:32:43 -0700
committerEric Holk <eholk@mozilla.com>2011-06-17 15:17:46 -0700
commit81fc51a8d7f4ccb4f0a7b2c7718a2926d9842f59 (patch)
treeec7fc68c832b78645cd2e1da1f282ee2aa3c8293 /src/comp
parent71e1db596cebc35e2218ae011da2c76ee4ed5532 (diff)
downloadrust-81fc51a8d7f4ccb4f0a7b2c7718a2926d9842f59.tar.gz
rust-81fc51a8d7f4ccb4f0a7b2c7718a2926d9842f59.zip
Started using deep_copy for spawn arguments.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs94
-rw-r--r--src/comp/middle/ty.rs7
2 files changed, 86 insertions, 15 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index f3c071fec1c..9e28e43bd73 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -2429,8 +2429,7 @@ type val_pair_and_ty_fn =
 // Iterates through the elements of a structural type.
 fn iter_structural_ty(&@block_ctxt cx, ValueRef v, &ty::t t, val_and_ty_fn f)
    -> result {
-    fn adaptor_fn(val_and_ty_fn f, &@block_ctxt cx, ValueRef av, ValueRef bv,
-                  ty::t t) -> result {
+    fn adaptor_fn(val_and_ty_fn f, &@block_ctxt cx, ValueRef av, ValueRef bv,                  ty::t t) -> result {
         ret f(cx, av, t);
     }
     ret iter_structural_ty_full(cx, v, v, t, bind adaptor_fn(f, _, _, _, _));
@@ -6079,6 +6078,11 @@ fn trans_chan(&@block_ctxt cx, &@ast::expr e, &ast::ann ann) -> result {
     auto chan_raw_val =
         bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.new_chan,
                        [bcx.fcx.lltaskptr, prt_val]);
+    ret chan_raw_to_val(bcx, e, ann, chan_raw_val);
+}
+
+fn chan_raw_to_val(&@block_ctxt bcx, &@ast::expr e,  &ast::ann ann,
+                   ValueRef chan_raw_val) -> result {
     auto chan_ty = node_ann_type(bcx.fcx.lcx.ccx, ann);
     auto chan_llty = type_of(bcx.fcx.lcx.ccx, e.span, chan_ty);
     auto chan_val = bcx.build.PointerCast(chan_raw_val, chan_llty);
@@ -6122,16 +6126,28 @@ fn trans_spawn(&@block_ctxt cx, &ast::spawn_dom dom, &option::t[str] name,
     //
     // 5. Oh yeah, we have to create the task before we start it...
 
+    // But first, we'll create a task.
+
+    let ValueRef lltname = C_str(bcx.fcx.lcx.ccx, tname);
+    auto new_task =
+        bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.new_task,
+                       [bcx.fcx.lltaskptr, lltname]);
+
     // Translate the arguments, remembering their types and where the values
     // ended up.
 
     let vec[ty::t] arg_tys = [];
     let vec[ValueRef] arg_vals = [];
     for (@ast::expr e in args) {
+        auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e);
         auto arg = trans_expr(bcx, e);
+
+        arg = deep_copy(arg.bcx, arg.val, e_ty);
+
         bcx = arg.bcx;
+
         vec::push[ValueRef](arg_vals, arg.val);
-        vec::push[ty::t](arg_tys, ty::expr_ty(cx.fcx.lcx.ccx.tcx, e));
+        vec::push[ty::t](arg_tys, e_ty);
     }
     // Make the tuple.
 
@@ -6152,24 +6168,14 @@ fn trans_spawn(&@block_ctxt cx, &ast::spawn_dom dom, &option::t[str] name,
         bcx.build.Store(v, target);
         i += 1u;
     }
-    // Now we're ready to do the upcall.
-
-    // But first, we'll create a task.
-
-    let ValueRef lltname = C_str(bcx.fcx.lcx.ccx, tname);
-    auto new_task =
-        bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.new_task,
-                       [bcx.fcx.lltaskptr, lltname]);
-    // Okay, start the task.
 
-    auto llargs_i = bcx.build.PointerCast(llargs.val, T_int());
     // Generate the wrapper function
-
     auto wrapper = mk_spawn_wrapper(bcx, func, args_ty);
     bcx = wrapper.bcx;
     auto llfnptr_i = bcx.build.PointerCast(wrapper.val, T_int());
-    // And start the task
 
+    // And start the task
+    auto llargs_i = bcx.build.PointerCast(llargs.val, T_int());
     auto args_size = size_of(bcx, args_ty).val;
     bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.start_task,
                    [bcx.fcx.lltaskptr, new_task, llfnptr_i, llargs_i,
@@ -6229,6 +6235,64 @@ fn mk_spawn_wrapper(&@block_ctxt cx, &@ast::expr func, &ty::t args_ty) ->
     ret res(cx, llfndecl);
 }
 
+// Does a deep copy of a value. This is needed for passing arguments to child
+// tasks, and for sending things through channels. There are probably some
+// uniqueness optimizations and things we can do here for tasks in the same
+// domain.
+fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t) -> result {
+    auto tcx = bcx.fcx.lcx.ccx.tcx;
+    if(ty::type_is_scalar(tcx, t)) {
+        ret res(bcx, v);
+    }
+    /*
+      else if(ty::type_is_chan(tcx, t)) {
+      // If this is a channel, we need to clone it.
+      log_err "Generating clone call for channel argument.";
+      
+      log_err #fmt("ty(clone_chan) = %s", 
+      val_str(bcx.fcx.lcx.ccx.tn,
+      bcx.fcx.lcx.ccx.upcalls.clone_chan));
+      
+      log_err #fmt("ty(lltaskptr) = %s", 
+      val_str(bcx.fcx.lcx.ccx.tn, 
+      bcx.fcx.lltaskptr));
+      
+      log_err #fmt("ty(new_task) = %s", 
+      val_str(bcx.fcx.lcx.ccx.tn, 
+      new_task));
+      
+      log_err #fmt("ty(chan) = %s", 
+      val_str(bcx.fcx.lcx.ccx.tn, 
+      arg.val));
+      
+      auto chan_ptr = bcx.build.PointerCast(arg.val, T_opaque_chan_ptr());
+      
+      auto chan_raw_val = 
+      bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.clone_chan,
+      [bcx.fcx.lltaskptr, new_task, chan_ptr]);
+      
+      arg = chan_raw_to_val(bcx, e, ann, chan_raw_val);
+      
+      log_err "Done";
+      } 
+    */
+    else if(ty::type_is_structural(tcx, t)) {
+        fn inner_deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t) -> result {
+            auto tcx = bcx.fcx.lcx.ccx.tcx;
+    
+            log_err "Unimplemented type for deep_copy.";
+            fail;
+        }
+
+        ret iter_structural_ty(bcx, v, t, inner_deep_copy);
+    }
+    else {
+        bcx.fcx.lcx.ccx.sess.bug("unexpected type in " +
+                                "trans::deep_copy: " +
+                                ty_to_str(tcx, t));
+    }
+}
+
 fn trans_send(&@block_ctxt cx, &@ast::expr lhs, &@ast::expr rhs,
               &ast::ann ann) -> result {
     auto bcx = cx;
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index a1ed4f86ddd..17af83bf7b2 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -719,6 +719,13 @@ fn type_is_bool(&ctxt cx, &t ty) -> bool {
     }
 }
 
+fn type_is_chan(&ctxt cx, &t ty) -> bool {
+    alt (struct(cx, ty)) {
+        case (ty_chan(_)) { ret true; }
+        case (_) { ret false; }
+    }
+}
+
 fn type_is_structural(&ctxt cx, &t ty) -> bool {
     alt (struct(cx, ty)) {
         case (ty_tup(_)) { ret true; }