about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-06-20 13:46:44 -0700
committerEric Holk <eholk@mozilla.com>2011-06-20 13:47:02 -0700
commita2dcd08cc273bcc880fc9687bffc98796fa1f3c4 (patch)
treef794a78f7e6723995ed983e779ee9cbbbd896ad4 /src
parentc0515017842a4b7872ff31bd91acec4a54d2ef2d (diff)
downloadrust-a2dcd08cc273bcc880fc9687bffc98796fa1f3c4.tar.gz
rust-a2dcd08cc273bcc880fc9687bffc98796fa1f3c4.zip
Added string duplication to deep_copy. Closes #520.
Diffstat (limited to 'src')
-rw-r--r--src/comp/back/upcall.rs3
-rw-r--r--src/comp/middle/trans.rs29
-rw-r--r--src/comp/middle/ty.rs8
-rw-r--r--src/rt/rust_upcall.cpp18
-rw-r--r--src/rt/rustrt.def.in1
-rw-r--r--src/test/run-pass/spawn-types.rs25
6 files changed, 59 insertions, 25 deletions
diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs
index 7cb859a8fa3..1a5a9a8d254 100644
--- a/src/comp/back/upcall.rs
+++ b/src/comp/back/upcall.rs
@@ -49,6 +49,7 @@ type upcalls =
         ValueRef free,
         ValueRef mark,
         ValueRef new_str,
+        ValueRef dup_str,
         ValueRef new_vec,
         ValueRef vec_append,
         ValueRef get_type_desc,
@@ -101,6 +102,8 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls {
              mark=d("mark", [T_ptr(T_i8())], T_int()),
              new_str=d("new_str", [T_ptr(T_i8()), T_size_t()],
                        T_ptr(T_str())),
+             dup_str=d("dup_str", [T_ptr(T_str())],
+                       T_ptr(T_str())),
              new_vec=d("new_vec", [T_size_t(), T_ptr(T_tydesc(tn))],
                        T_opaque_vec_ptr()),
              vec_append=d("vec_append",
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 483d6f7a5b0..408a9f3e7db 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -6340,28 +6340,13 @@ fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
     if(ty::type_is_scalar(tcx, t)) {
         ret res(bcx, v);
     }
+    else if(ty::type_is_str(tcx, t)) {
+        ret res(bcx,
+                bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.dup_str,
+                               [bcx.fcx.lltaskptr, 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(target_task) = %s", 
-                     val_str(bcx.fcx.lcx.ccx.tn, 
-                             target_task));
-      
-        log_err #fmt("ty(chan) = %s", 
-                     val_str(bcx.fcx.lcx.ccx.tn, 
-                             v));
-        */
-
         auto chan_ptr = bcx.build.PointerCast(v, T_opaque_chan_ptr());
       
         auto chan_raw_val = 
@@ -6386,8 +6371,8 @@ fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
     }
     else {
         bcx.fcx.lcx.ccx.sess.bug("unexpected type in " +
-                                "trans::deep_copy: " +
-                                ty_to_str(tcx, t));
+                                 "trans::deep_copy: " +
+                                 ty_to_str(tcx, t));
     }
 }
 
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index df33890ea7f..d3e6dbfed3f 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -168,6 +168,7 @@ export type_is_sequence;
 export type_is_signed;
 export type_is_structural;
 export type_is_tup_like;
+export type_is_str;
 export type_owns_heap_mem;
 export type_param;
 export unify;
@@ -899,6 +900,13 @@ fn type_is_sequence(&ctxt cx, &t ty) -> bool {
     }
 }
 
+fn type_is_str(&ctxt cx, &t ty) -> bool {
+    alt (struct(cx, ty)) {
+        case (ty_str) { ret true; }
+        case (_) { ret false; }
+    }
+}
+
 fn sequence_is_interior(&ctxt cx, &t ty) -> bool {
     alt (struct(cx, ty)) {
         case (
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 1a0d4f8c0b0..7fb6bc4c84d 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -315,9 +315,7 @@ upcall_mark(rust_task *task, void* ptr) {
     return 0;
 }
 
-extern "C" CDECL rust_str *
-upcall_new_str(rust_task *task, char const *s, size_t fill) {
-    LOG_UPCALL_ENTRY(task);
+rust_str *make_str(rust_task *task, char const *s, size_t fill) {
     rust_dom *dom = task->dom;
     size_t alloc = next_power_of_two(sizeof(rust_str) + fill);
     void *mem = task->malloc(alloc);
@@ -332,6 +330,20 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) {
     return st;
 }
 
+extern "C" CDECL rust_str *
+upcall_new_str(rust_task *task, char const *s, size_t fill) {
+    LOG_UPCALL_ENTRY(task);
+    
+    return make_str(task, s, fill);
+}
+
+extern "C" CDECL rust_str *
+upcall_dup_str(rust_task *task, rust_str *str) {
+    LOG_UPCALL_ENTRY(task);
+
+    return make_str(task, (char const *)str->data, str->fill);
+}
+
 extern "C" CDECL rust_vec *
 upcall_new_vec(rust_task *task, size_t fill, type_desc *td) {
     LOG_UPCALL_ENTRY(task);
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index b47d18e780e..17b4ba9817d 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -47,6 +47,7 @@ unsupervise
 upcall_clone_chan
 upcall_del_chan
 upcall_del_port
+upcall_dup_str
 upcall_exit
 upcall_fail
 upcall_flush_chan
diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs
new file mode 100644
index 00000000000..45052ffabcc
--- /dev/null
+++ b/src/test/run-pass/spawn-types.rs
@@ -0,0 +1,25 @@
+/*
+  Make sure we can spawn tasks that take different types of
+  parameters. This is based on a test case for #520 provided by Rob
+  Arnold.
+ */
+
+// xfail-stage0
+// xfail-stage1
+// xfail-stage2
+// xfail-stage3
+
+use std;
+
+import std::str;
+
+type ctx = chan[int];
+
+fn iotask(ctx cx, str ip) {
+  assert(str::eq(ip, "localhost"));
+}
+
+fn main() {
+  let port[int] p = port();
+  spawn iotask(chan(p), "localhost");
+}