diff --git a/README.md b/README.md index faf4b8181fb14..60b238bfb7fde 100644 --- a/README.md +++ b/README.md @@ -64,12 +64,7 @@ use std::error::Error; /// do `unsafe` operations internally. type SumFunc = unsafe extern "C" fn(u64, u64, u64) -> u64; -fn main() { - Target::initialize_native(&InitializationConfig::default()).unwrap(); - run().unwrap(); -} - -fn run() -> Result<(), Box> { +fn main() -> Result<(), Box> { let context = Context::create(); let module = context.create_module("sum"); let builder = context.create_builder(); diff --git a/examples/jit.rs b/examples/jit.rs index f39f8515bbf87..45f69e1585c2e 100644 --- a/examples/jit.rs +++ b/examples/jit.rs @@ -40,7 +40,7 @@ fn jit_compile_sum( unsafe { execution_engine.get_function("sum").ok() } } -fn run() -> Result<(), Box> { +fn main() -> Result<(), Box> { let context = Context::create(); let module = context.create_module("sum"); let builder = context.create_builder(); @@ -60,8 +60,3 @@ fn run() -> Result<(), Box> { Ok(()) } - -fn main() { - Target::initialize_native(&InitializationConfig::default()).unwrap(); - run().unwrap(); -} diff --git a/examples/kaleidoscope/main.rs b/examples/kaleidoscope/main.rs index 44fb108114cca..94dae4fc409d5 100644 --- a/examples/kaleidoscope/main.rs +++ b/examples/kaleidoscope/main.rs @@ -26,7 +26,6 @@ use self::inkwell::builder::Builder; use self::inkwell::context::Context; use self::inkwell::module::Module; use self::inkwell::passes::PassManager; -use self::inkwell::targets::{InitializationConfig, Target}; use self::inkwell::types::BasicTypeEnum; use self::inkwell::values::{BasicValueEnum, FloatValue, FunctionValue, PointerValue}; use self::inkwell::{OptimizationLevel, FloatPredicate}; @@ -1218,8 +1217,6 @@ pub fn main() { } } - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target."); - let context = Context::create(); let module = context.create_module("repl"); let builder = context.create_builder(); @@ -1255,7 +1252,7 @@ pub fn main() { } // Build precedence map - let mut prec = HashMap::with_capacity(4); + let mut prec = HashMap::with_capacity(6); prec.insert('=', 2); prec.insert('<', 10); diff --git a/src/module.rs b/src/module.rs index 1dafd7e92fa09..0a8baa5cc3774 100644 --- a/src/module.rs +++ b/src/module.rs @@ -34,9 +34,9 @@ use data_layout::DataLayout; use execution_engine::ExecutionEngine; use memory_buffer::MemoryBuffer; use support::LLVMString; -use targets::Target; +use targets::{Target, InitializationConfig}; use types::{AsTypeRef, BasicType, FunctionType, BasicTypeEnum}; -use values::{AsValueRef, BasicValue, BasicValueEnum, FunctionValue, GlobalValue, MetadataValue}; +use values::{AsValueRef, BasicValue, FunctionValue, GlobalValue, MetadataValue}; enum_rename!{ /// This enum defines how to link a global variable or function in a module. The variant documenation is @@ -417,8 +417,15 @@ impl Module { /// /// assert_eq!(module.get_context(), context); /// ``` - // SubType: ExecutionEngine + // SubType: ExecutionEngine pub fn create_execution_engine(&self) -> Result { + Target::initialize_native(&InitializationConfig::default()) + .map_err(|mut err_string| { + err_string.push('\0'); + + LLVMString::create(err_string.as_ptr() as *const i8) + })?; + let mut execution_engine = unsafe { zeroed() }; let mut err_string = unsafe { zeroed() }; let code = unsafe { @@ -455,6 +462,13 @@ impl Module { /// ``` // SubType: ExecutionEngine pub fn create_interpreter_execution_engine(&self) -> Result { + Target::initialize_native(&InitializationConfig::default()) + .map_err(|mut err_string| { + err_string.push('\0'); + + LLVMString::create(err_string.as_ptr() as *const i8) + })?; + let mut execution_engine = unsafe { zeroed() }; let mut err_string = unsafe { zeroed() }; @@ -493,6 +507,13 @@ impl Module { /// ``` // SubType: ExecutionEngine pub fn create_jit_execution_engine(&self, opt_level: OptimizationLevel) -> Result { + Target::initialize_native(&InitializationConfig::default()) + .map_err(|mut err_string| { + err_string.push('\0'); + + LLVMString::create(err_string.as_ptr() as *const i8) + })?; + let mut execution_engine = unsafe { zeroed() }; let mut err_string = unsafe { zeroed() }; @@ -501,18 +522,6 @@ impl Module { }; if code == 1 { - // The module still seems "owned" in this error case, despite failing to create an EE. This would normally - // end in a segfault on Module drop, however we're avoiding that by cloning the module and replacing the underlying pointer - // REVIEW: Ensure this doesn't lead to unexpected behavior... If it does, the alternate strategy would be to change the fn - // signature to take ownership of self and return it with good EE: (self, opt_level) -> Result<(Module, EE), LLVMString> - let module = self.clone(); - - self.module.set(module.module.get()); - - forget(module); - - // REVIEW: Module still seems "owned" in the error case and may segfault on module drop. :/ - // Need to figure out if there's a way to prevent this. return Err(LLVMString::new(err_string)); } diff --git a/src/support/mod.rs b/src/support/mod.rs index 709f0c0f94bc3..4a90f31ddb9cb 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -35,8 +35,7 @@ impl LLVMString { /// Don't use this if it's not necessary. You likely need to allocate /// a CString as input and then LLVM will likely allocate their own string /// anyway. - #[allow(dead_code)] - fn create(bytes: *const c_char) -> LLVMString { + pub(crate) fn create(bytes: *const c_char) -> LLVMString { let ptr = unsafe { LLVMCreateMessage(bytes) }; diff --git a/src/types/enums.rs b/src/types/enums.rs index 6ecc5f03495c5..e2e1274adbe8e 100644 --- a/src/types/enums.rs +++ b/src/types/enums.rs @@ -64,6 +64,7 @@ enum_type_set! { ArrayType, /// A floating point type. FloatType, + // An integer type. IntType, /// A pointer type. PointerType, diff --git a/tests/all/test_builder.rs b/tests/all/test_builder.rs index a30d7606e4c2a..2b19e5088ddcf 100644 --- a/tests/all/test_builder.rs +++ b/tests/all/test_builder.rs @@ -46,8 +46,6 @@ fn test_build_call() { #[test] fn test_null_checked_ptr_ops() { - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - let context = Context::create(); let module = context.create_module("unsafe"); let builder = context.create_builder(); @@ -152,8 +150,6 @@ fn test_null_checked_ptr_ops() { #[test] fn test_binary_ops() { - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - let context = Context::create(); let module = context.create_module("unsafe"); let builder = context.create_builder(); @@ -238,8 +234,6 @@ fn test_binary_ops() { #[test] fn test_switch() { - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - let context = Context::create(); let module = context.create_module("unsafe"); let builder = context.create_builder(); @@ -298,8 +292,6 @@ fn test_switch() { #[test] fn test_bit_shifts() { - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - let context = Context::create(); let module = context.create_module("unsafe"); let builder = context.create_builder(); diff --git a/tests/all/test_execution_engine.rs b/tests/all/test_execution_engine.rs index 11caeae5fbb88..36ef5a68ea8eb 100644 --- a/tests/all/test_execution_engine.rs +++ b/tests/all/test_execution_engine.rs @@ -123,8 +123,6 @@ fn test_execution_engine() { let context = Context::create(); let module = context.create_module("main_module"); - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - assert!(module.create_execution_engine().is_ok()); } @@ -133,16 +131,12 @@ fn test_interpreter_execution_engine() { let context = Context::create(); let module = context.create_module("main_module"); - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - assert!(module.create_interpreter_execution_engine().is_ok()); } #[test] fn test_add_remove_module() { - Target::initialize_all(&InitializationConfig::default()); - let context = Context::create(); let module = context.create_module("test"); let ee = module.create_jit_execution_engine(OptimizationLevel::default()).unwrap(); diff --git a/tests/all/test_module.rs b/tests/all/test_module.rs index 6230e26401839..ebcb05917ccbb 100644 --- a/tests/all/test_module.rs +++ b/tests/all/test_module.rs @@ -185,8 +185,6 @@ fn test_module_no_double_free() { #[test] fn test_owned_module_dropped_ee_and_context() { - Target::initialize_native(&InitializationConfig::default()).unwrap(); - let _module = { let context = Context::create(); let module = context.create_module("my_mod"); @@ -388,8 +386,6 @@ fn test_linking_modules() { // fn_val2 is no longer the same instance of f2 assert_ne!(module.get_function("f2"), Some(fn_val2)); - Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target"); - let _execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).expect("Could not create Execution Engine"); let module4 = context.create_module("mod4");