@@ -34,9 +34,9 @@ use data_layout::DataLayout;
34
34
use execution_engine:: ExecutionEngine ;
35
35
use memory_buffer:: MemoryBuffer ;
36
36
use support:: LLVMString ;
37
- use targets:: Target ;
37
+ use targets:: { Target , InitializationConfig } ;
38
38
use types:: { AsTypeRef , BasicType , FunctionType , BasicTypeEnum } ;
39
- use values:: { AsValueRef , BasicValue , BasicValueEnum , FunctionValue , GlobalValue , MetadataValue } ;
39
+ use values:: { AsValueRef , BasicValue , FunctionValue , GlobalValue , MetadataValue } ;
40
40
41
41
enum_rename ! {
42
42
/// This enum defines how to link a global variable or function in a module. The variant documenation is
@@ -417,8 +417,15 @@ impl Module {
417
417
///
418
418
/// assert_eq!(module.get_context(), context);
419
419
/// ```
420
- // SubType: ExecutionEngine<?>
420
+ // SubType: ExecutionEngine<Basic ?>
421
421
pub fn create_execution_engine ( & self ) -> Result < ExecutionEngine , LLVMString > {
422
+ Target :: initialize_native ( & InitializationConfig :: default ( ) )
423
+ . map_err ( |mut err_string| {
424
+ err_string. push ( '\0' ) ;
425
+
426
+ LLVMString :: create ( err_string. as_ptr ( ) as * const i8 )
427
+ } ) ?;
428
+
422
429
let mut execution_engine = unsafe { zeroed ( ) } ;
423
430
let mut err_string = unsafe { zeroed ( ) } ;
424
431
let code = unsafe {
@@ -455,6 +462,13 @@ impl Module {
455
462
/// ```
456
463
// SubType: ExecutionEngine<Interpreter>
457
464
pub fn create_interpreter_execution_engine ( & self ) -> Result < ExecutionEngine , LLVMString > {
465
+ Target :: initialize_native ( & InitializationConfig :: default ( ) )
466
+ . map_err ( |mut err_string| {
467
+ err_string. push ( '\0' ) ;
468
+
469
+ LLVMString :: create ( err_string. as_ptr ( ) as * const i8 )
470
+ } ) ?;
471
+
458
472
let mut execution_engine = unsafe { zeroed ( ) } ;
459
473
let mut err_string = unsafe { zeroed ( ) } ;
460
474
@@ -493,6 +507,13 @@ impl Module {
493
507
/// ```
494
508
// SubType: ExecutionEngine<Jit>
495
509
pub fn create_jit_execution_engine ( & self , opt_level : OptimizationLevel ) -> Result < ExecutionEngine , LLVMString > {
510
+ Target :: initialize_native ( & InitializationConfig :: default ( ) )
511
+ . map_err ( |mut err_string| {
512
+ err_string. push ( '\0' ) ;
513
+
514
+ LLVMString :: create ( err_string. as_ptr ( ) as * const i8 )
515
+ } ) ?;
516
+
496
517
let mut execution_engine = unsafe { zeroed ( ) } ;
497
518
let mut err_string = unsafe { zeroed ( ) } ;
498
519
@@ -501,18 +522,6 @@ impl Module {
501
522
} ;
502
523
503
524
if code == 1 {
504
- // The module still seems "owned" in this error case, despite failing to create an EE. This would normally
505
- // end in a segfault on Module drop, however we're avoiding that by cloning the module and replacing the underlying pointer
506
- // REVIEW: Ensure this doesn't lead to unexpected behavior... If it does, the alternate strategy would be to change the fn
507
- // signature to take ownership of self and return it with good EE: (self, opt_level) -> Result<(Module, EE), LLVMString>
508
- let module = self . clone ( ) ;
509
-
510
- self . module . set ( module. module . get ( ) ) ;
511
-
512
- forget ( module) ;
513
-
514
- // REVIEW: Module still seems "owned" in the error case and may segfault on module drop. :/
515
- // Need to figure out if there's a way to prevent this.
516
525
return Err ( LLVMString :: new ( err_string) ) ;
517
526
}
518
527
0 commit comments