Added ExecutionEngine::get_function_address
@@ -305,14 +305,34 @@ impl<'ctx> ExecutionEngine<'ctx> {
return Err(FunctionLookupError::JITNotEnabled);
}
+ let address = self.get_function_address(fn_name)?;
+
+ assert_eq!(size_of::<F>(), size_of::<usize>(),
+ "The type `F` must have the same size as a function pointer");
+
+ let execution_engine = self.execution_engine.as_ref().expect(EE_INNER_PANIC);
+
+ Ok(JitFunction {
+ _execution_engine: execution_engine.clone(),
+ inner: transmute_copy(&address),
+ })
+ }
+
+ /// Attempts to look up a function's address by its name. May return Err if the function cannot be
+ /// found or some other unknown error has occurred.
+ ///
+ /// It is recommended to use `get_function` instead of this method when intending to call the function
+ /// pointer so that you don't have to do error-prone transmutes yourself.
+ pub fn get_function_address(&self, fn_name: &str) -> Result<usize, FunctionLookupError> {
// LLVMGetFunctionAddress segfaults in llvm 5.0 -> 8.0 when fn_name doesn't exist. This is a workaround
// to see if it exists and avoid the segfault when it doesn't
#[cfg(any(feature = "llvm5-0", feature = "llvm6-0", feature = "llvm7-0", feature = "llvm8-0"))]
self.get_function_value(fn_name)?;
let c_string = CString::new(fn_name).expect("Conversion to CString failed unexpectedly");
-
- let address = LLVMGetFunctionAddress(self.execution_engine_inner(), c_string.as_ptr());
+ let address = unsafe {
+ LLVMGetFunctionAddress(self.execution_engine_inner(), c_string.as_ptr())
+ };
// REVIEW: Can also return 0 if no targets are initialized.
// One option might be to set a (thread local?) global to true if any at all of the targets have been
@@ -322,15 +342,7 @@ impl<'ctx> ExecutionEngine<'ctx> {
return Err(FunctionLookupError::FunctionNotFound);
}
- assert_eq!(size_of::<F>(), size_of::<usize>(),
- "The type `F` must have the same size as a function pointer");
-
- let execution_engine = self.execution_engine.as_ref().expect(EE_INNER_PANIC);
-
- Ok(JitFunction {
- _execution_engine: execution_engine.clone(),
- inner: transmute_copy(&address),
- })
+ Ok(address as usize)
}
// REVIEW: Not sure if an EE's target data can change.. if so we might want to update the value
