diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 24bef67d758..a01650dc1ac 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5842,7 +5842,8 @@ fn mk_spawn_wrapper(&@block_ctxt cx, &@ast::expr func, &ty::t args_ty) -> let str wrap_name = mangle_internal_name_by_path_and_seq(cx.fcx.lcx.ccx, cx.fcx.lcx.path, "spawn_wrapper"); - auto llfndecl = decl_fastcall_fn(llmod, wrap_name, wrapper_fn_type); + auto llfndecl = decl_cdecl_fn(llmod, wrap_name, wrapper_fn_type); + auto fcx = new_fn_ctxt(cx.fcx.lcx, cx.sp, llfndecl); auto fbcx = new_top_block_ctxt(fcx); // 3u to skip the three implicit args diff --git a/src/rt/main.ll.in b/src/rt/main.ll.in index 4fc22afdaa6..c25b324f956 100644 --- a/src/rt/main.ll.in +++ b/src/rt/main.ll.in @@ -10,13 +10,20 @@ @_rust_crate_map_toplevel = external global %0 declare fastcc void @_rust_main(i1* nocapture, %task*, %2* nocapture, %5*); -declare i32 @rust_start(i32, i32, i32, i32) +declare i32 @rust_start(i32, i32, i32, i32, i32) %tydesc = type { %tydesc**, i32, i32, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*, i8*, i8)* } %task = type { i32, i32, i32, i32, i32, i32, i32, i32 } +define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %5 *) +{ + tail call fastcc void @_rust_main(i1* %0, %task *%1, %2* nocapture %2, %5 *%3) + ret void +} + define i32 @"MAIN"(i32, i32) { - %3 = tail call i32 @rust_start(i32 ptrtoint (void (i1*, %task*, %2*, %5*)* @_rust_main to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32)) +; %3 = tail call i32 @rust_start(i32 ptrtoint (void (i1*, %task*, %2*, %5*)* @_rust_main_wrap to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32)) + %3 = tail call i32 @rust_start(i32 0, i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32), i32 ptrtoint (void (i1*, %task*, %2*, %5*)* @_rust_main_wrap to i32)) ret i32 %3 } diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index ae150acab17..a8ac7c7ef9c 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -71,13 +71,24 @@ command_line_args : public dom_owned } }; +// THIS IS AN UGLY HACK TO MAKE rust_start STILL WORK WITH STAGE0 WHILE WE +// TRANSITION TO ALL-CDECL TASK STARTUP FUNCTIONS. +void FASTCALL +(*real_main)(uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d) = NULL; + +void CDECL fake_main(uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d) +{ + real_main(a, b, c, d); +} + /** * Main entry point into the Rust runtime. Here we create a Rust service, * initialize the kernel, create the root domain and run it. */ extern "C" CDECL int -rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { +rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map, + uintptr_t main_fn_cdecl) { update_log_settings(crate_map, getenv("RUST_LOG")); rust_srv *srv = new rust_srv(); @@ -93,12 +104,9 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { DLOG(dom, dom, "startup: arg[%d] = '%s'", i, args->argv[i]); } - /* - uintptr_t main_args[4] = {0, 0, 0, (uintptr_t)args->args}; - dom->root_task->start(main_fn, - (uintptr_t)&main_args, sizeof(main_args)); - */ - dom->root_task->start(main_fn, + real_main = (typeof(real_main))main_fn; + if(main_fn) { printf("using fastcall main\n"); } + dom->root_task->start(main_fn ? (uintptr_t)fake_main : main_fn_cdecl, (uintptr_t)args->args, sizeof(args->args)); int ret = dom->start_main_loop(); diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 6caaf25db82..bae6f221a95 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -118,7 +118,7 @@ struct spawn_args { rust_task *task; uintptr_t a3; uintptr_t a4; - void (*FASTCALL f)(int *, rust_task *, + void (*CDECL f)(int *, rust_task *, uintptr_t, uintptr_t); };