Skip to content

librustc/libstd: No longer pass crate_map to start. #9301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 24, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 37 additions & 14 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
@@ -2442,11 +2442,6 @@ pub fn create_entry_wrapper(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,
@@ -2469,8 +2464,7 @@ pub fn create_entry_wrapper(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)
@@ -2479,8 +2473,7 @@ pub fn create_entry_wrapper(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)
@@ -2661,13 +2654,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
}
}
}
}
@@ -2985,7 +2981,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;
}

@@ -3140,6 +3143,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 {
3 changes: 1 addition & 2 deletions src/librustc/middle/typeck/mod.rs
Original file line number Diff line number Diff line change
@@ -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()
}
40 changes: 39 additions & 1 deletion src/libstd/rt/crate_map.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,21 @@ use vec;
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that's pretty cool!

}

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,
18 changes: 18 additions & 0 deletions src/libstd/rt/logging.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ use libc::{uintptr_t, exit, STDERR_FILENO};
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 @@ impl Logger for StdErrLogger {
/// 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() } }
31 changes: 30 additions & 1 deletion src/libstd/rt/mod.rs
Original file line number Diff line number Diff line change
@@ -171,11 +171,11 @@ pub mod borrowck;
///
/// * `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);
@@ -184,25 +184,44 @@ 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);
cleanup();

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`.
@@ -212,6 +231,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() {
4 changes: 2 additions & 2 deletions src/libstd/unstable/dynamic_lib.rs
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ mod test {
#[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 @@ mod dl {
}

#[cfg(target_os = "win32")]
mod dl {
pub mod dl {
use os;
use libc;
use path;
14 changes: 14 additions & 0 deletions src/libstd/unstable/lang.rs
Original file line number Diff line number Diff line change
@@ -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();
};
}
}
6 changes: 6 additions & 0 deletions src/test/run-pass/attr-start.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,12 @@
//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;
}
8 changes: 8 additions & 0 deletions src/test/run-pass/core-rt-smoke.rs
Original file line number Diff line number Diff line change
@@ -13,8 +13,16 @@
// 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");
}
}
13 changes: 12 additions & 1 deletion src/test/run-pass/rt-start-main-thread.rs
Original file line number Diff line number Diff line change
@@ -11,11 +11,22 @@
// 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");
do spawn {
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");
}
}
}