about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-10-20 13:48:10 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-10-20 17:18:38 +0200
commitef63f09dcd65729f84a4f49432467ad5ace86906 (patch)
tree867d013350635b1e1130baa0a57345d8016c2d31 /src
parentcff9c676748b719d5333aa7521e4684f3543e4b9 (diff)
downloadrust-ef63f09dcd65729f84a4f49432467ad5ace86906.tar.gz
rust-ef63f09dcd65729f84a4f49432467ad5ace86906.zip
Don't rely on main.ll anymore
I'll remove the actual file after I register a snapshot.

Issue #992
Diffstat (limited to 'src')
-rw-r--r--src/comp/back/link.rs8
-rw-r--r--src/comp/middle/trans.rs84
-rw-r--r--src/comp/middle/trans_common.rs3
-rw-r--r--src/rt/main.ll.in11
-rw-r--r--src/rt/rust.cpp4
5 files changed, 63 insertions, 47 deletions
diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs
index 562c7f0d6f1..6988f0c1f21 100644
--- a/src/comp/back/link.rs
+++ b/src/comp/back/link.rs
@@ -503,12 +503,6 @@ fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: str) -> str {
 // gcc to link the object file with some libs
 fn link_binary(sess: session::session,
                saved_out_filename: str) {
-    let main: str = alt filesearch::search(
-        sess.filesearch(), bind filesearch::pick_file("main.o", _)) {
-      option::some(f) { f }
-      option::none. { sess.fatal("can't find main.o") }
-    };
-
     // The default library location, we need this to find the runtime.
     // The location of crates will be determined as needed.
     let stage: str = "-L" + sess.filesearch().get_target_lib_path();
@@ -579,7 +573,7 @@ fn link_binary(sess: session::session,
         }
     } else {
         // FIXME: why do we hardcode -lm?
-        gcc_args += ["-lm", main];
+        gcc_args += ["-lm"];
     }
 
 
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 83d1de8bfaf..6c6b2c590af 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -5632,6 +5632,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
 
     let llfn = create_main(ccx, sp, main_llfn, main_takes_argv);
     ccx.main_fn = some(llfn);
+    create_entry_fn(ccx, llfn);
 
     fn create_main(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
                    takes_argv: bool) -> ValueRef {
@@ -5664,6 +5665,35 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
 
         ret llfdecl;
     }
+
+    fn create_entry_fn(ccx: @crate_ctxt, rust_main: ValueRef) {
+        #[cfg(target_os = "win32")]
+        fn main_name() -> str { ret "WinMain@16"; }
+        #[cfg(target_os = "macos")]
+        fn main_name() -> str { ret "main"; }
+        #[cfg(target_os = "linux")]
+        fn main_name() -> str { ret "main"; }
+        let llfty = T_fn([T_int(), T_int()], T_int());
+        let llfn = decl_cdecl_fn(ccx.llmod, main_name(), llfty);
+        let llbb = str::as_buf("top", {|buf|
+            llvm::LLVMAppendBasicBlock(llfn, buf)
+        });
+        let bld = *ccx.builder;
+        llvm::LLVMPositionBuilderAtEnd(bld, llbb);
+        let crate_map = ccx.crate_map;
+        let start_ty = T_fn([val_ty(rust_main), T_int(), T_int(),
+                             val_ty(crate_map)], T_int());
+        let start = str::as_buf("rust_start", {|buf|
+            llvm::LLVMAddGlobal(ccx.llmod, start_ty, buf)
+        });
+        let args = [rust_main, llvm::LLVMGetParam(llfn, 0u),
+                    llvm::LLVMGetParam(llfn, 1u), crate_map];
+        let result = unsafe {
+            llvm::LLVMBuildCall(bld, start, vec::to_ptr(args),
+                                vec::len(args), noname())
+        };
+        llvm::LLVMBuildRet(bld, result);
+    }
 }
 
 // Create a /real/ closure: this is like create_fn_pair, but creates a
@@ -6146,38 +6176,39 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
 }
 
 
+fn decl_crate_map(sess: session::session, mapname: str,
+                  llmod: ModuleRef) -> ValueRef {
+    let n_subcrates = 1;
+    let cstore = sess.get_cstore();
+    while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; }
+    if !sess.get_opts().library { mapname = "toplevel"; }
+    let sym_name = "_rust_crate_map_" + mapname;
+    let arrtype = T_array(T_int(), n_subcrates as uint);
+    let maptype = T_struct([T_int(), arrtype]);
+    let map = str::as_buf(sym_name, {|buf|
+        llvm::LLVMAddGlobal(llmod, maptype, buf)
+    });
+    llvm::LLVMSetLinkage(map, lib::llvm::LLVMExternalLinkage
+                         as llvm::Linkage);
+    ret map;
+}
+
 // FIXME use hashed metadata instead of crate names once we have that
-fn create_crate_map(ccx: @crate_ctxt) -> ValueRef {
+fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
     let subcrates: [ValueRef] = [];
     let i = 1;
     let cstore = ccx.sess.get_cstore();
     while cstore::have_crate_data(cstore, i) {
         let nm = "_rust_crate_map_" + cstore::get_crate_data(cstore, i).name;
-        let cr =
-            str::as_buf(nm,
-                        {|buf|
-                            llvm::LLVMAddGlobal(ccx.llmod, T_int(), buf)
-                        });
+        let cr = str::as_buf(nm, {|buf|
+            llvm::LLVMAddGlobal(ccx.llmod, T_int(), buf)
+        });
         subcrates += [p2i(cr)];
         i += 1;
     }
     subcrates += [C_int(0)];
-    let mapname;
-    if ccx.sess.get_opts().library {
-        mapname = ccx.link_meta.name;
-    } else { mapname = "toplevel"; }
-    let sym_name = "_rust_crate_map_" + mapname;
-    let arrtype = T_array(T_int(), std::vec::len::<ValueRef>(subcrates));
-    let maptype = T_struct([T_int(), arrtype]);
-    let map =
-        str::as_buf(sym_name,
-                    {|buf| llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) });
-    llvm::LLVMSetLinkage(map,
-                         lib::llvm::LLVMExternalLinkage as llvm::Linkage);
-    llvm::LLVMSetInitializer(map,
-                             C_struct([p2i(create_module_map(ccx)),
-                                       C_array(T_int(), subcrates)]));
-    ret map;
+    llvm::LLVMSetInitializer(map, C_struct([p2i(create_module_map(ccx)),
+                                            C_array(T_int(), subcrates)]));
 }
 
 fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) {
@@ -6242,6 +6273,8 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
     let sha1s = map::mk_hashmap::<ty::t, str>(hasher, eqer);
     let short_names = map::mk_hashmap::<ty::t, str>(hasher, eqer);
     let sha = std::sha1::mk_sha1();
+    let link_meta = link::build_link_meta(sess, *crate, output, sha);
+    let crate_map = decl_crate_map(sess, link_meta.name, llmod);
     let ccx =
         @{sess: sess,
           llmod: llmod,
@@ -6253,7 +6286,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
           ast_map: amap,
           item_symbols: new_int_hash::<str>(),
           mutable main_fn: none::<ValueRef>,
-          link_meta: link::build_link_meta(sess, *crate, output, sha),
+          link_meta: link_meta,
           tag_sizes: tag_sizes,
           discrims: new_int_hash::<ValueRef>(),
           discrim_symbols: new_int_hash::<str>(),
@@ -6283,13 +6316,14 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
           task_type: task_type,
           builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
           shape_cx: shape::mk_ctxt(llmod),
-          gc_cx: gc::mk_ctxt()};
+          gc_cx: gc::mk_ctxt(),
+          crate_map: crate_map};
     let cx = new_local_ctxt(ccx);
     collect_items(ccx, crate);
     collect_tag_ctors(ccx, crate);
     trans_constants(ccx, crate);
     trans_mod(cx, crate.node.module);
-    create_crate_map(ccx);
+    fill_crate_map(ccx, crate_map);
     emit_tydescs(ccx);
     shape::gen_shape_tables(ccx);
     write_abi_version(ccx);
diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs
index 76e04bb9aab..2218b5a8ee8 100644
--- a/src/comp/middle/trans_common.rs
+++ b/src/comp/middle/trans_common.rs
@@ -123,7 +123,8 @@ type crate_ctxt =
      task_type: TypeRef,
      builder: BuilderRef_res,
      shape_cx: shape::ctxt,
-     gc_cx: gc::ctxt};
+     gc_cx: gc::ctxt,
+     crate_map: ValueRef};
 
 type local_ctxt =
     {path: [str],
diff --git a/src/rt/main.ll.in b/src/rt/main.ll.in
index a953ef90444..8c19b2df251 100644
--- a/src/rt/main.ll.in
+++ b/src/rt/main.ll.in
@@ -11,14 +11,3 @@
 %task = type { i32, i32, i32, i32, i32, i32, i32, i32 }
 
 %vec = type { i32, i32, [0 x i8] }
-
-@_rust_crate_map_toplevel = external global %0
-
-declare i32 @rust_start(i32, i32, i32, i32)
-
-declare external void @_rust_main(i1* nocapture, %task*, %2* nocapture, %vec*)
-
-define i32 @"MAIN"(i32, i32) {
-  %result = tail call i32 @rust_start(i32 ptrtoint (void (i1*, %task*, %2*, %vec*)* @_rust_main to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32))
-  ret i32 %result
-}
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp
index 122c7b306bf..b8a3cde5a93 100644
--- a/src/rt/rust.cpp
+++ b/src/rt/rust.cpp
@@ -74,9 +74,7 @@ command_line_args : public kernel_owned<command_line_args>
 int check_claims = 0;
 
 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) {
     rust_env *env = load_env();
 
     update_log_settings(crate_map, env->logspec);