auto merge of #9301 : luqmana/rust/ncm, r=brson
Get rid of the crate_map arg! r? @brson
This commit is contained in:
commit
9705399504
10 changed files with 167 additions and 21 deletions
|
@ -2416,11 +2416,6 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
|
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_fn, args) = if use_start_lang_item {
|
||||||
let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) {
|
let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
|
@ -2443,8 +2438,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||||
C_null(Type::opaque_box(ccx).ptr_to()),
|
C_null(Type::opaque_box(ccx).ptr_to()),
|
||||||
opaque_rust_main,
|
opaque_rust_main,
|
||||||
llvm::LLVMGetParam(llfn, 0),
|
llvm::LLVMGetParam(llfn, 0),
|
||||||
llvm::LLVMGetParam(llfn, 1),
|
llvm::LLVMGetParam(llfn, 1)
|
||||||
opaque_crate_map
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
(start_fn, args)
|
(start_fn, args)
|
||||||
|
@ -2453,8 +2447,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
||||||
let args = ~[
|
let args = ~[
|
||||||
C_null(Type::opaque_box(ccx).ptr_to()),
|
C_null(Type::opaque_box(ccx).ptr_to()),
|
||||||
llvm::LLVMGetParam(llfn, 0 as c_uint),
|
llvm::LLVMGetParam(llfn, 0 as c_uint),
|
||||||
llvm::LLVMGetParam(llfn, 1 as c_uint),
|
llvm::LLVMGetParam(llfn, 1 as c_uint)
|
||||||
opaque_crate_map
|
|
||||||
];
|
];
|
||||||
|
|
||||||
(rust_main, args)
|
(rust_main, args)
|
||||||
|
@ -2635,13 +2628,16 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
|
||||||
}
|
}
|
||||||
ast::foreign_item_static(*) => {
|
ast::foreign_item_static(*) => {
|
||||||
let ident = foreign::link_name(ccx, ni);
|
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);
|
let ty = type_of(ccx, ty);
|
||||||
llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
|
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)
|
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;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3114,6 +3117,26 @@ pub fn trans_crate(sess: session::Session,
|
||||||
|
|
||||||
decl_gc_metadata(ccx, llmod_id);
|
decl_gc_metadata(ccx, llmod_id);
|
||||||
fill_crate_map(ccx, ccx.crate_map);
|
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);
|
glue::emit_tydescs(ccx);
|
||||||
write_abi_version(ccx);
|
write_abi_version(ccx);
|
||||||
if ccx.sess.opts.debuginfo {
|
if ccx.sess.opts.debuginfo {
|
||||||
|
|
|
@ -402,8 +402,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
||||||
bound_lifetime_names: opt_vec::Empty,
|
bound_lifetime_names: opt_vec::Empty,
|
||||||
inputs: ~[
|
inputs: ~[
|
||||||
ty::mk_int(),
|
ty::mk_int(),
|
||||||
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8())),
|
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
|
||||||
ty::mk_imm_ptr(tcx, ty::mk_u8())
|
|
||||||
],
|
],
|
||||||
output: ty::mk_int()
|
output: ty::mk_int()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,21 @@ use vec;
|
||||||
use hashmap::HashSet;
|
use hashmap::HashSet;
|
||||||
use container::MutableSet;
|
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,
|
name: *c_char,
|
||||||
log_level: *mut u32
|
log_level: *mut u32
|
||||||
}
|
}
|
||||||
|
@ -34,6 +48,30 @@ struct CrateMap {
|
||||||
children: [*CrateMap, ..1]
|
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 {
|
unsafe fn version(crate_map: *CrateMap) -> i32 {
|
||||||
match (*crate_map).version {
|
match (*crate_map).version {
|
||||||
1 => return 1,
|
1 => return 1,
|
||||||
|
|
|
@ -12,6 +12,7 @@ use libc::{uintptr_t, exit, STDERR_FILENO};
|
||||||
use option::{Some, None, Option};
|
use option::{Some, None, Option};
|
||||||
use rt::util::dumb_println;
|
use rt::util::dumb_println;
|
||||||
use rt::crate_map::{ModEntry, iter_crate_map};
|
use rt::crate_map::{ModEntry, iter_crate_map};
|
||||||
|
#[cfg(not(stage0))] use rt::crate_map::get_crate_map;
|
||||||
use str::StrSlice;
|
use str::StrSlice;
|
||||||
use str::raw::from_c_str;
|
use str::raw::from_c_str;
|
||||||
use u32;
|
use u32;
|
||||||
|
@ -211,6 +212,7 @@ impl Logger for StdErrLogger {
|
||||||
/// Configure logging by traversing the crate map and setting the
|
/// Configure logging by traversing the crate map and setting the
|
||||||
/// per-module global logging flags based on the logging spec
|
/// per-module global logging flags based on the logging spec
|
||||||
#[fixed_stack_segment] #[inline(never)]
|
#[fixed_stack_segment] #[inline(never)]
|
||||||
|
#[cfg(stage0)]
|
||||||
pub fn init(crate_map: *u8) {
|
pub fn init(crate_map: *u8) {
|
||||||
use os;
|
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)]
|
#[fixed_stack_segment] #[inline(never)]
|
||||||
pub fn console_on() { unsafe { rust_log_console_on() } }
|
pub fn console_on() { unsafe { rust_log_console_on() } }
|
||||||
|
|
|
@ -172,11 +172,11 @@ pub mod borrowck;
|
||||||
///
|
///
|
||||||
/// * `argc` & `argv` - The argument vector. On Unix this information is used
|
/// * `argc` & `argv` - The argument vector. On Unix this information is used
|
||||||
/// by os::args.
|
/// by os::args.
|
||||||
/// * `crate_map` - Runtime information about the executing crate, mostly for logging
|
|
||||||
///
|
///
|
||||||
/// # Return value
|
/// # Return value
|
||||||
///
|
///
|
||||||
/// The return value is used as the process return code. 0 on success, 101 on error.
|
/// 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 {
|
pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
|
||||||
|
|
||||||
init(argc, argv, crate_map);
|
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;
|
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,
|
/// 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.
|
/// 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,
|
/// This is appropriate for running code that must execute on the main thread,
|
||||||
/// such as the platform event loop and GUI.
|
/// 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 {
|
pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
|
||||||
init(argc, argv, crate_map);
|
init(argc, argv, crate_map);
|
||||||
let exit_code = run_on_main_thread(main);
|
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;
|
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.
|
/// One-time runtime initialization.
|
||||||
///
|
///
|
||||||
/// Initializes global state, including frobbing
|
/// Initializes global state, including frobbing
|
||||||
/// the crate's logging flags, registering GC
|
/// the crate's logging flags, registering GC
|
||||||
/// metadata, and storing the process arguments.
|
/// metadata, and storing the process arguments.
|
||||||
|
#[cfg(stage0)]
|
||||||
pub fn init(argc: int, argv: **u8, crate_map: *u8) {
|
pub fn init(argc: int, argv: **u8, crate_map: *u8) {
|
||||||
// XXX: Derefing these pointers is not safe.
|
// XXX: Derefing these pointers is not safe.
|
||||||
// Need to propagate the unsafety to `start`.
|
// 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);
|
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.
|
/// One-time runtime cleanup.
|
||||||
pub fn cleanup() {
|
pub fn cleanup() {
|
||||||
|
|
|
@ -138,7 +138,7 @@ mod test {
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[cfg(target_os = "freebsd")]
|
#[cfg(target_os = "freebsd")]
|
||||||
mod dl {
|
pub mod dl {
|
||||||
use c_str::ToCStr;
|
use c_str::ToCStr;
|
||||||
use libc;
|
use libc;
|
||||||
use path;
|
use path;
|
||||||
|
@ -207,7 +207,7 @@ mod dl {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "win32")]
|
#[cfg(target_os = "win32")]
|
||||||
mod dl {
|
pub mod dl {
|
||||||
use os;
|
use os;
|
||||||
use libc;
|
use libc;
|
||||||
use path;
|
use path;
|
||||||
|
|
|
@ -93,6 +93,7 @@ pub unsafe fn check_not_borrowed(a: *u8,
|
||||||
borrowck::check_not_borrowed(a, file, line)
|
borrowck::check_not_borrowed(a, file, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[lang="start"]
|
#[lang="start"]
|
||||||
pub fn start(main: *u8, argc: int, argv: **c_char,
|
pub fn start(main: *u8, argc: int, argv: **c_char,
|
||||||
crate_map: *u8) -> int {
|
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();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
//xfail-fast
|
//xfail-fast
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
|
#[cfg(stage0)]
|
||||||
fn start(_argc: int, _argv: **u8, _crate_map: *u8) -> int {
|
fn start(_argc: int, _argv: **u8, _crate_map: *u8) -> int {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#[start]
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
fn start(_argc: int, _argv: **u8) -> int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -13,8 +13,16 @@
|
||||||
// A simple test of starting the runtime manually
|
// A simple test of starting the runtime manually
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
|
#[cfg(stage0)]
|
||||||
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
|
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
|
||||||
do std::rt::start(argc, argv, crate_map) {
|
do std::rt::start(argc, argv, crate_map) {
|
||||||
info!("creating my own runtime is joy");
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
|
#[cfg(stage0)]
|
||||||
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
|
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
|
||||||
do std::rt::start_on_main_thread(argc, argv, crate_map) {
|
do std::rt::start_on_main_thread(argc, argv, crate_map) {
|
||||||
info!("running on main thread");
|
info!("running on main thread");
|
||||||
|
@ -18,4 +19,14 @@ fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
|
||||||
info!("running on another thread");
|
info!("running on another thread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue