Expand description
Safe(r) wrappers around llvm_sys::lljit
§Example
use pliron_llvm::llvm_sys::target::initialize_native;
use pliron_llvm::llvm_sys::core::{LLVMContext, LLVMModule, LLVMMemoryBuffer};
use pliron_llvm::llvm_sys::lljit::{LLVMLLJIT, JITSymbolGenericFlags};
fn main() -> Result<(), String> {
initialize_native()?;
let context = LLVMContext::default();
fn my_rust_adder(a: i32, b: i32) -> i32 {
a + b
}
let ir = r#"
declare i32 @my_rust_adder(i32, i32)
define i32 @add(i32 %a, i32 %b) {
%sum = call i32 @my_rust_adder(i32 %a, i32 %b)
ret i32 %sum
}"#;
let ir_mb = LLVMMemoryBuffer::from_str(ir, "test_buffer");
let module = LLVMModule::from_ir_in_memory_buffer(&context, ir_mb)?;
let jit = LLVMLLJIT::new_with_default_builder()?;
jit.add_module(module)?;
// Add the Rust function as a symbol mapping
let rust_adder_addr = my_rust_adder as *const () as u64;
jit.add_symbol_mapping
("my_rust_adder", rust_adder_addr,
JITSymbolGenericFlags::JITSymbolGenericFlagsCallable
| JITSymbolGenericFlags::JITSymbolGenericFlagsExported)?;
// Get symbol address for 'add' in the LLVM module
let symbol_addr = jit.lookup_symbol("add")?;
assert!(symbol_addr != 0);
let adder = unsafe { std::mem::transmute::<u64, fn(i32, i32) -> i32>(symbol_addr) };
assert_eq!(adder(2, 3), 5);
Ok(())
}