Skip to content

Commit 9705399

Browse files
committed
auto merge of #9301 : luqmana/rust/ncm, r=brson
Get rid of the crate_map arg! r? @brson
2 parents 2e77c25 + 20a10ff commit 9705399

File tree

10 files changed

+167
-21
lines changed

10 files changed

+167
-21
lines changed

src/librustc/middle/trans/base.rs

+37-14
Original file line numberDiff line numberDiff line change
@@ -2416,11 +2416,6 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
24162416
unsafe {
24172417
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
24182418

2419-
let crate_map = ccx.crate_map;
2420-
let opaque_crate_map = do "crate_map".with_c_str |buf| {
2421-
llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
2422-
};
2423-
24242419
let (start_fn, args) = if use_start_lang_item {
24252420
let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) {
24262421
Ok(id) => id,
@@ -2443,8 +2438,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
24432438
C_null(Type::opaque_box(ccx).ptr_to()),
24442439
opaque_rust_main,
24452440
llvm::LLVMGetParam(llfn, 0),
2446-
llvm::LLVMGetParam(llfn, 1),
2447-
opaque_crate_map
2441+
llvm::LLVMGetParam(llfn, 1)
24482442
]
24492443
};
24502444
(start_fn, args)
@@ -2453,8 +2447,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
24532447
let args = ~[
24542448
C_null(Type::opaque_box(ccx).ptr_to()),
24552449
llvm::LLVMGetParam(llfn, 0 as c_uint),
2456-
llvm::LLVMGetParam(llfn, 1 as c_uint),
2457-
opaque_crate_map
2450+
llvm::LLVMGetParam(llfn, 1 as c_uint)
24582451
];
24592452

24602453
(rust_main, args)
@@ -2635,13 +2628,16 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
26352628
}
26362629
ast::foreign_item_static(*) => {
26372630
let ident = foreign::link_name(ccx, ni);
2638-
let g = do ident.with_c_str |buf| {
2639-
unsafe {
2631+
unsafe {
2632+
let g = do ident.with_c_str |buf| {
26402633
let ty = type_of(ccx, ty);
26412634
llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
2635+
};
2636+
if attr::contains_name(ni.attrs, "weak_linkage") {
2637+
lib::llvm::SetLinkage(g, lib::llvm::ExternalWeakLinkage);
26422638
}
2643-
};
2644-
g
2639+
g
2640+
}
26452641
}
26462642
}
26472643
}
@@ -2959,7 +2955,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
29592955
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
29602956
}
29612957
};
2962-
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
2958+
// On windows we'd like to export the toplevel cratemap
2959+
// such that we can find it from libstd.
2960+
if targ_cfg.os == session::OsWin32 && "toplevel" == mapname {
2961+
lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
2962+
} else {
2963+
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
2964+
}
2965+
29632966
return map;
29642967
}
29652968

@@ -3114,6 +3117,26 @@ pub fn trans_crate(sess: session::Session,
31143117

31153118
decl_gc_metadata(ccx, llmod_id);
31163119
fill_crate_map(ccx, ccx.crate_map);
3120+
3121+
// NOTE win32: wart with exporting crate_map symbol
3122+
// We set the crate map (_rust_crate_map_toplevel) to use dll_export
3123+
// linkage but that ends up causing the linker to look for a
3124+
// __rust_crate_map_toplevel symbol (extra underscore) which it will
3125+
// subsequently fail to find. So to mitigate that we just introduce
3126+
// an alias from the symbol it expects to the one that actually exists.
3127+
if ccx.sess.targ_cfg.os == session::OsWin32 &&
3128+
!*ccx.sess.building_library {
3129+
3130+
let maptype = val_ty(ccx.crate_map).to_ref();
3131+
3132+
do "__rust_crate_map_toplevel".with_c_str |buf| {
3133+
unsafe {
3134+
llvm::LLVMAddAlias(ccx.llmod, maptype,
3135+
ccx.crate_map, buf);
3136+
}
3137+
}
3138+
}
3139+
31173140
glue::emit_tydescs(ccx);
31183141
write_abi_version(ccx);
31193142
if ccx.sess.opts.debuginfo {

src/librustc/middle/typeck/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
402402
bound_lifetime_names: opt_vec::Empty,
403403
inputs: ~[
404404
ty::mk_int(),
405-
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8())),
406-
ty::mk_imm_ptr(tcx, ty::mk_u8())
405+
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
407406
],
408407
output: ty::mk_int()
409408
}

src/libstd/rt/crate_map.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,21 @@ use vec;
1616
use hashmap::HashSet;
1717
use container::MutableSet;
1818

19-
pub struct ModEntry{
19+
// Need to tell the linker on OS X to not barf on undefined symbols
20+
// and instead look them up at runtime, which we need to resolve
21+
// the crate_map properly.
22+
#[cfg(target_os = "macos")]
23+
#[link_args = "-undefined dynamic_lookup"]
24+
extern {}
25+
26+
#[cfg(not(stage0), not(windows))]
27+
extern {
28+
#[weak_linkage]
29+
#[link_name = "_rust_crate_map_toplevel"]
30+
static CRATE_MAP: CrateMap;
31+
}
32+
33+
pub struct ModEntry {
2034
name: *c_char,
2135
log_level: *mut u32
2236
}
@@ -34,6 +48,30 @@ struct CrateMap {
3448
children: [*CrateMap, ..1]
3549
}
3650

51+
#[cfg(not(stage0), not(windows))]
52+
pub fn get_crate_map() -> *CrateMap {
53+
&'static CRATE_MAP as *CrateMap
54+
}
55+
56+
#[cfg(not(stage0), windows)]
57+
#[fixed_stack_segment]
58+
#[inline(never)]
59+
pub fn get_crate_map() -> *CrateMap {
60+
use c_str::ToCStr;
61+
use unstable::dynamic_lib::dl;
62+
63+
let sym = unsafe {
64+
let module = dl::open_internal();
65+
let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
66+
dl::symbol(module, buf)
67+
};
68+
dl::close(module);
69+
sym
70+
};
71+
72+
sym as *CrateMap
73+
}
74+
3775
unsafe fn version(crate_map: *CrateMap) -> i32 {
3876
match (*crate_map).version {
3977
1 => return 1,

src/libstd/rt/logging.rs

+18
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use libc::{uintptr_t, exit, STDERR_FILENO};
1212
use option::{Some, None, Option};
1313
use rt::util::dumb_println;
1414
use rt::crate_map::{ModEntry, iter_crate_map};
15+
#[cfg(not(stage0))] use rt::crate_map::get_crate_map;
1516
use str::StrSlice;
1617
use str::raw::from_c_str;
1718
use u32;
@@ -211,6 +212,7 @@ impl Logger for StdErrLogger {
211212
/// Configure logging by traversing the crate map and setting the
212213
/// per-module global logging flags based on the logging spec
213214
#[fixed_stack_segment] #[inline(never)]
215+
#[cfg(stage0)]
214216
pub fn init(crate_map: *u8) {
215217
use os;
216218

@@ -224,6 +226,22 @@ pub fn init(crate_map: *u8) {
224226
}
225227
}
226228
}
229+
#[cfg(not(stage0))]
230+
pub fn init() {
231+
use os;
232+
233+
let crate_map = get_crate_map() as *u8;
234+
235+
let log_spec = os::getenv("RUST_LOG");
236+
match log_spec {
237+
Some(spec) => {
238+
update_log_settings(crate_map, spec);
239+
}
240+
None => {
241+
update_log_settings(crate_map, ~"");
242+
}
243+
}
244+
}
227245

228246
#[fixed_stack_segment] #[inline(never)]
229247
pub fn console_on() { unsafe { rust_log_console_on() } }

src/libstd/rt/mod.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ pub mod borrowck;
172172
///
173173
/// * `argc` & `argv` - The argument vector. On Unix this information is used
174174
/// by os::args.
175-
/// * `crate_map` - Runtime information about the executing crate, mostly for logging
176175
///
177176
/// # Return value
178177
///
179178
/// The return value is used as the process return code. 0 on success, 101 on error.
179+
#[cfg(stage0)]
180180
pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
181181

182182
init(argc, argv, crate_map);
@@ -185,25 +185,44 @@ pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
185185

186186
return exit_code;
187187
}
188+
#[cfg(not(stage0))]
189+
pub fn start(argc: int, argv: **u8, main: ~fn()) -> int {
190+
191+
init(argc, argv);
192+
let exit_code = run(main);
193+
cleanup();
194+
195+
return exit_code;
196+
}
188197

189198
/// Like `start` but creates an additional scheduler on the current thread,
190199
/// which in most cases will be the 'main' thread, and pins the main task to it.
191200
///
192201
/// This is appropriate for running code that must execute on the main thread,
193202
/// such as the platform event loop and GUI.
203+
#[cfg(stage0)]
194204
pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
195205
init(argc, argv, crate_map);
196206
let exit_code = run_on_main_thread(main);
197207
cleanup();
198208

199209
return exit_code;
200210
}
211+
#[cfg(not(stage0))]
212+
pub fn start_on_main_thread(argc: int, argv: **u8, main: ~fn()) -> int {
213+
init(argc, argv);
214+
let exit_code = run_on_main_thread(main);
215+
cleanup();
216+
217+
return exit_code;
218+
}
201219

202220
/// One-time runtime initialization.
203221
///
204222
/// Initializes global state, including frobbing
205223
/// the crate's logging flags, registering GC
206224
/// metadata, and storing the process arguments.
225+
#[cfg(stage0)]
207226
pub fn init(argc: int, argv: **u8, crate_map: *u8) {
208227
// XXX: Derefing these pointers is not safe.
209228
// Need to propagate the unsafety to `start`.
@@ -213,6 +232,16 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) {
213232
logging::init(crate_map);
214233
}
215234
}
235+
#[cfg(not(stage0))]
236+
pub fn init(argc: int, argv: **u8) {
237+
// XXX: Derefing these pointers is not safe.
238+
// Need to propagate the unsafety to `start`.
239+
unsafe {
240+
args::init(argc, argv);
241+
env::init();
242+
logging::init();
243+
}
244+
}
216245

217246
/// One-time runtime cleanup.
218247
pub fn cleanup() {

src/libstd/unstable/dynamic_lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ mod test {
138138
#[cfg(target_os = "android")]
139139
#[cfg(target_os = "macos")]
140140
#[cfg(target_os = "freebsd")]
141-
mod dl {
141+
pub mod dl {
142142
use c_str::ToCStr;
143143
use libc;
144144
use path;
@@ -207,7 +207,7 @@ mod dl {
207207
}
208208

209209
#[cfg(target_os = "win32")]
210-
mod dl {
210+
pub mod dl {
211211
use os;
212212
use libc;
213213
use path;

src/libstd/unstable/lang.rs

+14
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub unsafe fn check_not_borrowed(a: *u8,
9393
borrowck::check_not_borrowed(a, file, line)
9494
}
9595

96+
#[cfg(stage0)]
9697
#[lang="start"]
9798
pub fn start(main: *u8, argc: int, argv: **c_char,
9899
crate_map: *u8) -> int {
@@ -105,3 +106,16 @@ pub fn start(main: *u8, argc: int, argv: **c_char,
105106
};
106107
}
107108
}
109+
110+
#[cfg(not(stage0))]
111+
#[lang="start"]
112+
pub fn start(main: *u8, argc: int, argv: **c_char) -> int {
113+
use rt;
114+
115+
unsafe {
116+
return do rt::start(argc, argv as **u8) {
117+
let main: extern "Rust" fn() = transmute(main);
118+
main();
119+
};
120+
}
121+
}

src/test/run-pass/attr-start.rs

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
//xfail-fast
1212

1313
#[start]
14+
#[cfg(stage0)]
1415
fn start(_argc: int, _argv: **u8, _crate_map: *u8) -> int {
1516
return 0;
1617
}
18+
#[start]
19+
#[cfg(not(stage0))]
20+
fn start(_argc: int, _argv: **u8) -> int {
21+
return 0;
22+
}

src/test/run-pass/core-rt-smoke.rs

+8
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@
1313
// A simple test of starting the runtime manually
1414

1515
#[start]
16+
#[cfg(stage0)]
1617
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
1718
do std::rt::start(argc, argv, crate_map) {
1819
info!("creating my own runtime is joy");
1920
}
2021
}
22+
#[start]
23+
#[cfg(not(stage0))]
24+
fn start(argc: int, argv: **u8) -> int {
25+
do std::rt::start(argc, argv) {
26+
info!("creating my own runtime is joy");
27+
}
28+
}

src/test/run-pass/rt-start-main-thread.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,22 @@
1111
// xfail-fast
1212

1313
#[start]
14+
#[cfg(stage0)]
1415
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
1516
do std::rt::start_on_main_thread(argc, argv, crate_map) {
1617
info!("running on main thread");
1718
do spawn {
1819
info!("running on another thread");
1920
}
2021
}
21-
}
22+
}
23+
#[start]
24+
#[cfg(not(stage0))]
25+
fn start(argc: int, argv: **u8) -> int {
26+
do std::rt::start_on_main_thread(argc, argv) {
27+
info!("running on main thread");
28+
do spawn {
29+
info!("running on another thread");
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)