Add a 'start' lang item and use it instead of rust_start

This commit is contained in:
Brian Anderson 2013-02-26 19:40:39 -08:00
parent 93a7f237d7
commit f4327230fa
4 changed files with 58 additions and 18 deletions

View File

@ -11,7 +11,7 @@
//! Runtime calls emitted by the compiler.
use cast::transmute;
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t};
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
use managed::raw::BoxRepr;
use str;
use sys;
@ -121,6 +121,21 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
str::raw::from_buf_len(ptr, len)
}
#[lang="start"]
pub fn start(main: *u8, argc: int, argv: *c_char,
crate_map: *u8) -> int {
extern {
fn rust_start(main: *c_void, argc: c_int, argv: *c_char,
crate_map: *c_void) -> c_int;
}
unsafe {
return rust_start(main as *c_void, argc as c_int, argv,
crate_map as *c_void) as int;
}
}
// Local Variables:
// mode: rust;
// fill-column: 78;

View File

@ -838,9 +838,6 @@ pub fn link_binary(sess: Session,
}
}
// Always want the runtime linked in
cc_args.push(~"-lrustrt");
// On linux librt and libdl are an indirect dependencies via rustrt,
// and binutils 2.22+ won't add them automatically
if sess.targ_cfg.os == session::os_linux {
@ -880,6 +877,9 @@ pub fn link_binary(sess: Session,
cc_args.push(~"-lmorestack");
}
// Always want the runtime linked in
cc_args.push(~"-lrustrt");
// FIXME (#2397): At some point we want to rpath our guesses as to where
// extern libraries might live, based on the addl_lib_search_paths
cc_args.push_all(rpath::get_rpath_flags(sess, &output));

View File

@ -75,16 +75,18 @@ pub enum LangItem {
ReturnToMutFnLangItem, // 31
CheckNotBorrowedFnLangItem, // 32
StrDupUniqFnLangItem, // 33
StartFnLangItem, // 34
}
pub struct LanguageItems {
items: [ Option<def_id> * 34 ]
items: [ Option<def_id> * 35 ]
}
pub impl LanguageItems {
static pub fn new(&self) -> LanguageItems {
LanguageItems {
items: [ None, ..34 ]
items: [ None, ..35 ]
}
}
@ -136,6 +138,8 @@ pub impl LanguageItems {
32 => "check_not_borrowed",
33 => "strdup_uniq",
34 => "start",
_ => "???"
}
}
@ -248,6 +252,9 @@ pub impl LanguageItems {
pub fn strdup_uniq_fn(&const self) -> def_id {
self.items[StrDupUniqFnLangItem as uint].get()
}
pub fn start_fn(&const self) -> def_id {
self.items[StartFnLangItem as uint].get()
}
}
fn LanguageItemCollector(crate: @crate,
@ -296,6 +303,7 @@ fn LanguageItemCollector(crate: @crate,
item_refs.insert(@~"check_not_borrowed",
CheckNotBorrowedFnLangItem as uint);
item_refs.insert(@~"strdup_uniq", StrDupUniqFnLangItem as uint);
item_refs.insert(@~"start", StartFnLangItem as uint);
LanguageItemCollector {
crate: crate,

View File

@ -2267,7 +2267,7 @@ pub fn create_main_wrapper(ccx: @CrateContext,
fn main_name() -> ~str { return ~"WinMain@16"; }
#[cfg(unix)]
fn main_name() -> ~str { return ~"main"; }
let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
let llfty = T_fn(~[ccx.int_type, T_ptr(T_i8())], ccx.int_type);
// FIXME #4404 android JNI hacks
let llfn = if *ccx.sess.building_library {
@ -2285,33 +2285,50 @@ pub fn create_main_wrapper(ccx: @CrateContext,
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
}
let crate_map = ccx.crate_map;
let start_ty = T_fn(~[val_ty(rust_main), ccx.int_type, ccx.int_type,
val_ty(crate_map)], ccx.int_type);
let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
let start_def_id = ccx.tcx.lang_items.start_fn();
let start_fn = if start_def_id.crate == ast::local_crate {
ccx.sess.bug(~"start lang item is never in the local crate")
} else {
let start_fn_type = csearch::get_type(ccx.tcx,
start_def_id).ty;
trans_external_path(ccx, start_def_id, start_fn_type)
};
let retptr = unsafe {
llvm::LLVMBuildAlloca(bld, ccx.int_type, noname())
};
let args = unsafe {
let opaque_rust_main = llvm::LLVMBuildPointerCast(
bld, rust_main, T_ptr(T_i8()), noname());
let opaque_crate_map = llvm::LLVMBuildPointerCast(
bld, crate_map, T_ptr(T_i8()), noname());
if *ccx.sess.building_library {
~[
rust_main,
retptr,
C_null(T_opaque_box_ptr(ccx)),
opaque_rust_main,
llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
crate_map
opaque_crate_map
]
} else {
~[
rust_main,
retptr,
C_null(T_opaque_box_ptr(ccx)),
opaque_rust_main,
llvm::LLVMGetParam(llfn, 0 as c_uint),
llvm::LLVMGetParam(llfn, 1 as c_uint),
crate_map
opaque_crate_map
]
}
};
let result = unsafe {
llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
args.len() as c_uint, noname())
};
unsafe {
llvm::LLVMBuildCall(bld, start_fn, vec::raw::to_ptr(args),
args.len() as c_uint, noname());
let result = llvm::LLVMBuildLoad(bld, retptr, noname());
llvm::LLVMBuildRet(bld, result);
}
}