@@ -102,7 +102,7 @@ pub mod jit {
102
102
use back:: link:: llvm_err;
103
103
use driver:: session:: Session ;
104
104
use lib:: llvm:: llvm;
105
- use lib:: llvm:: { ModuleRef , PassManagerRef } ;
105
+ use lib:: llvm:: { ModuleRef , PassManagerRef , ContextRef } ;
106
106
use metadata:: cstore;
107
107
108
108
use core:: cast;
@@ -125,6 +125,7 @@ pub mod jit {
125
125
126
126
pub fn exec ( sess : Session ,
127
127
pm : PassManagerRef ,
128
+ c : ContextRef ,
128
129
m : ModuleRef ,
129
130
opt : c_int ,
130
131
stacks : bool ) {
@@ -153,26 +154,43 @@ pub mod jit {
153
154
} ) ;
154
155
}
155
156
156
- // The execute function will return a void pointer
157
- // to the _rust_main function. We can do closure
158
- // magic here to turn it straight into a callable rust
159
- // closure. It will also cleanup the memory manager
160
- // for us.
161
-
162
- let entry = llvm:: LLVMRustExecuteJIT ( manager,
163
- pm, m, opt, stacks) ;
164
-
165
- if ptr:: is_null ( entry) {
166
- llvm_err ( sess, ~"Could not JIT ") ;
167
- } else {
168
- let closure = Closure {
169
- code : entry,
170
- env : ptr:: null ( )
171
- } ;
172
- let func: & fn ( ) = cast:: transmute ( closure) ;
157
+ // We custom-build a JIT execution engine via some rust wrappers
158
+ // first. This wrappers takes ownership of the module passed in.
159
+ let ee = llvm:: LLVMRustBuildJIT ( manager, pm, m, opt, stacks) ;
160
+ if ee. is_null ( ) {
161
+ llvm:: LLVMContextDispose ( c) ;
162
+ llvm_err ( sess, ~"Could not create the JIT ") ;
163
+ }
173
164
174
- func ( ) ;
165
+ // Next, we need to get a handle on the _rust_main function by
166
+ // looking up it's corresponding ValueRef and then requesting that
167
+ // the execution engine compiles the function.
168
+ let fun = do str:: as_c_str ( "_rust_main" ) |entry| {
169
+ llvm:: LLVMGetNamedFunction ( m, entry)
170
+ } ;
171
+ if fun. is_null ( ) {
172
+ llvm:: LLVMDisposeExecutionEngine ( ee) ;
173
+ llvm:: LLVMContextDispose ( c) ;
174
+ llvm_err ( sess, ~"Could not find _rust_main in the JIT ") ;
175
175
}
176
+
177
+ // Finally, once we have the pointer to the code, we can do some
178
+ // closure magic here to turn it straight into a callable rust
179
+ // closure
180
+ let code = llvm:: LLVMGetPointerToGlobal ( ee, fun) ;
181
+ assert ! ( !code. is_null( ) ) ;
182
+ let closure = Closure {
183
+ code : code,
184
+ env : ptr:: null ( )
185
+ } ;
186
+ let func: & fn ( ) = cast:: transmute ( closure) ;
187
+ func ( ) ;
188
+
189
+ // Sadly, there currently is no interface to re-use this execution
190
+ // engine, so it's disposed of here along with the context to
191
+ // prevent leaks.
192
+ llvm:: LLVMDisposeExecutionEngine ( ee) ;
193
+ llvm:: LLVMContextDispose ( c) ;
176
194
}
177
195
}
178
196
}
@@ -189,6 +207,7 @@ pub mod write {
189
207
use driver:: session;
190
208
use lib:: llvm:: llvm;
191
209
use lib:: llvm:: { ModuleRef , mk_pass_manager, mk_target_data} ;
210
+ use lib:: llvm:: { ContextRef } ;
192
211
use lib;
193
212
194
213
use back:: passes;
@@ -207,6 +226,7 @@ pub mod write {
207
226
}
208
227
209
228
pub fn run_passes ( sess : Session ,
229
+ llcx : ContextRef ,
210
230
llmod : ModuleRef ,
211
231
output_type : output_type ,
212
232
output : & Path ) {
@@ -281,7 +301,7 @@ pub mod write {
281
301
// JIT execution takes ownership of the module,
282
302
// so don't dispose and return.
283
303
284
- jit:: exec ( sess, pm. llpm , llmod, CodeGenOptLevel , true ) ;
304
+ jit:: exec ( sess, pm. llpm , llcx , llmod, CodeGenOptLevel , true ) ;
285
305
286
306
if sess. time_llvm_passes ( ) {
287
307
llvm:: LLVMRustPrintPassTimings ( ) ;
@@ -349,6 +369,7 @@ pub mod write {
349
369
// Clean up and return
350
370
351
371
llvm:: LLVMDisposeModule ( llmod) ;
372
+ llvm:: LLVMContextDispose ( llcx) ;
352
373
if sess. time_llvm_passes ( ) {
353
374
llvm:: LLVMRustPrintPassTimings ( ) ;
354
375
}
@@ -367,6 +388,7 @@ pub mod write {
367
388
}
368
389
369
390
llvm:: LLVMDisposeModule ( llmod) ;
391
+ llvm:: LLVMContextDispose ( llcx) ;
370
392
if sess. time_llvm_passes ( ) { llvm:: LLVMRustPrintPassTimings ( ) ; }
371
393
}
372
394
}
0 commit comments