Add a 'start' lang item and use it instead of rust_start
This commit is contained in:
parent
93a7f237d7
commit
f4327230fa
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user