Last active
December 31, 2022 15:32
-
-
Save y21/3be1dee38f58d70fba04a7c94974c7fb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use llvm_sys::analysis::*; | |
use llvm_sys::core::*; | |
use llvm_sys::execution_engine::*; | |
use llvm_sys::prelude::*; | |
use llvm_sys::target::*; | |
use llvm_sys::*; | |
use std::ptr; | |
macro_rules! c { | |
($s:expr) => { | |
cstr::cstr!($s).as_ptr() | |
}; | |
} | |
pub unsafe fn init() { | |
LLVM_InitializeNativeTarget(); | |
LLVM_InitializeNativeAsmPrinter(); | |
LLVM_InitializeNativeAsmParser(); | |
LLVMLinkInMCJIT(); | |
} | |
unsafe fn create_and_run(module: LLVMModuleRef, exec: LLVMExecutionEngineRef) { | |
// Create and add function | |
let fun_ty = LLVMFunctionType(LLVMVoidType(), ptr::null_mut(), 0, 0); | |
let function = LLVMAddFunction(module, c!("jit"), fun_ty); | |
LLVMSetFunctionCallConv(function, LLVMCallConv::LLVMCCallConv as u32); | |
// Add some instructions | |
let builder = LLVMCreateBuilder(); | |
let bb = LLVMAppendBasicBlock(function, c!("entry")); | |
LLVMPositionBuilderAtEnd(builder, bb); | |
LLVMBuildRetVoid(builder); | |
// Verify & print for debugging | |
LLVMPrintModuleToFile(module, c!("out.ll"), ptr::null_mut()); | |
LLVMVerifyModule(module, LLVMVerifierFailureAction::LLVMAbortProcessAction, ptr::null_mut()); | |
// Trigger codegen, get function pointer, call | |
let mut length = 0; | |
let name = LLVMGetValueName2(function, &mut length); | |
let address = LLVMGetFunctionAddress(exec, name); | |
assert!(address != 0); | |
let fun = std::mem::transmute::<u64, extern "C" fn()>(address); | |
fun(); | |
println!("Done"); | |
} | |
fn main() { | |
unsafe { | |
init(); | |
// Create module & EE | |
let module = LLVMModuleCreateWithName(c!("test")); | |
let mut exec = ptr::null_mut(); | |
let mut err = ptr::null_mut(); | |
assert!(LLVMCreateExecutionEngineForModule(&mut exec, module, &mut err) == 0); | |
assert!(err.is_null()); | |
create_and_run(module, exec); | |
create_and_run(module, exec); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment