diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index a18b495a7bb..6cfdf80a0f9 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -6385,84 +6385,20 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span, ccx.sess.span_fatal(sp, "multiple 'main' functions"); } - tag main_mode { - mm_nil; - mm_vec; - mm_ivec; - }; - - let main_mode = alt ty::struct(ccx.tcx, main_node_type) { + let main_takes_ivec = alt ty::struct(ccx.tcx, main_node_type) { ty::ty_fn(_, args, _ ,_ ,_) { - if std::vec::len(args) == 0u { - mm_nil - } else { - alt ty::struct(ccx.tcx, args.(0).ty) { - ty::ty_ivec(_) { mm_ivec } - ty::ty_vec(_) { mm_vec } - } - } + std::vec::len(args) != 0u } }; - // Have to create two different main functions depending on whether - // main was declared to take vec or ivec - let llfn_vec = create_main_wrapper_vec(ccx, sp, main_llfn, main_mode); - let llfn_ivec = create_main_wrapper_ivec(ccx, sp, main_llfn, main_mode); - let takes_ivec = main_mode == mm_ivec; - // Create a global to tell main.ll which main we want to use - create_main_type_indicator(ccx, takes_ivec); - ccx.main_fn = takes_ivec ? some(llfn_ivec) : some(llfn_vec); + let llfn = create_main(ccx, sp, main_llfn, main_takes_ivec); + create_main_type_indicator(ccx, main_takes_ivec); + ccx.main_fn = some(llfn); - fn create_main_wrapper_vec(ccx: &@crate_ctxt, - sp: &span, - main_llfn: ValueRef, - main_mode: main_mode) -> ValueRef { - - let vecarg = { - mode: ty::mo_val, - ty: ty::mk_vec(ccx.tcx, { - ty: ty::mk_str(ccx.tcx), - mut: ast::imm - }) - }; - let llfty = type_of_fn(ccx, sp, - ast::proto_fn, - ~[vecarg], - ty::mk_nil(ccx.tcx), - 0u); - let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main", llfty); - - let fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl); - let bcx = new_top_block_ctxt(fcx); - - if main_mode != mm_ivec { - let lloutputarg = llvm::LLVMGetParam(llfdecl, 0u); - let lltaskarg = llvm::LLVMGetParam(llfdecl, 1u); - let llenvarg = llvm::LLVMGetParam(llfdecl, 2u); - let llargvarg = llvm::LLVMGetParam(llfdecl, 3u); - let args = alt main_mode { - mm_nil. { ~[lloutputarg, - lltaskarg, - llenvarg] } - mm_vec. { ~[lloutputarg, - lltaskarg, - llenvarg, - llargvarg] } - }; - bcx.build.FastCall(main_llfn, args); - } - build_return(bcx); - - let lltop = bcx.llbb; - finish_fn(fcx, lltop); - - ret llfdecl; - } - - fn create_main_wrapper_ivec(ccx: &@crate_ctxt, - sp: &span, - main_llfn: ValueRef, - main_mode: main_mode) -> ValueRef { + fn create_main(ccx: &@crate_ctxt, + sp: &span, + main_llfn: ValueRef, + takes_ivec: bool) -> ValueRef { let ivecarg = { mode: ty::mo_val, ty: ty::mk_ivec(ccx.tcx, { @@ -6475,12 +6411,12 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span, ~[ivecarg], ty::mk_nil(ccx.tcx), 0u); - let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main_ivec", llfty); + let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main", llfty); let fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl); let bcx = new_top_block_ctxt(fcx); - if main_mode == mm_ivec { + if takes_ivec { let lloutputarg = llvm::LLVMGetParam(llfdecl, 0u); let lltaskarg = llvm::LLVMGetParam(llfdecl, 1u); let llenvarg = llvm::LLVMGetParam(llfdecl, 2u); @@ -6490,6 +6426,14 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span, llenvarg, llargvarg]; bcx.build.FastCall(main_llfn, args); + } else { + let lloutputarg = llvm::LLVMGetParam(llfdecl, 0u); + let lltaskarg = llvm::LLVMGetParam(llfdecl, 1u); + let llenvarg = llvm::LLVMGetParam(llfdecl, 2u); + let args = ~[lloutputarg, + lltaskarg, + llenvarg]; + bcx.build.FastCall(main_llfn, args); } build_return(bcx); diff --git a/src/rt/main.ll.in b/src/rt/main.ll.in index 2081200ba94..c13e167d3c6 100644 --- a/src/rt/main.ll.in +++ b/src/rt/main.ll.in @@ -17,37 +17,20 @@ ; FIXME: Remove after main takes only ivec @_rust_main_is_ivec = external global i32 -declare i32 @rust_start(i32, i32, i32, i32) +declare i32 @rust_start(i32, i32, i32, i32, i32) -declare external fastcc void @_rust_main(i1* nocapture, %task*, %2* nocapture, %5*); +declare external fastcc void @_rust_main(i1* nocapture, %task*, %2* nocapture, %ivec) -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 -} - -declare i32 @rust_start_ivec(i32, i32, i32, i32, i32) - -declare external fastcc void @_rust_main_ivec(i1* nocapture, %task*, %2* nocapture, %ivec) - -define void @_rust_main_wrap_ivec(i1* nocapture, %task *, %2* nocapture, %ivec *) +define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %ivec *) { %ivec = load %ivec *%3 - tail call fastcc void @_rust_main_ivec(i1* %0, %task *%1, %2* nocapture %2, %ivec %ivec) + tail call fastcc void @_rust_main(i1* %0, %task *%1, %2* nocapture %2, %ivec %ivec) ret void } define i32 @"MAIN"(i32, i32) { %is_ivec = load i32 *@_rust_main_is_ivec - %is_ivec1 = trunc i32 %is_ivec to i1 - br i1 %is_ivec1, label %ivec, label %evec -evec: - %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 ptrtoint (void (i1*, %task*, %2*, %ivec*)* @_rust_main_wrap to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32), i32 %is_ivec) ret i32 %3 - -ivec: - %4 = tail call i32 @rust_start_ivec(i32 ptrtoint (void (i1*, %task*, %2*, %ivec*)* @_rust_main_wrap_ivec to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32), i32 %is_ivec) - ret i32 %4 } diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index c211408d4d4..908d3dca80b 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -59,15 +59,15 @@ command_line_args : public kernel_owned // array here to ensure it survives to program-shutdown. args->ref(); + size_t ivec_interior_sz = + sizeof(size_t) * 2 + sizeof(rust_str *) * 4; + args_ivec = (rust_ivec *) + kernel->malloc(ivec_interior_sz, + "command line arg interior"); + args_ivec->fill = 0; + size_t ivec_exterior_sz = sizeof(rust_str *) * argc; + args_ivec->alloc = ivec_exterior_sz; if (main_is_ivec) { - size_t ivec_interior_sz = - sizeof(size_t) * 2 + sizeof(rust_str *) * 4; - args_ivec = (rust_ivec *) - kernel->malloc(ivec_interior_sz, - "command line arg interior"); - args_ivec->fill = 0; - size_t ivec_exterior_sz = sizeof(rust_str *) * argc; - args_ivec->alloc = ivec_exterior_sz; // NB: This is freed by some ivec machinery, probably the drop // glue in main, so we don't free it ourselves args_ivec->payload.ptr = (rust_ivec_heap *) @@ -75,15 +75,11 @@ command_line_args : public kernel_owned "command line arg exterior"); args_ivec->payload.ptr->fill = ivec_exterior_sz; memcpy(&args_ivec->payload.ptr->data, strs, ivec_exterior_sz); - } else { - args_ivec = NULL; } } ~command_line_args() { - if (args_ivec) { - kernel->free(args_ivec); - } + kernel->free(args_ivec); if (args) { // Drop the args we've had pinned here. rust_str **strs = (rust_str**) &args->data[0]; @@ -110,8 +106,8 @@ command_line_args : public kernel_owned int check_claims = 0; extern "C" CDECL int -rust_start_ivec(uintptr_t main_fn, int argc, char **argv, - void* crate_map, int main_is_ivec) { +rust_start(uintptr_t main_fn, int argc, char **argv, + void* crate_map, int main_takes_ivec) { rust_env *env = load_env(); @@ -126,7 +122,7 @@ rust_start_ivec(uintptr_t main_fn, int argc, char **argv, rust_scheduler *sched = root_task->sched; command_line_args *args = new (kernel, "main command line args") - command_line_args(root_task, argc, argv, main_is_ivec); + command_line_args(root_task, argc, argv, main_takes_ivec); DLOG(sched, dom, "startup: %d args in 0x%" PRIxPTR, args->argc, (uintptr_t)args->args); @@ -134,13 +130,7 @@ rust_start_ivec(uintptr_t main_fn, int argc, char **argv, DLOG(sched, dom, "startup: arg[%d] = '%s'", i, args->argv[i]); } - if (main_is_ivec) { - DLOG(sched, dom, "main takes ivec"); - root_task->start(main_fn, (uintptr_t)args->args_ivec); - } else { - DLOG(sched, dom, "main takes vec"); - root_task->start(main_fn, (uintptr_t)args->args); - } + root_task->start(main_fn, (uintptr_t)args->args_ivec); root_task->deref(); root_task = NULL; @@ -160,10 +150,11 @@ rust_start_ivec(uintptr_t main_fn, int argc, char **argv, return ret; } +// FIXME: Transitional. Please remove. extern "C" CDECL int -rust_start(uintptr_t main_fn, int argc, char **argv, - void* crate_map) { - return rust_start_ivec(main_fn, argc, argv, crate_map, 0); +rust_start_ivec(uintptr_t main_fn, int argc, char **argv, + void* crate_map, int main_takes_ivec) { + return rust_start(main_fn, argc, argv, crate_map, main_takes_ivec); }