Skip to content

Commit 427563f

Browse files
committed
Extract a couple of functions out of run_jit
1 parent eed9aaa commit 427563f

File tree

1 file changed

+48
-35
lines changed

1 file changed

+48
-35
lines changed

src/driver/jit.rs

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
44
use std::cell::RefCell;
55
use std::ffi::CString;
6-
use std::os::raw::{c_char, c_int};
76

87
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
98
use rustc_codegen_ssa::CrateInfo;
@@ -50,6 +49,34 @@ fn create_jit_module<'tcx>(
5049
(jit_module, cx)
5150
}
5251

52+
fn make_args(crate_name: &str, args: &[String]) -> (usize, *const *const u8) {
53+
let mut argv = std::iter::once(crate_name)
54+
.chain(args.iter().map(|arg| &**arg))
55+
.map(|arg| CString::new(arg).unwrap().into_raw() as *const u8)
56+
.collect::<Vec<_>>();
57+
58+
// Push a null pointer as a terminating argument. This is required by POSIX and
59+
// useful as some dynamic linkers use it as a marker to jump over.
60+
argv.push(std::ptr::null());
61+
62+
let (ptr, size, _cap) = argv.into_raw_parts();
63+
(size, ptr)
64+
}
65+
66+
fn get_main_fn(jit_module: &mut JITModule) -> extern "C" fn(usize, *const *const u8) -> isize {
67+
let start_sig = Signature {
68+
params: vec![
69+
AbiParam::new(jit_module.target_config().pointer_type()),
70+
AbiParam::new(jit_module.target_config().pointer_type()),
71+
],
72+
returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
73+
call_conv: jit_module.target_config().default_call_conv,
74+
};
75+
let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap();
76+
let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id);
77+
unsafe { ::std::mem::transmute(finalized_start) }
78+
}
79+
5380
pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
5481
if !tcx.sess.opts.output_types.should_codegen() {
5582
tcx.sess.fatal("JIT mode doesn't work with `cargo check`");
@@ -85,7 +112,9 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
85112
crate::base::codegen_fn(&mut cx, &mut jit_module, inst)
86113
});
87114
}
88-
CodegenMode::JitLazy => codegen_shim(&mut cx, &mut jit_module, inst),
115+
CodegenMode::JitLazy => {
116+
codegen_shim(&mut cx, &mut jit_module, inst, "__clif_jit_fn");
117+
}
89118
},
90119
MonoItem::Static(def_id) => {
91120
crate::constant::codegen_static(tcx, &mut jit_module, def_id);
@@ -107,41 +136,22 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
107136
jit_module.finalize_definitions();
108137
unsafe { cx.unwind_context.register_jit(&jit_module) };
109138

110-
println!(
111-
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
112-
);
113-
114-
let args = std::iter::once(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string())
115-
.chain(backend_config.jit_args.iter().map(|arg| &**arg))
116-
.map(|arg| CString::new(arg).unwrap())
117-
.collect::<Vec<_>>();
118-
let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
139+
let (argc, argv) = make_args(&tcx.crate_name(LOCAL_CRATE).as_str(), &backend_config.jit_args);
119140

120-
// Push a null pointer as a terminating argument. This is required by POSIX and
121-
// useful as some dynamic linkers use it as a marker to jump over.
122-
argv.push(std::ptr::null());
123-
124-
let start_sig = Signature {
125-
params: vec![
126-
AbiParam::new(jit_module.target_config().pointer_type()),
127-
AbiParam::new(jit_module.target_config().pointer_type()),
128-
],
129-
returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
130-
call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
131-
};
132-
let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap();
133-
let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id);
141+
let start_fn = get_main_fn(&mut jit_module);
134142

135143
LAZY_JIT_STATE.with(|lazy_jit_state| {
136144
let mut lazy_jit_state = lazy_jit_state.borrow_mut();
137145
assert!(lazy_jit_state.is_none());
138146
*lazy_jit_state = Some(JitState { backend_config, jit_module });
139147
});
140148

141-
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
142-
unsafe { ::std::mem::transmute(finalized_start) };
143-
let ret = f(args.len() as c_int, argv.as_ptr());
144-
std::process::exit(ret);
149+
println!(
150+
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
151+
);
152+
153+
let ret = start_fn(argc, argv);
154+
std::process::exit(ret as i32);
145155
}
146156

147157
#[no_mangle]
@@ -236,20 +246,23 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
236246
imported_symbols
237247
}
238248

239-
fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: Instance<'tcx>) {
240-
let tcx = cx.tcx;
241-
249+
fn codegen_shim<'tcx>(
250+
cx: &mut CodegenCx<'tcx>,
251+
module: &mut JITModule,
252+
inst: Instance<'tcx>,
253+
jit_fn: &str,
254+
) {
242255
let pointer_type = module.target_config().pointer_type();
243256

244-
let name = tcx.symbol_name(inst).name.to_string();
245-
let sig = crate::abi::get_function_sig(tcx, module.isa().triple(), inst);
257+
let name = cx.tcx.symbol_name(inst).name.to_string();
258+
let sig = crate::abi::get_function_sig(cx.tcx, module.isa().triple(), inst);
246259
let func_id = module.declare_function(&name, Linkage::Export, &sig).unwrap();
247260

248261
let instance_ptr = Box::into_raw(Box::new(inst));
249262

250263
let jit_fn = module
251264
.declare_function(
252-
"__clif_jit_fn",
265+
jit_fn,
253266
Linkage::Import,
254267
&Signature {
255268
call_conv: module.target_config().default_call_conv,

0 commit comments

Comments
 (0)