aboutsummaryrefslogtreecommitdiff
path: root/src/rt
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-02-22 16:37:01 -0800
committerGraydon Hoare <[email protected]>2011-02-22 16:37:27 -0800
commitaf4d6ae76b05d4edb9d7074b971600a447c9c9a4 (patch)
tree20b65962db38b2c2cddd0eea9ba7563584fec0d0 /src/rt
parentRework typechecking of bind expressions (diff)
downloadrust-af4d6ae76b05d4edb9d7074b971600a447c9c9a4.tar.xz
rust-af4d6ae76b05d4edb9d7074b971600a447c9c9a4.zip
Add ABI tagging to crates, adjust rustc output and runtime stack-frame setup so access to argv works.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust.cpp8
-rw-r--r--src/rt/rust_internal.h6
-rw-r--r--src/rt/rust_task.cpp52
-rw-r--r--src/rt/rust_task.h1
-rw-r--r--src/rt/rust_upcall.cpp11
-rw-r--r--src/rt/test/rust_test_runtime.cpp1
6 files changed, 55 insertions, 24 deletions
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp
index 0ea167a4..46fcb22e 100644
--- a/src/rt/rust.cpp
+++ b/src/rt/rust.cpp
@@ -78,7 +78,7 @@ command_line_args : public dom_owned<command_line_args>
extern "C" CDECL int
rust_start(uintptr_t main_fn, rust_crate const *crate, int argc,
- char **argv) {
+ char **argv) {
rust_srv *srv = new rust_srv();
rust_kernel *kernel = new rust_kernel(srv);
@@ -87,7 +87,8 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc,
rust_dom *dom = handle->referent();
command_line_args *args = new (dom) command_line_args(dom, argc, argv);
- dom->log(rust_log::DOM, "startup: %d args", args->argc);
+ dom->log(rust_log::DOM, "startup: %d args in 0x%" PRIxPTR,
+ args->argc, (uintptr_t)args->args);
for (int i = 0; i < args->argc; i++) {
dom->log(rust_log::DOM,
"startup: arg[%d] = '%s'", i, args->argv[i]);
@@ -99,7 +100,8 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc,
uintptr_t main_args[4] = {0, 0, 0, (uintptr_t)args->args};
dom->root_task->start(crate->get_exit_task_glue(),
- main_fn, (uintptr_t)&main_args, sizeof(main_args));
+ crate->abi_tag, main_fn,
+ (uintptr_t)&main_args, sizeof(main_args));
int ret = dom->start_main_loop();
delete args;
kernel->destroy_domain(dom);
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index 61716703..42b61801 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -88,6 +88,10 @@ static size_t const TIME_SLICE_IN_MS = 10;
static intptr_t const CONST_REFCOUNT = 0x7badface;
+// ABI tags for rust_start, rust_task::start and friends.
+static uintptr_t const ABI_X86_RUSTBOOT_CDECL = 1;
+static uintptr_t const ABI_X86_RUSTC_FASTCALL = 2;
+
// This accounts for logging buffers.
static size_t const BUF_BYTES = 2048;
@@ -241,6 +245,8 @@ public:
size_t n_c_syms;
size_t n_libs;
+ uintptr_t abi_tag;
+
// Crates are immutable, constructed by the compiler.
uintptr_t get_image_base() const;
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 3564b9e3..1afbfdd6 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -123,6 +123,7 @@ rust_task::~rust_task()
void
rust_task::start(uintptr_t exit_task_glue,
+ uintptr_t spawnee_abi,
uintptr_t spawnee_fn,
uintptr_t args,
size_t callsz)
@@ -147,26 +148,29 @@ rust_task::start(uintptr_t exit_task_glue,
// The exit_task_glue frame we synthesize above the frame we activate:
*spp-- = (uintptr_t) 0; // closure-or-obj
*spp-- = (uintptr_t) this; // task
- *spp-- = (uintptr_t) 0; // output
- *spp-- = (uintptr_t) 0; // retpc
+ *spp-- = (uintptr_t) 0x0; // output
+ *spp-- = (uintptr_t) 0x0; // retpc
uintptr_t exit_task_frame_base;
- for (size_t j = 0; j < n_callee_saves; ++j) {
+ if (spawnee_abi == ABI_X86_RUSTBOOT_CDECL) {
+ for (size_t j = 0; j < n_callee_saves; ++j) {
- // We want 'frame_base' to point to the old fp in this (exit-task)
- // frame, because we're going to inject this frame-pointer into the
- // callee-save frame pointer value in the *next* (spawnee) frame. A
- // cheap trick, but this means the spawnee frame will restore the
- // proper frame pointer of the glue frame as it runs its epilogue.
- if (j == callee_save_fp)
- exit_task_frame_base = (uintptr_t)spp;
+ // We want 'frame_base' to point to the old fp in this (exit-task)
+ // frame, because we're going to inject this frame-pointer into
+ // the callee-save frame pointer value in the *next* (spawnee)
+ // frame. A cheap trick, but this means the spawnee frame will
+ // restore the proper frame pointer of the glue frame as it runs
+ // its epilogue.
+ if (j == callee_save_fp)
+ exit_task_frame_base = (uintptr_t)spp;
- *spp-- = 0;
- }
+ *spp-- = 0;
+ }
- *spp-- = (uintptr_t) dom->root_crate; // crate ptr
- *spp-- = (uintptr_t) 0; // frame_glue_fns
+ *spp-- = (uintptr_t) dom->root_crate; // crate ptr
+ *spp-- = (uintptr_t) 0; // frame_glue_fns
+ }
// Copy args from spawner to spawnee.
if (args) {
@@ -174,12 +178,16 @@ rust_task::start(uintptr_t exit_task_glue,
src += 1; // spawn-call output slot
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);
- // Move sp down to point to task cell.
+ // Move sp down to point to last implicit-arg cell (env).
spp--;
} else {
// We're at root, starting up.
@@ -188,10 +196,18 @@ rust_task::start(uintptr_t exit_task_glue,
// The *implicit* incoming args to the spawnee frame we're
// activating:
+ *spp-- = (uintptr_t) 0x0; // closure-or-obj
+
+ if (spawnee_abi == ABI_X86_RUSTBOOT_CDECL) {
+ // in CDECL mode we write the task + outptr to the spawnee stack.
+ *spp-- = (uintptr_t) this; // task
+ *spp-- = (uintptr_t) 0; // output addr
+ } else {
+ // 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.
+ I(dom, spawnee_abi == ABI_X86_RUSTC_FASTCALL);
+ }
- *spp-- = (uintptr_t) 0; // closure-or-obj
- *spp-- = (uintptr_t) this; // task
- *spp-- = (uintptr_t) 0; // output addr
*spp-- = (uintptr_t) exit_task_glue; // retpc
// The context the activate_glue needs to switch stack.
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 9fbc67ac..5318ab71 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -56,6 +56,7 @@ rust_task : public maybe_proxy<rust_task>,
~rust_task();
void start(uintptr_t exit_task_glue,
+ uintptr_t spawnee_abi,
uintptr_t spawnee_fn,
uintptr_t args,
size_t callsz);
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 46e53048..1dba1102 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -559,6 +559,7 @@ extern "C" CDECL rust_task *
upcall_start_task(rust_task *spawner,
rust_task *task,
uintptr_t exit_task_glue,
+ uintptr_t spawnee_abi,
uintptr_t spawnee_fn,
size_t callsz) {
LOG_UPCALL_ENTRY(spawner);
@@ -570,7 +571,8 @@ upcall_start_task(rust_task *spawner,
", spawnee 0x%" PRIxPTR
", callsz %" PRIdPTR ")", task->name, task, exit_task_glue,
spawnee_fn, callsz);
- task->start(exit_task_glue, spawnee_fn, spawner->rust_sp, callsz);
+ task->start(exit_task_glue, spawnee_abi, spawnee_fn,
+ spawner->rust_sp, callsz);
return task;
}
@@ -623,6 +625,7 @@ extern "C" CDECL maybe_proxy<rust_task> *
upcall_start_thread(rust_task *task,
rust_proxy<rust_task> *child_task_proxy,
uintptr_t exit_task_glue,
+ uintptr_t spawnee_abi,
uintptr_t spawnee_fn,
size_t callsz) {
LOG_UPCALL_ENTRY(task);
@@ -630,9 +633,11 @@ upcall_start_thread(rust_task *task,
rust_handle<rust_task> *child_task_handle = child_task_proxy->handle();
task->log(rust_log::UPCALL | rust_log::MEM | rust_log::TASK,
"exit_task_glue: " PTR ", spawnee_fn " PTR
- ", callsz %" PRIdPTR ")", exit_task_glue, spawnee_fn, callsz);
+ ", callsz %" PRIdPTR ")",
+ exit_task_glue, spawnee_fn, callsz);
rust_task *child_task = child_task_handle->referent();
- child_task->start(exit_task_glue, spawnee_fn, task->rust_sp, callsz);
+ child_task->start(exit_task_glue, spawnee_abi, spawnee_fn,
+ task->rust_sp, callsz);
#if defined(__WIN32__)
HANDLE thread;
thread = CreateThread(NULL, 0, rust_thread_start, child_task->dom, 0,
diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp
index 1cde532e..e0e24156 100644
--- a/src/rt/test/rust_test_runtime.cpp
+++ b/src/rt/test/rust_test_runtime.cpp
@@ -54,6 +54,7 @@ rust_task_test::worker::run() {
kernel->create_domain(crate, "test");
rust_dom *domain = handle->referent();
domain->root_task->start(crate->get_exit_task_glue(),
+ ABI_X86_RUSTBOOT_CDECL,
(uintptr_t)&task_entry, (uintptr_t)NULL, 0);
domain->start_main_loop();
kernel->destroy_domain(domain);