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