about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorRafael Ávila de Espíndola <respindola@mozilla.com>2011-05-05 14:01:16 -0400
committerGraydon Hoare <graydon@mozilla.com>2011-05-05 15:46:10 -0700
commitd6deeffd95d8f2f5a7ddaaf90d2b0ce68dbf0f35 (patch)
treee6cafaaf77e54e5a7ee74cedeb3909ed4e562bda /src/rt/rust_task.cpp
parentd85260bcc5c4ec7cefec7f9cfaa1201d01a860a3 (diff)
downloadrust-d6deeffd95d8f2f5a7ddaaf90d2b0ce68dbf0f35.tar.gz
rust-d6deeffd95d8f2f5a7ddaaf90d2b0ce68dbf0f35.zip
Change the setup so that rust_activate_glue returns to rust_exit_task_glue
and rust_exit_task_glue calls the rust main.

This is simpler since we only need to setup one frame. It also matches
what ld.so does, so gdb is happy and stops a backtrace at rust_exit_task_glue
instead of continuing past whatever function happened to be before
rust_exit_task_glue is the object file.

This is the rt part and should be merged after the rust0 part.
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp57
1 files changed, 19 insertions, 38 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 3f4c89d8948..ab75798817c 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -254,9 +254,9 @@ rust_task::start_rustboot(uintptr_t exit_task_glue,
 
 void
 rust_task::start_rustc(uintptr_t exit_task_glue,
-                          uintptr_t spawnee_fn,
-                          uintptr_t args,
-                          size_t callsz)
+                       uintptr_t spawnee_fn,
+                       uintptr_t args,
+                       size_t callsz)
 {
     LOGPTR(dom, "exit-task glue", exit_task_glue);
     LOGPTR(dom, "from spawnee", spawnee_fn);
@@ -271,27 +271,18 @@ rust_task::start_rustc(uintptr_t exit_task_glue,
     // see: "Mac OS X ABI Function Call Guide"
 
 
-    // Begin synthesizing frames. There are two: a "fully formed"
-    // exit-task frame at the top of the stack -- that pretends to be
-    // mid-execution -- and a just-starting frame beneath it that
-    // starts executing the first instruction of the spawnee. The
-    // spawnee *thinks* it was called by the exit-task frame above
-    // it. It wasn't; we put that fake frame in place here, but the
-    // illusion is enough for the spawnee to return to the exit-task
-    // frame when it's done, and exit.
+    // Begin synthesizing the exit_task_glue frame. We will return to
+    // exit_task_glue and it is responsible for calling the user code
+    // and passing the value returned by the user to the system
+    // exit routine.
     uintptr_t *spp = (uintptr_t *)rust_sp;
 
+    uintptr_t dummy_ret = (uintptr_t) spp--;
 
-    // The exit_task_glue frame we synthesize above the frame we activate:
-    make_aligned_room_for_bytes(spp, 2 * sizeof(uintptr_t));
-    *spp-- = (uintptr_t) 0;          // closure-or-obj
-    *spp-- = (uintptr_t) this;       // task
-    I(dom, spp == align_down(spp));
-    *spp-- = (uintptr_t) 0x0;        // output
-    *spp-- = (uintptr_t) 0x0;        // retpc
+    uintptr_t args_size = callsz - 3*sizeof(uintptr_t);
+    uintptr_t frame_size = args_size + 4*sizeof(uintptr_t);
 
-    I(dom, args);
-    make_aligned_room_for_bytes(spp, callsz - 3 * sizeof(uintptr_t));
+    make_aligned_room_for_bytes(spp, frame_size);
 
     // Copy args from spawner to spawnee.
     uintptr_t *src = (uintptr_t *)args;
@@ -299,29 +290,19 @@ rust_task::start_rustc(uintptr_t exit_task_glue,
     src += 1;                  // spawn-call task slot
     src += 1;                  // spawn-call closure-or-obj slot
 
-    // Undo previous sp-- so we're pointing at the last word pushed.
-    ++spp;
-
-    // Memcpy all but the task, output and env pointers
-    callsz -= (3 * sizeof(uintptr_t));
-    spp = (uintptr_t*) (((uintptr_t)spp) - callsz);
-    memcpy(spp, src, callsz);
+    *spp-- = (uintptr_t) *src;       // vec
+    *spp-- = (uintptr_t) 0x0;        // closure-or-obj
+    *spp-- = (uintptr_t) this;       // task
+    *spp-- = (uintptr_t) dummy_ret;  // output address
 
-    // Move sp down to point to last implicit-arg cell (env).
-    spp--;
+    *spp-- = (uintptr_t) (uintptr_t) spawnee_fn;
 
-    // The *implicit* incoming args to the spawnee frame we're
-    // activating:
-    *spp-- = (uintptr_t) 0x0;               // closure-or-obj
+    I(dom, spp == align_down(spp));
 
-    // in FASTCALL mode we don't, the outptr will be in ecx and the task
-    // in edx, and the activate_glue will make sure to set that up.
+    *spp-- = (uintptr_t) 0x0;        // retp
 
-    I(dom, spp+1 == align_down(spp+1));
-    *spp-- = (uintptr_t) exit_task_glue;  // retpc
+    *spp-- = (uintptr_t) exit_task_glue;
 
-    // The context the activate_glue needs to switch stack.
-    *spp-- = (uintptr_t) spawnee_fn;      // instruction to start at
     for (size_t j = 0; j < n_callee_saves; ++j) {
         *spp-- = (uintptr_t)NULL;
     }