about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-09-06 14:03:20 -0700
committerBrian Anderson <banderson@mozilla.com>2011-09-07 10:32:58 -0700
commit25ae3d655cef63041d405a45f4797d21f8904502 (patch)
tree6a6dc9c15050df636670e36709a1a3ed7f2a8759 /src/rt/rust_task.cpp
parent1bd627039ed6979c59d25aee67548091522c6ff9 (diff)
downloadrust-25ae3d655cef63041d405a45f4797d21f8904502.tar.gz
rust-25ae3d655cef63041d405a45f4797d21f8904502.zip
Rewrite spawn yet again
The motivation here is that the bottom of each stack needs to contain a C++
try/catch block so that we can unwind. This is already the case for main, but
not spawned tasks.

Issue #236
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 993a6b25cfb..ab29b106783 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -125,13 +125,13 @@ struct spawn_args {
                        uintptr_t, uintptr_t);
 };
 
-struct rust_closure {
+struct rust_closure_env {
     intptr_t ref_count;
     type_desc *td;
 };
 
 extern "C" CDECL
-void task_exit(rust_closure *env, int rval, rust_task *task) {
+void task_exit(rust_closure_env *env, int rval, rust_task *task) {
     LOG(task, task, "task exited with value %d", rval);
     if(env) {
         // free the environment.
@@ -155,14 +155,32 @@ void task_start_wrapper(spawn_args *a)
     int rval = 42;
 
     a->f(&rval, task, a->a3, a->a4);
-    task_exit(NULL, rval, task);
+    task_exit((rust_closure_env*)a->a3, rval, task);
+}
+
+/* We spawn a rust (fastcc) function through a CDECL function
+   defined in main.ll, which is built as part of each crate. These accessors
+   allow each rust program to install that function at startup */
+
+uintptr_t spawn_wrapper;
+
+extern "C" CDECL void
+set_spawn_wrapper(uintptr_t f) {
+    spawn_wrapper = f;
+}
+
+extern "C" CDECL uintptr_t
+get_spawn_wrapper() {
+    return spawn_wrapper;
 }
 
 void
 rust_task::start(uintptr_t spawnee_fn,
-                 uintptr_t args)
+                 uintptr_t args,
+                 uintptr_t env)
 {
-    LOGPTR(sched, "from spawnee", spawnee_fn);
+    LOG(this, task, "starting task from fn 0x%" PRIxPTR
+        " with args 0x%" PRIxPTR, spawnee_fn, args);
 
     I(sched, stk->data != NULL);
 
@@ -173,16 +191,23 @@ rust_task::start(uintptr_t spawnee_fn,
     spawn_args *a = (spawn_args *)sp;
 
     a->task = this;
-    a->a3 = 0;
+    a->a3 = env;
     a->a4 = args;
     void **f = (void **)&a->f;
     *f = (void *)spawnee_fn;
 
-    user.ctx.call((void *)task_start_wrapper, a, sp);
+    ctx.call((void *)task_start_wrapper, a, sp);
 
     this->start();
 }
 
+void
+rust_task::start(uintptr_t spawnee_fn,
+                 uintptr_t args)
+{
+    start(spawnee_fn, args, 0);
+}
+
 void rust_task::start()
 {
     yield_timer.reset_us(0);
@@ -213,7 +238,7 @@ rust_task::yield(size_t time_in_us) {
     yield_timer.reset_us(time_in_us);
 
     // Return to the scheduler.
-    user.ctx.next->swap(user.ctx);
+    ctx.next->swap(ctx);
 }
 
 void