Skip to content

Commit e86b954

Browse files
committed
Directly invoke the main function in JIT mode
Fixes #1151
1 parent 218b383 commit e86b954

File tree

1 file changed

+52
-22
lines changed

1 file changed

+52
-22
lines changed

src/driver/jit.rs

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::os::raw::{c_char, c_int};
77

88
use rustc_codegen_ssa::CrateInfo;
99
use rustc_middle::mir::mono::MonoItem;
10+
use rustc_session::config::EntryFnType;
1011

1112
use cranelift_jit::{JITBuilder, JITModule};
1213

@@ -32,16 +33,6 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
3233
let mut jit_module = JITModule::new(jit_builder);
3334
assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type());
3435

35-
let sig = Signature {
36-
params: vec![
37-
AbiParam::new(jit_module.target_config().pointer_type()),
38-
AbiParam::new(jit_module.target_config().pointer_type()),
39-
],
40-
returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
41-
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
42-
};
43-
let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap();
44-
4536
let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
4637
let mono_items = cgus
4738
.iter()
@@ -86,24 +77,17 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
8677
tcx.sess.fatal("Inline asm is not supported in JIT mode");
8778
}
8879

89-
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context);
9080
crate::allocator::codegen(tcx, &mut jit_module, &mut unwind_context);
9181

9282
tcx.sess.abort_if_errors();
9383

9484
jit_module.finalize_definitions();
95-
9685
let _unwind_register_guard = unsafe { unwind_context.register_jit(&jit_module) };
9786

98-
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
99-
10087
println!(
10188
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
10289
);
10390

104-
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
105-
unsafe { ::std::mem::transmute(finalized_main) };
106-
10791
let args = ::std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new());
10892
let args = std::iter::once(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string())
10993
.chain(args.split(' '))
@@ -118,12 +102,58 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
118102
BACKEND_CONFIG.with(|tls_backend_config| {
119103
assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none())
120104
});
121-
CURRENT_MODULE
122-
.with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none()));
123105

124-
let ret = f(args.len() as c_int, argv.as_ptr());
106+
let (main_def_id, entry_ty) = tcx.entry_fn(LOCAL_CRATE).unwrap();
107+
let instance = Instance::mono(tcx, main_def_id.to_def_id()).polymorphize(tcx);
108+
109+
match entry_ty {
110+
EntryFnType::Main => {
111+
// FIXME set program arguments somehow
125112

126-
std::process::exit(ret);
113+
let main_sig = Signature {
114+
params: vec![],
115+
returns: vec![],
116+
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
117+
};
118+
let main_func_id = jit_module
119+
.declare_function(tcx.symbol_name(instance).name, Linkage::Import, &main_sig)
120+
.unwrap();
121+
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
122+
123+
CURRENT_MODULE.with(|current_module| {
124+
assert!(current_module.borrow_mut().replace(jit_module).is_none())
125+
});
126+
127+
let f: extern "C" fn() = unsafe { ::std::mem::transmute(finalized_main) };
128+
f();
129+
std::process::exit(0);
130+
}
131+
EntryFnType::Start => {
132+
let start_sig = Signature {
133+
params: vec![
134+
AbiParam::new(jit_module.target_config().pointer_type()),
135+
AbiParam::new(jit_module.target_config().pointer_type()),
136+
],
137+
returns: vec![AbiParam::new(
138+
jit_module.target_config().pointer_type(), /*isize*/
139+
)],
140+
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
141+
};
142+
let start_func_id = jit_module
143+
.declare_function(tcx.symbol_name(instance).name, Linkage::Import, &start_sig)
144+
.unwrap();
145+
let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id);
146+
147+
CURRENT_MODULE.with(|current_module| {
148+
assert!(current_module.borrow_mut().replace(jit_module).is_none())
149+
});
150+
151+
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
152+
unsafe { ::std::mem::transmute(finalized_start) };
153+
let ret = f(args.len() as c_int, argv.as_ptr());
154+
std::process::exit(ret);
155+
}
156+
}
127157
}
128158

129159
#[no_mangle]
@@ -220,7 +250,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
220250
imported_symbols
221251
}
222252

223-
pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) {
253+
fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) {
224254
let tcx = cx.tcx;
225255

226256
let pointer_type = cx.module.target_config().pointer_type();

0 commit comments

Comments
 (0)