Continue transition to an ivec-only main
Only generate a single main function. Rename rust_start_ivec to rust_start, leaving a transitional rust_start_ivec in place.
This commit is contained in:
parent
53eb4a3025
commit
c2d8a4df35
3 changed files with 41 additions and 123 deletions
|
@ -6385,84 +6385,20 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span,
|
||||||
ccx.sess.span_fatal(sp, "multiple 'main' functions");
|
ccx.sess.span_fatal(sp, "multiple 'main' functions");
|
||||||
}
|
}
|
||||||
|
|
||||||
tag main_mode {
|
let main_takes_ivec = alt ty::struct(ccx.tcx, main_node_type) {
|
||||||
mm_nil;
|
|
||||||
mm_vec;
|
|
||||||
mm_ivec;
|
|
||||||
};
|
|
||||||
|
|
||||||
let main_mode = alt ty::struct(ccx.tcx, main_node_type) {
|
|
||||||
ty::ty_fn(_, args, _ ,_ ,_) {
|
ty::ty_fn(_, args, _ ,_ ,_) {
|
||||||
if std::vec::len(args) == 0u {
|
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 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Have to create two different main functions depending on whether
|
let llfn = create_main(ccx, sp, main_llfn, main_takes_ivec);
|
||||||
// main was declared to take vec or ivec
|
create_main_type_indicator(ccx, main_takes_ivec);
|
||||||
let llfn_vec = create_main_wrapper_vec(ccx, sp, main_llfn, main_mode);
|
ccx.main_fn = some(llfn);
|
||||||
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);
|
|
||||||
|
|
||||||
fn create_main_wrapper_vec(ccx: &@crate_ctxt,
|
fn create_main(ccx: &@crate_ctxt,
|
||||||
sp: &span,
|
sp: &span,
|
||||||
main_llfn: ValueRef,
|
main_llfn: ValueRef,
|
||||||
main_mode: main_mode) -> ValueRef {
|
takes_ivec: bool) -> 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 {
|
|
||||||
let ivecarg = {
|
let ivecarg = {
|
||||||
mode: ty::mo_val,
|
mode: ty::mo_val,
|
||||||
ty: ty::mk_ivec(ccx.tcx, {
|
ty: ty::mk_ivec(ccx.tcx, {
|
||||||
|
@ -6475,12 +6411,12 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span,
|
||||||
~[ivecarg],
|
~[ivecarg],
|
||||||
ty::mk_nil(ccx.tcx),
|
ty::mk_nil(ccx.tcx),
|
||||||
0u);
|
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 fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl);
|
||||||
let bcx = new_top_block_ctxt(fcx);
|
let bcx = new_top_block_ctxt(fcx);
|
||||||
|
|
||||||
if main_mode == mm_ivec {
|
if takes_ivec {
|
||||||
let lloutputarg = llvm::LLVMGetParam(llfdecl, 0u);
|
let lloutputarg = llvm::LLVMGetParam(llfdecl, 0u);
|
||||||
let lltaskarg = llvm::LLVMGetParam(llfdecl, 1u);
|
let lltaskarg = llvm::LLVMGetParam(llfdecl, 1u);
|
||||||
let llenvarg = llvm::LLVMGetParam(llfdecl, 2u);
|
let llenvarg = llvm::LLVMGetParam(llfdecl, 2u);
|
||||||
|
@ -6490,6 +6426,14 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span,
|
||||||
llenvarg,
|
llenvarg,
|
||||||
llargvarg];
|
llargvarg];
|
||||||
bcx.build.FastCall(main_llfn, args);
|
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);
|
build_return(bcx);
|
||||||
|
|
||||||
|
|
|
@ -17,37 +17,20 @@
|
||||||
; FIXME: Remove after main takes only ivec
|
; FIXME: Remove after main takes only ivec
|
||||||
@_rust_main_is_ivec = external global i32
|
@_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 *)
|
define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %ivec *)
|
||||||
{
|
|
||||||
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 *)
|
|
||||||
{
|
{
|
||||||
%ivec = load %ivec *%3
|
%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
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @"MAIN"(i32, i32) {
|
define i32 @"MAIN"(i32, i32) {
|
||||||
%is_ivec = load i32 *@_rust_main_is_ivec
|
%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*, %ivec*)* @_rust_main_wrap to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32), i32 %is_ivec)
|
||||||
%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))
|
|
||||||
ret i32 %3
|
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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,15 +59,15 @@ command_line_args : public kernel_owned<command_line_args>
|
||||||
// array here to ensure it survives to program-shutdown.
|
// array here to ensure it survives to program-shutdown.
|
||||||
args->ref();
|
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) {
|
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
|
// NB: This is freed by some ivec machinery, probably the drop
|
||||||
// glue in main, so we don't free it ourselves
|
// glue in main, so we don't free it ourselves
|
||||||
args_ivec->payload.ptr = (rust_ivec_heap *)
|
args_ivec->payload.ptr = (rust_ivec_heap *)
|
||||||
|
@ -75,15 +75,11 @@ command_line_args : public kernel_owned<command_line_args>
|
||||||
"command line arg exterior");
|
"command line arg exterior");
|
||||||
args_ivec->payload.ptr->fill = ivec_exterior_sz;
|
args_ivec->payload.ptr->fill = ivec_exterior_sz;
|
||||||
memcpy(&args_ivec->payload.ptr->data, strs, ivec_exterior_sz);
|
memcpy(&args_ivec->payload.ptr->data, strs, ivec_exterior_sz);
|
||||||
} else {
|
|
||||||
args_ivec = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~command_line_args() {
|
~command_line_args() {
|
||||||
if (args_ivec) {
|
kernel->free(args_ivec);
|
||||||
kernel->free(args_ivec);
|
|
||||||
}
|
|
||||||
if (args) {
|
if (args) {
|
||||||
// Drop the args we've had pinned here.
|
// Drop the args we've had pinned here.
|
||||||
rust_str **strs = (rust_str**) &args->data[0];
|
rust_str **strs = (rust_str**) &args->data[0];
|
||||||
|
@ -110,8 +106,8 @@ command_line_args : public kernel_owned<command_line_args>
|
||||||
int check_claims = 0;
|
int check_claims = 0;
|
||||||
|
|
||||||
extern "C" CDECL int
|
extern "C" CDECL int
|
||||||
rust_start_ivec(uintptr_t main_fn, int argc, char **argv,
|
rust_start(uintptr_t main_fn, int argc, char **argv,
|
||||||
void* crate_map, int main_is_ivec) {
|
void* crate_map, int main_takes_ivec) {
|
||||||
|
|
||||||
rust_env *env = load_env();
|
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;
|
rust_scheduler *sched = root_task->sched;
|
||||||
command_line_args *args
|
command_line_args *args
|
||||||
= new (kernel, "main command line 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,
|
DLOG(sched, dom, "startup: %d args in 0x%" PRIxPTR,
|
||||||
args->argc, (uintptr_t)args->args);
|
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]);
|
DLOG(sched, dom, "startup: arg[%d] = '%s'", i, args->argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (main_is_ivec) {
|
root_task->start(main_fn, (uintptr_t)args->args_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->deref();
|
root_task->deref();
|
||||||
root_task = NULL;
|
root_task = NULL;
|
||||||
|
|
||||||
|
@ -160,10 +150,11 @@ rust_start_ivec(uintptr_t main_fn, int argc, char **argv,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Transitional. Please remove.
|
||||||
extern "C" CDECL int
|
extern "C" CDECL int
|
||||||
rust_start(uintptr_t main_fn, int argc, char **argv,
|
rust_start_ivec(uintptr_t main_fn, int argc, char **argv,
|
||||||
void* crate_map) {
|
void* crate_map, int main_takes_ivec) {
|
||||||
return rust_start_ivec(main_fn, argc, argv, crate_map, 0);
|
return rust_start(main_fn, argc, argv, crate_map, main_takes_ivec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue