about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-08-17 16:50:49 -0700
committerBrian Anderson <banderson@mozilla.com>2011-08-18 13:09:49 -0700
commitc2d8a4df35a0a22d64d7d15ccd5fe25a495a2bc1 (patch)
treeefb0e83b03126a0fadd2b2d240e3217a860fcc92 /src
parent53eb4a30255fc6b3d6be700c10eb7248b0bad3a9 (diff)
downloadrust-c2d8a4df35a0a22d64d7d15ccd5fe25a495a2bc1.tar.gz
rust-c2d8a4df35a0a22d64d7d15ccd5fe25a495a2bc1.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans.rs94
-rw-r--r--src/rt/main.ll.in27
-rw-r--r--src/rt/rust.cpp43
3 files changed, 41 insertions, 123 deletions
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);
-
-    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);
+    let llfn = create_main(ccx, sp, main_llfn, main_takes_ivec);
+    create_main_type_indicator(ccx, main_takes_ivec);
+    ccx.main_fn = some(llfn);
 
-        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<command_line_args>
         // 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_args>
                                "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<command_line_args>
 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);
 }