From 46ec94cac70657a15f9c247615e9540b8897ff9a Mon Sep 17 00:00:00 2001
From: Graham Fawcett <fawcett@uwindsor.ca>
Date: Fri, 3 Dec 2010 10:12:16 -0500
Subject: [PATCH] move yield and join from keywords into stdlib

---
 src/boot/fe/ast.ml                          |  8 --------
 src/boot/fe/item.ml                         | 13 -------------
 src/boot/fe/lexer.mll                       |  2 --
 src/boot/fe/token.ml                        |  4 ----
 src/boot/me/trans.ml                        |  9 ---------
 src/boot/me/type.ml                         |  8 ++------
 src/boot/me/typestate.ml                    |  4 ----
 src/boot/me/walk.ml                         |  5 +----
 src/comp/front/lexer.rs                     |  2 --
 src/comp/front/token.rs                     |  4 ----
 src/lib/_task.rs                            | 10 ++++++++++
 src/rt/rust_builtin.cpp                     | 15 +++++++++++++++
 src/test/run-pass/clone-with-exterior.rs    |  5 ++++-
 src/test/run-pass/obj-dtor.rs               |  5 ++++-
 src/test/run-pass/spawn-fn.rs               |  4 +++-
 src/test/run-pass/spawn-module-qualified.rs |  5 ++++-
 src/test/run-pass/task-comm-1.rs            |  5 ++++-
 src/test/run-pass/task-comm-10.rs           |  5 ++++-
 src/test/run-pass/task-comm-12.rs           |  2 +-
 src/test/run-pass/task-comm-13-thread.rs    |  2 +-
 src/test/run-pass/task-comm-13.rs           |  2 +-
 src/test/run-pass/task-comm-2.rs            |  5 ++++-
 src/test/run-pass/task-comm-3.rs            |  5 ++++-
 src/test/run-pass/task-comm-7.rs            | 11 +++++++----
 src/test/run-pass/task-comm-8.rs            | 11 +++++++----
 src/test/run-pass/task-comm-9.rs            |  5 ++++-
 src/test/run-pass/task-comm.rs              |  6 ++++--
 src/test/run-pass/yield.rs                  | 13 ++++++++-----
 src/test/run-pass/yield2.rs                 |  4 +++-
 29 files changed, 95 insertions(+), 84 deletions(-)

diff --git a/src/boot/fe/ast.ml b/src/boot/fe/ast.ml
index ce9f9cc4139b1..a9cfd9c9796da 100644
--- a/src/boot/fe/ast.ml
+++ b/src/boot/fe/ast.ml
@@ -225,8 +225,6 @@ and stmt' =
 
   (* structural and misc stmts. *)
   | STMT_fail
-  | STMT_yield
-  | STMT_join of lval
   | STMT_send of (lval * lval)
   | STMT_log of atom
   | STMT_note of atom
@@ -1471,7 +1469,6 @@ and fmt_stmt_body (ff:Format.formatter) (s:stmt) : unit =
           fmt ff ";"
 
       | STMT_fail -> fmt ff "fail;"
-      | STMT_yield -> fmt ff "yield;"
 
       | STMT_send (chan, v) ->
           fmt_lval ff chan;
@@ -1485,11 +1482,6 @@ and fmt_stmt_body (ff:Format.formatter) (s:stmt) : unit =
           fmt_lval ff port;
           fmt ff ";";
 
-      | STMT_join t ->
-          fmt ff "join ";
-          fmt_lval ff t;
-          fmt ff ";"
-
       | STMT_new_box (lv, mutability, at) ->
           fmt_lval ff lv;
           fmt ff " = @@";
diff --git a/src/boot/fe/item.ml b/src/boot/fe/item.ml
index fc14443960f01..23f02b948279d 100644
--- a/src/boot/fe/item.ml
+++ b/src/boot/fe/item.ml
@@ -585,25 +585,12 @@ and parse_stmts_including_none (ps:pstate) : Ast.stmt array =
           in
             Array.concat [[| span ps apos bpos (Ast.STMT_decl decl) |]; stmts]
 
-      | YIELD ->
-          bump ps;
-          expect ps SEMI;
-          let bpos = lexpos ps in
-            [| span ps apos bpos Ast.STMT_yield |]
-
       | FAIL ->
           bump ps;
           expect ps SEMI;
           let bpos = lexpos ps in
             [| span ps apos bpos Ast.STMT_fail |]
 
-      | JOIN ->
-          bump ps;
-          let (stmts, lval) = ctxt "stmts: task expr" parse_lval ps in
-            expect ps SEMI;
-            spans ps stmts apos (Ast.STMT_join lval)
-
-
        | STATE | GC
        | IMPURE | UNSAFE
        | ABS | NATIVE
diff --git a/src/boot/fe/lexer.mll b/src/boot/fe/lexer.mll
index 84aeb9ab11487..bb5d98273771e 100644
--- a/src/boot/fe/lexer.mll
+++ b/src/boot/fe/lexer.mll
@@ -121,8 +121,6 @@
                 ("cont", CONT);
                 ("spawn", SPAWN);
                 ("thread", THREAD);
-                ("yield", YIELD);
-                ("join", JOIN);
 
                 ("bool", BOOL);
 
diff --git a/src/boot/fe/token.ml b/src/boot/fe/token.ml
index 6c2282de2109a..dc73312384009 100644
--- a/src/boot/fe/token.ml
+++ b/src/boot/fe/token.ml
@@ -109,8 +109,6 @@ type token =
   | SPAWN
   | BIND
   | THREAD
-  | YIELD
-  | JOIN
 
   (* Literals *)
   | LIT_INT       of int64
@@ -272,8 +270,6 @@ let rec string_of_tok t =
     | SPAWN      -> "spawn"
     | BIND       -> "bind"
     | THREAD     -> "thread"
-    | YIELD      -> "yield"
-    | JOIN       -> "join"
 
     (* Literals *)
     | LIT_INT i  -> Int64.to_string i
diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml
index 34f4d81db04b8..ac05bda8056b5 100644
--- a/src/boot/me/trans.ml
+++ b/src/boot/me/trans.ml
@@ -2796,9 +2796,6 @@ let trans_visitor
           imm (Int64.of_int line)
         |];
 
-  and trans_join (task:Ast.lval) : unit =
-    trans_void_upcall "upcall_join" [| trans_atom (Ast.ATOM_lval task) |]
-
   and trans_send (chan:Ast.lval) (src:Ast.lval) : unit =
     let (src_cell, src_ty) = trans_lval src in
       begin
@@ -5309,15 +5306,9 @@ let trans_visitor
       | Ast.STMT_check_expr e ->
           trans_check_expr stmt.id e
 
-      | Ast.STMT_yield ->
-          trans_yield ()
-
       | Ast.STMT_fail ->
           trans_fail ()
 
-      | Ast.STMT_join task ->
-          trans_join task
-
       | Ast.STMT_send (chan,src) ->
           trans_send chan src
 
diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml
index 87e8e4c15822f..120da411e6465 100644
--- a/src/boot/me/type.ml
+++ b/src/boot/me/type.ml
@@ -900,8 +900,7 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) =
     let check_ret (stmt:Ast.stmt) : unit =
       fn_ctx.fnctx_just_saw_ret <-
         match stmt.Common.node with
-            Ast.STMT_ret _ | Ast.STMT_be _ | Ast.STMT_fail
-          | Ast.STMT_yield -> true
+            Ast.STMT_ret _ | Ast.STMT_be _ | Ast.STMT_fail -> true
           | _ -> false
     in
 
@@ -1118,10 +1117,7 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) =
         | Ast.STMT_alt_port _ -> () (* TODO *)
 
         (* always well-typed *)
-        | Ast.STMT_fail | Ast.STMT_yield 
-        | Ast.STMT_break | Ast.STMT_cont -> ()
-
-        | Ast.STMT_join lval -> infer_lval Ast.TY_task lval
+        | Ast.STMT_fail | Ast.STMT_break | Ast.STMT_cont -> ()
 
         | Ast.STMT_send (chan, value) ->
             let value_ty = demand_chan (check_lval chan) in
diff --git a/src/boot/me/typestate.ml b/src/boot/me/typestate.ml
index ea0204f37cc35..5fd19ea016239 100644
--- a/src/boot/me/typestate.ml
+++ b/src/boot/me/typestate.ml
@@ -695,10 +695,6 @@ let condition_assigning_visitor
             let precond = slot_inits (atom_slots cx at) in
               raise_pre_post_cond s.id precond
 
-        | Ast.STMT_join lval ->
-            let precond = slot_inits (lval_slots cx lval) in
-              raise_pre_post_cond s.id precond
-
         | Ast.STMT_log atom ->
             let precond = slot_inits (atom_slots cx atom) in
               raise_pre_post_cond s.id precond
diff --git a/src/boot/me/walk.ml b/src/boot/me/walk.ml
index d3fdc9b483b8a..f7553efda7d91 100644
--- a/src/boot/me/walk.ml
+++ b/src/boot/me/walk.ml
@@ -481,12 +481,9 @@ and walk_stmt
       | Ast.STMT_decl (Ast.DECL_slot (_, slot)) ->
           walk_slot_identified v slot
 
-      | Ast.STMT_break | Ast.STMT_cont | Ast.STMT_yield | Ast.STMT_fail ->
+      | Ast.STMT_break | Ast.STMT_cont | Ast.STMT_fail ->
           ()
 
-      | Ast.STMT_join task ->
-          walk_lval v task
-
       | Ast.STMT_send (dst,src) ->
           walk_lval v dst;
           walk_lval v src
diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs
index 0506ce6c3607d..8491b6b11f061 100644
--- a/src/comp/front/lexer.rs
+++ b/src/comp/front/lexer.rs
@@ -141,8 +141,6 @@ fn new_reader(stdio_reader rdr, str filename) -> reader
     keywords.insert("log", token.LOG);
     keywords.insert("spawn", token.SPAWN);
     keywords.insert("thread", token.THREAD);
-    keywords.insert("yield", token.YIELD);
-    keywords.insert("join", token.JOIN);
 
     keywords.insert("bool", token.BOOL);
 
diff --git a/src/comp/front/token.rs b/src/comp/front/token.rs
index 84869aacabc8a..d81c6020d48d1 100644
--- a/src/comp/front/token.rs
+++ b/src/comp/front/token.rs
@@ -118,8 +118,6 @@ tag token {
     SPAWN;
     BIND;
     THREAD;
-    YIELD;
-    JOIN;
 
     /* Literals */
     LIT_INT(int);
@@ -284,8 +282,6 @@ fn to_str(token t) -> str {
         case (SPAWN) { ret "spawn"; }
         case (BIND) { ret "bind"; }
         case (THREAD) { ret "thread"; }
-        case (YIELD) { ret "yield"; }
-        case (JOIN) { ret "join"; }
 
         /* Literals */
         case (LIT_INT(?i)) { ret _int.to_str(i, 10u); }
diff --git a/src/lib/_task.rs b/src/lib/_task.rs
index 8eece16b50827..03c2003e7a028 100644
--- a/src/lib/_task.rs
+++ b/src/lib/_task.rs
@@ -1,5 +1,7 @@
 native "rust" mod rustrt {
     fn task_sleep(uint time_in_us);
+    fn task_yield();
+    fn task_join(task t);
 }
 
 /**
@@ -11,6 +13,14 @@ fn sleep(uint time_in_us) {
     ret rustrt.task_sleep(time_in_us);
 }
 
+fn join(task t) {
+    ret rustrt.task_join(t);
+}
+
+fn yield() {
+    ret rustrt.task_yield();
+}
+
 // Local Variables:
 // mode: rust;
 // fill-column: 78;
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index cb16fbf067daf..71d1e72d5dbe4 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -239,6 +239,21 @@ task_sleep(rust_task *task, size_t time_in_us) {
     upcall_sleep(task, time_in_us);
 }
 
+extern "C" CDECL void upcall_yield(rust_task *task);
+
+extern "C" CDECL void
+task_yield(rust_task *task) {
+    upcall_yield(task);
+}
+
+extern "C" CDECL void 
+upcall_join(rust_task *task, maybe_proxy<rust_task> *target);
+
+extern "C" CDECL void
+task_join(rust_task *task, maybe_proxy<rust_task> *target) {
+    upcall_join(task, target);
+}
+
 /* Debug builtins for std.dbg. */
 
 static void
diff --git a/src/test/run-pass/clone-with-exterior.rs b/src/test/run-pass/clone-with-exterior.rs
index 7de90425a35b3..d4e308927446d 100644
--- a/src/test/run-pass/clone-with-exterior.rs
+++ b/src/test/run-pass/clone-with-exterior.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.join;
+
 fn f(@rec(int a, int b) x) {
   check (x.a == 10);
   check (x.b == 12);
@@ -6,5 +9,5 @@ fn f(@rec(int a, int b) x) {
 fn main() {
   let @rec(int a, int b) z = rec(a=10, b=12);
   let task p = spawn thread f(z);
-  join p;
+  join(p);
 }
\ No newline at end of file
diff --git a/src/test/run-pass/obj-dtor.rs b/src/test/run-pass/obj-dtor.rs
index d1f54f8fa6cf3..5126d5f533cb6 100644
--- a/src/test/run-pass/obj-dtor.rs
+++ b/src/test/run-pass/obj-dtor.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.yield;
+
 obj worker(chan[int] c) {
   drop {
     log "in dtor";
@@ -16,7 +19,7 @@ impure fn do_work(chan[int] c) {
     // Deadlock-condition not handled properly yet, need to avoid
     // exiting the child early.
     c <| 11;
-    yield;
+    yield();
   }
 }
 
diff --git a/src/test/run-pass/spawn-fn.rs b/src/test/run-pass/spawn-fn.rs
index 894a8321528ef..2be2fbf2c28d7 100644
--- a/src/test/run-pass/spawn-fn.rs
+++ b/src/test/run-pass/spawn-fn.rs
@@ -1,4 +1,6 @@
 // -*- rust -*-
+use std;
+import std._task.yield;
 
 fn x(str s, int n) {
   log s;
@@ -13,6 +15,6 @@ fn main() {
   while (i > 0) {
     i = i - 1;
     log "parent sleeping";
-    yield;
+    yield();
   }
 }
diff --git a/src/test/run-pass/spawn-module-qualified.rs b/src/test/run-pass/spawn-module-qualified.rs
index 68f665df7d8d0..c43c89188f35e 100644
--- a/src/test/run-pass/spawn-module-qualified.rs
+++ b/src/test/run-pass/spawn-module-qualified.rs
@@ -1,6 +1,9 @@
+use std;
+import std._task.join;
+
 fn main() {
   auto x = spawn m.child(10);
-  join x;
+  join(x);
 }
 mod m {
   fn child(int i) {
diff --git a/src/test/run-pass/task-comm-1.rs b/src/test/run-pass/task-comm-1.rs
index 48983b71e1af2..8f631c3beae70 100644
--- a/src/test/run-pass/task-comm-1.rs
+++ b/src/test/run-pass/task-comm-1.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task;
+
 fn main() -> () {
    test00(); 
 }
@@ -8,6 +11,6 @@ fn start() {
 
 fn test00() {
     let task t = spawn thread start();
-    join t;
+    _task.join(t);
     log "Completing.";
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-10.rs b/src/test/run-pass/task-comm-10.rs
index 4cdcf18b9ce2f..b1628727aa9d8 100644
--- a/src/test/run-pass/task-comm-10.rs
+++ b/src/test/run-pass/task-comm-10.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.yield;
+
 io fn start(chan[chan[str]] c) {
     let port[str] p = port();
     c <| chan(p);
@@ -11,5 +14,5 @@ io fn main() {
     auto c <- p;
     c <| "A";
     c <| "B";
-    yield;
+    yield();
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs
index ceb6ba017293b..1f5ef9c00b13c 100644
--- a/src/test/run-pass/task-comm-12.rs
+++ b/src/test/run-pass/task-comm-12.rs
@@ -17,7 +17,7 @@ fn test00() {
     _task.sleep(10000u);
     
     // Try joining tasks that have already finished.
-    join t;
+    _task.join(t);
     
     log "Joined Task.";
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-13-thread.rs b/src/test/run-pass/task-comm-13-thread.rs
index e7cfc24720d9a..55a49506f88b9 100644
--- a/src/test/run-pass/task-comm-13-thread.rs
+++ b/src/test/run-pass/task-comm-13-thread.rs
@@ -13,6 +13,6 @@ fn main() -> () {
     log "Check that we don't deadlock.";
     let port[int] p = port();
     let task a = spawn thread "start" start(chan(p), 0, 10);
-    join a;
+    _task.join(a);
     log "Joined Task";
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-13.rs b/src/test/run-pass/task-comm-13.rs
index 6b29ec1ee2a85..542b8fb6d6228 100644
--- a/src/test/run-pass/task-comm-13.rs
+++ b/src/test/run-pass/task-comm-13.rs
@@ -13,6 +13,6 @@ fn main() -> () {
     log "Check that we don't deadlock.";
     let port[int] p = port();
     let task a = spawn "start" start(chan(p), 0, 10);
-    join a;
+    _task.join(a);
     log "Joined Task";
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-2.rs b/src/test/run-pass/task-comm-2.rs
index 864d49de1e09b..16084ce12d882 100644
--- a/src/test/run-pass/task-comm-2.rs
+++ b/src/test/run-pass/task-comm-2.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.join;
+
 fn main() -> () {    
     log "===== SPAWNING and JOINING TASKS =====";
     test00(false);
@@ -29,7 +32,7 @@ fn test00(bool create_threads) {
     }
     
     for (task t in tasks) {
-        join t;
+        join(t);
     }
     
     log "Joined all task.";
diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs
index 9a3f9e16919ef..14753ddd54211 100644
--- a/src/test/run-pass/task-comm-3.rs
+++ b/src/test/run-pass/task-comm-3.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.join;
+
 io fn main() -> () {
    log "===== WITHOUT THREADS =====";
    test00(false);
@@ -52,7 +55,7 @@ io fn test00(bool is_multithreaded) {
 
     // Join spawned tasks...
     for (task t in tasks) {
-        join t;
+        join(t);
     }
     
     log "Completed: Final number is: ";
diff --git a/src/test/run-pass/task-comm-7.rs b/src/test/run-pass/task-comm-7.rs
index 099f8d6b6d4e0..9ad6ef2ecff1a 100644
--- a/src/test/run-pass/task-comm-7.rs
+++ b/src/test/run-pass/task-comm-7.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.join;
+
 impure fn main() -> () {
    test00();
 }
@@ -34,10 +37,10 @@ impure fn test00() {
         i += 1;
     }
             
-    join t0;
-    join t1;
-    join t2;
-    join t3;
+    join(t0);
+    join(t1);
+    join(t2);
+    join(t3);
     
     check (sum == (((number_of_messages * 4) * 
                    ((number_of_messages * 4) - 1)) / 2));
diff --git a/src/test/run-pass/task-comm-8.rs b/src/test/run-pass/task-comm-8.rs
index c5f73a3f08e41..2794e773984ac 100644
--- a/src/test/run-pass/task-comm-8.rs
+++ b/src/test/run-pass/task-comm-8.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.join;
+
 io fn main() -> () {
    test00();
 }
@@ -34,10 +37,10 @@ io fn test00() {
         i += 1;
     }
             
-    join t0;
-    join t1;
-    join t2;
-    join t3;
+    join(t0);
+    join(t1);
+    join(t2);
+    join(t3);
     
     check (sum == (((number_of_messages * 4) * 
                    ((number_of_messages * 4) - 1)) / 2));
diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs
index a2c9d5c9b4c89..d2d08a82e9e51 100644
--- a/src/test/run-pass/task-comm-9.rs
+++ b/src/test/run-pass/task-comm-9.rs
@@ -1,3 +1,6 @@
+use std;
+import std._task.join;
+
 io fn main() -> () {
    test00();
 }
@@ -25,7 +28,7 @@ io fn test00() {
         i += 1;
     }
             
-    join t0;
+    join(t0);
     
     check (sum == (number_of_messages * (number_of_messages - 1)) / 2);
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm.rs b/src/test/run-pass/task-comm.rs
index 3c5d321689fd9..b9a99bac0f76b 100644
--- a/src/test/run-pass/task-comm.rs
+++ b/src/test/run-pass/task-comm.rs
@@ -1,3 +1,5 @@
+use std;
+import std._task.join;
 
 io fn main() -> () {
     test00(true);
@@ -52,7 +54,7 @@ io fn test00(bool is_multithreaded) {
     }
 
     for (task t in tasks) {
-        join t;
+        join(t);
     }
     
     log "Completed: Final number is: ";
@@ -152,7 +154,7 @@ fn test06() {
     }
     
     for (task t in tasks) {
-        join t;
+        join(t);
     }
 }
 
diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs
index d2ae592a80acd..857ac4770a91c 100644
--- a/src/test/run-pass/yield.rs
+++ b/src/test/run-pass/yield.rs
@@ -1,20 +1,23 @@
 // -*- rust -*-
+use std;
+import std._task.yield;
+import std._task.join;
 
 fn main() {
   auto other = spawn child();
   log "1";
-  yield;
+  yield();
   log "2";
-  yield;
+  yield();
   log "3";
-  join other;
+  join(other);
 }
 
 fn child() {
   log "4";
-  yield;
+  yield();
   log "5";
-  yield;
+  yield();
   log "6";
 }
 
diff --git a/src/test/run-pass/yield2.rs b/src/test/run-pass/yield2.rs
index 11285822a7e84..ddb01b08dd93e 100644
--- a/src/test/run-pass/yield2.rs
+++ b/src/test/run-pass/yield2.rs
@@ -1,10 +1,12 @@
 // -*- rust -*-
+use std;
+import std._task.yield;
 
 fn main() {
   let int i = 0;
   while (i < 100) {
     i = i + 1;
     log i;
-    yield;
+    yield();
   }
 }