3
3
4
4
use std:: cell:: RefCell ;
5
5
use std:: ffi:: CString ;
6
- use std:: os:: raw:: { c_char, c_int} ;
7
6
8
7
use cranelift_codegen:: binemit:: { NullStackMapSink , NullTrapSink } ;
9
8
use rustc_codegen_ssa:: CrateInfo ;
@@ -50,6 +49,34 @@ fn create_jit_module<'tcx>(
50
49
( jit_module, cx)
51
50
}
52
51
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
+
53
80
pub ( crate ) fn run_jit ( tcx : TyCtxt < ' _ > , backend_config : BackendConfig ) -> ! {
54
81
if !tcx. sess . opts . output_types . should_codegen ( ) {
55
82
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) -> ! {
85
112
crate :: base:: codegen_fn ( & mut cx, & mut jit_module, inst)
86
113
} ) ;
87
114
}
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
+ }
89
118
} ,
90
119
MonoItem :: Static ( def_id) => {
91
120
crate :: constant:: codegen_static ( tcx, & mut jit_module, def_id) ;
@@ -107,41 +136,22 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
107
136
jit_module. finalize_definitions ( ) ;
108
137
unsafe { cx. unwind_context . register_jit ( & jit_module) } ;
109
138
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 ) ;
119
140
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) ;
134
142
135
143
LAZY_JIT_STATE . with ( |lazy_jit_state| {
136
144
let mut lazy_jit_state = lazy_jit_state. borrow_mut ( ) ;
137
145
assert ! ( lazy_jit_state. is_none( ) ) ;
138
146
* lazy_jit_state = Some ( JitState { backend_config, jit_module } ) ;
139
147
} ) ;
140
148
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 ) ;
145
155
}
146
156
147
157
#[ no_mangle]
@@ -236,20 +246,23 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
236
246
imported_symbols
237
247
}
238
248
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
+ ) {
242
255
let pointer_type = module. target_config ( ) . pointer_type ( ) ;
243
256
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) ;
246
259
let func_id = module. declare_function ( & name, Linkage :: Export , & sig) . unwrap ( ) ;
247
260
248
261
let instance_ptr = Box :: into_raw ( Box :: new ( inst) ) ;
249
262
250
263
let jit_fn = module
251
264
. declare_function (
252
- "__clif_jit_fn" ,
265
+ jit_fn ,
253
266
Linkage :: Import ,
254
267
& Signature {
255
268
call_conv : module. target_config ( ) . default_call_conv ,
0 commit comments