]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #9301 : luqmana/rust/ncm, r=brson
authorbors <bors@rust-lang.org>
Mon, 23 Sep 2013 22:46:05 +0000 (15:46 -0700)
committerbors <bors@rust-lang.org>
Mon, 23 Sep 2013 22:46:05 +0000 (15:46 -0700)
Get rid of the crate_map arg!

r? @brson

src/librustc/middle/trans/base.rs
src/librustc/middle/typeck/mod.rs
src/libstd/rt/crate_map.rs
src/libstd/rt/logging.rs
src/libstd/rt/mod.rs
src/libstd/unstable/dynamic_lib.rs
src/libstd/unstable/lang.rs
src/test/run-pass/attr-start.rs
src/test/run-pass/core-rt-smoke.rs
src/test/run-pass/rt-start-main-thread.rs

index f7fcd8f908d714809109b70cdb803f127ace295a..441cc1bfae264cabff1b60ea61cf19edcfeecf26 100644 (file)
@@ -2416,11 +2416,6 @@ fn create_entry_fn(ccx: @mut CrateContext,
         unsafe {
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
 
-            let crate_map = ccx.crate_map;
-            let opaque_crate_map = do "crate_map".with_c_str |buf| {
-                llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
-            };
-
             let (start_fn, args) = if use_start_lang_item {
                 let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) {
                     Ok(id) => id,
@@ -2443,8 +2438,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
                         C_null(Type::opaque_box(ccx).ptr_to()),
                         opaque_rust_main,
                         llvm::LLVMGetParam(llfn, 0),
-                        llvm::LLVMGetParam(llfn, 1),
-                        opaque_crate_map
+                        llvm::LLVMGetParam(llfn, 1)
                      ]
                 };
                 (start_fn, args)
@@ -2453,8 +2447,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
                 let args = ~[
                     C_null(Type::opaque_box(ccx).ptr_to()),
                     llvm::LLVMGetParam(llfn, 0 as c_uint),
-                    llvm::LLVMGetParam(llfn, 1 as c_uint),
-                    opaque_crate_map
+                    llvm::LLVMGetParam(llfn, 1 as c_uint)
                 ];
 
                 (rust_main, args)
@@ -2635,13 +2628,16 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
                         }
                         ast::foreign_item_static(*) => {
                             let ident = foreign::link_name(ccx, ni);
-                            let g = do ident.with_c_str |buf| {
-                                unsafe {
+                            unsafe {
+                                let g = do ident.with_c_str |buf| {
                                     let ty = type_of(ccx, ty);
                                     llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
+                                };
+                                if attr::contains_name(ni.attrs, "weak_linkage") {
+                                    lib::llvm::SetLinkage(g, lib::llvm::ExternalWeakLinkage);
                                 }
-                            };
-                            g
+                                g
+                            }
                         }
                     }
                 }
@@ -2959,7 +2955,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
     };
-    lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
+    // On windows we'd like to export the toplevel cratemap
+    // such that we can find it from libstd.
+    if targ_cfg.os == session::OsWin32 && "toplevel" == mapname {
+        lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
+    } else {
+        lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
+    }
+
     return map;
 }
 
@@ -3114,6 +3117,26 @@ pub fn trans_crate(sess: session::Session,
 
     decl_gc_metadata(ccx, llmod_id);
     fill_crate_map(ccx, ccx.crate_map);
+
+    // NOTE win32: wart with exporting crate_map symbol
+    // We set the crate map (_rust_crate_map_toplevel) to use dll_export
+    // linkage but that ends up causing the linker to look for a
+    // __rust_crate_map_toplevel symbol (extra underscore) which it will
+    // subsequently fail to find. So to mitigate that we just introduce
+    // an alias from the symbol it expects to the one that actually exists.
+    if ccx.sess.targ_cfg.os == session::OsWin32 &&
+       !*ccx.sess.building_library {
+
+        let maptype = val_ty(ccx.crate_map).to_ref();
+
+        do "__rust_crate_map_toplevel".with_c_str |buf| {
+            unsafe {
+                llvm::LLVMAddAlias(ccx.llmod, maptype,
+                                   ccx.crate_map, buf);
+            }
+        }
+    }
+
     glue::emit_tydescs(ccx);
     write_abi_version(ccx);
     if ccx.sess.opts.debuginfo {
index 8d7dbdf263ed8555a1aa09accbc87d3819fbfefe..45a65f954a3a91e824948e1d3e5bebdfae705065 100644 (file)
@@ -402,8 +402,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
                     bound_lifetime_names: opt_vec::Empty,
                     inputs: ~[
                         ty::mk_int(),
-                        ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8())),
-                        ty::mk_imm_ptr(tcx, ty::mk_u8())
+                        ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
                     ],
                     output: ty::mk_int()
                 }
index 270b5e5b1372e556a8de29f0774709419fc583f7..f73aa1fad67dce05b1792edfa133a3fc3a88398b 100644 (file)
 use hashmap::HashSet;
 use container::MutableSet;
 
-pub struct ModEntry{
+// Need to tell the linker on OS X to not barf on undefined symbols
+// and instead look them up at runtime, which we need to resolve
+// the crate_map properly.
+#[cfg(target_os = "macos")]
+#[link_args = "-undefined dynamic_lookup"]
+extern {}
+
+#[cfg(not(stage0), not(windows))]
+extern {
+    #[weak_linkage]
+    #[link_name = "_rust_crate_map_toplevel"]
+    static CRATE_MAP: CrateMap;
+}
+
+pub struct ModEntry {
     name: *c_char,
     log_level: *mut u32
 }
@@ -34,6 +48,30 @@ struct CrateMap {
     children: [*CrateMap, ..1]
 }
 
+#[cfg(not(stage0), not(windows))]
+pub fn get_crate_map() -> *CrateMap {
+    &'static CRATE_MAP as *CrateMap
+}
+
+#[cfg(not(stage0), windows)]
+#[fixed_stack_segment]
+#[inline(never)]
+pub fn get_crate_map() -> *CrateMap {
+    use c_str::ToCStr;
+    use unstable::dynamic_lib::dl;
+
+    let sym = unsafe {
+        let module = dl::open_internal();
+        let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
+            dl::symbol(module, buf)
+        };
+        dl::close(module);
+        sym
+    };
+
+    sym as *CrateMap
+}
+
 unsafe fn version(crate_map: *CrateMap) -> i32 {
     match (*crate_map).version {
         1 => return 1,
index fbe05267cf4f9ff9bafef3b088c6e2d612b0e7bb..26072079bcc18e1c6270d54b16a4a6aeccf1e14b 100644 (file)
@@ -12,6 +12,7 @@
 use option::{Some, None, Option};
 use rt::util::dumb_println;
 use rt::crate_map::{ModEntry, iter_crate_map};
+#[cfg(not(stage0))] use rt::crate_map::get_crate_map;
 use str::StrSlice;
 use str::raw::from_c_str;
 use u32;
@@ -211,6 +212,7 @@ fn print(s: &str) {
 /// Configure logging by traversing the crate map and setting the
 /// per-module global logging flags based on the logging spec
 #[fixed_stack_segment] #[inline(never)]
+#[cfg(stage0)]
 pub fn init(crate_map: *u8) {
     use os;
 
@@ -224,6 +226,22 @@ pub fn init(crate_map: *u8) {
         }
     }
 }
+#[cfg(not(stage0))]
+pub fn init() {
+    use os;
+
+    let crate_map = get_crate_map() as *u8;
+
+    let log_spec = os::getenv("RUST_LOG");
+    match log_spec {
+        Some(spec) => {
+            update_log_settings(crate_map, spec);
+        }
+        None => {
+            update_log_settings(crate_map, ~"");
+        }
+    }
+}
 
 #[fixed_stack_segment] #[inline(never)]
 pub fn console_on() { unsafe { rust_log_console_on() } }
index df59e5538b40ad03ab193a409af9689157281316..85a379cab5a040b03a198a6bab6ec4b3cfa3e264 100644 (file)
 ///
 /// * `argc` & `argv` - The argument vector. On Unix this information is used
 ///   by os::args.
-/// * `crate_map` - Runtime information about the executing crate, mostly for logging
 ///
 /// # Return value
 ///
 /// The return value is used as the process return code. 0 on success, 101 on error.
+#[cfg(stage0)]
 pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
 
     init(argc, argv, crate_map);
@@ -185,12 +185,22 @@ pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
 
     return exit_code;
 }
+#[cfg(not(stage0))]
+pub fn start(argc: int, argv: **u8, main: ~fn()) -> int {
+
+    init(argc, argv);
+    let exit_code = run(main);
+    cleanup();
+
+    return exit_code;
+}
 
 /// Like `start` but creates an additional scheduler on the current thread,
 /// which in most cases will be the 'main' thread, and pins the main task to it.
 ///
 /// This is appropriate for running code that must execute on the main thread,
 /// such as the platform event loop and GUI.
+#[cfg(stage0)]
 pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
     init(argc, argv, crate_map);
     let exit_code = run_on_main_thread(main);
@@ -198,12 +208,21 @@ pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn())
 
     return exit_code;
 }
+#[cfg(not(stage0))]
+pub fn start_on_main_thread(argc: int, argv: **u8, main: ~fn()) -> int {
+    init(argc, argv);
+    let exit_code = run_on_main_thread(main);
+    cleanup();
+
+    return exit_code;
+}
 
 /// One-time runtime initialization.
 ///
 /// Initializes global state, including frobbing
 /// the crate's logging flags, registering GC
 /// metadata, and storing the process arguments.
+#[cfg(stage0)]
 pub fn init(argc: int, argv: **u8, crate_map: *u8) {
     // XXX: Derefing these pointers is not safe.
     // Need to propagate the unsafety to `start`.
@@ -213,6 +232,16 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) {
         logging::init(crate_map);
     }
 }
+#[cfg(not(stage0))]
+pub fn init(argc: int, argv: **u8) {
+    // XXX: Derefing these pointers is not safe.
+    // Need to propagate the unsafety to `start`.
+    unsafe {
+        args::init(argc, argv);
+        env::init();
+        logging::init();
+    }
+}
 
 /// One-time runtime cleanup.
 pub fn cleanup() {
index 4c92d9c2e362c5272edbaf4e3e2bb399db614140..41ff79bc8845815db4eda5382c676bb04473eb62 100644 (file)
@@ -138,7 +138,7 @@ fn test_errors_do_not_crash() {
 #[cfg(target_os = "android")]
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
-mod dl {
+pub mod dl {
     use c_str::ToCStr;
     use libc;
     use path;
@@ -207,7 +207,7 @@ pub enum RTLD {
 }
 
 #[cfg(target_os = "win32")]
-mod dl {
+pub mod dl {
     use os;
     use libc;
     use path;
index 1d839b55195be9c7bc436d1d001238b69f70bc54..baa705514894bf69daa1ee806dbd342a56ccb061 100644 (file)
@@ -93,6 +93,7 @@ pub unsafe fn check_not_borrowed(a: *u8,
     borrowck::check_not_borrowed(a, file, line)
 }
 
+#[cfg(stage0)]
 #[lang="start"]
 pub fn start(main: *u8, argc: int, argv: **c_char,
              crate_map: *u8) -> int {
@@ -105,3 +106,16 @@ pub fn start(main: *u8, argc: int, argv: **c_char,
         };
     }
 }
+
+#[cfg(not(stage0))]
+#[lang="start"]
+pub fn start(main: *u8, argc: int, argv: **c_char) -> int {
+    use rt;
+
+    unsafe {
+        return do rt::start(argc, argv as **u8) {
+            let main: extern "Rust" fn() = transmute(main);
+            main();
+        };
+    }
+}
index ba54e92ef997805472e7de6228546b7d4235ff56..4c9d388dbd77ba0a43eb150603ebb8582db6b3c1 100644 (file)
 //xfail-fast
 
 #[start]
+#[cfg(stage0)]
 fn start(_argc: int, _argv: **u8, _crate_map: *u8) -> int {
     return 0;
 }
+#[start]
+#[cfg(not(stage0))]
+fn start(_argc: int, _argv: **u8) -> int {
+    return 0;
+}
index 10bd013b618bc4d28f6be9248f0b5eea29dcc357..d7824a6524fe56280df78d3a71a3bf04af8e8bdb 100644 (file)
 // A simple test of starting the runtime manually
 
 #[start]
+#[cfg(stage0)]
 fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
     do std::rt::start(argc, argv, crate_map) {
         info!("creating my own runtime is joy");
     }
 }
+#[start]
+#[cfg(not(stage0))]
+fn start(argc: int, argv: **u8) -> int {
+    do std::rt::start(argc, argv) {
+        info!("creating my own runtime is joy");
+    }
+}
index 8328e7416c57951faf201d39137c31a75c46f4e6..05e761378857961bee225a32a06adcf45db2258c 100644 (file)
@@ -11,6 +11,7 @@
 // xfail-fast
 
 #[start]
+#[cfg(stage0)]
 fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
     do std::rt::start_on_main_thread(argc, argv, crate_map) {
         info!("running on main thread");
@@ -18,4 +19,14 @@ fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
             info!("running on another thread");
         }
     }
-}
\ No newline at end of file
+}
+#[start]
+#[cfg(not(stage0))]
+fn start(argc: int, argv: **u8) -> int {
+    do std::rt::start_on_main_thread(argc, argv) {
+        info!("running on main thread");
+        do spawn {
+            info!("running on another thread");
+        }
+    }
+}