llvm_sys_wrapper/
engine.rs1extern crate llvm_sys;
2extern crate libc;
3
4use self::llvm_sys::prelude::*;
5use self::llvm_sys::execution_engine::*;
6use std::ffi::CString;
7use std::os::raw::{c_char, c_ulonglong, c_uint};
8use self::libc::c_void;
9use LLVM::Type;
10
11#[derive(Debug)]
12pub struct Engine {
13 llvm_execute_engine: LLVMExecutionEngineRef
14}
15
16impl Engine {
17 pub fn create_interpreter(module: LLVMModuleRef) -> Result<Engine, String> {
18 let mut error: *mut c_char = 0 as *mut c_char;
19 let mut engine: LLVMExecutionEngineRef = 0 as LLVMExecutionEngineRef;
20 let result = unsafe {
21 let buf: *mut *mut c_char = &mut error;
22 let engine_ref: *mut LLVMExecutionEngineRef = &mut engine;
23 LLVMLinkInInterpreter();
24 LLVMCreateInterpreterForModule(engine_ref, module, buf)
25 };
26
27 if result == 1 { let err_msg = unsafe { CString::from_raw(error).into_string().unwrap() };
29 Err(err_msg)
30
31 }else{ Ok(Engine {
33 llvm_execute_engine: engine
34 })
35 }
36 }
37
38 pub fn create_jit_engine(module: LLVMModuleRef) -> Result<Engine, String> {
39 let mut error: *mut c_char = 0 as *mut c_char;
40 let mut engine: LLVMExecutionEngineRef = 0 as LLVMExecutionEngineRef;
41 let result = unsafe {
42 let buf: *mut *mut c_char = &mut error;
43 let engine_ref: *mut LLVMExecutionEngineRef = &mut engine;
44 LLVMLinkInMCJIT();
45 LLVMCreateMCJITCompilerForModule(engine_ref, module, 0 as *mut LLVMMCJITCompilerOptions, 0, buf)
46 };
47
48 if result == 1 { let err_msg = unsafe { CString::from_raw(error).into_string().unwrap() };
50 Err(err_msg)
51
52 }else{ Ok(Engine {
54 llvm_execute_engine: engine
55 })
56 }
57 }
58
59 pub fn as_ref(&self) -> LLVMExecutionEngineRef {
60 self.llvm_execute_engine
61 }
62
63 pub fn run_function(&self, function: LLVMValueRef, args: &mut [LLVMGenericValueRef]) -> FuncallResult {
64 let func_result = unsafe { LLVMRunFunction(self.llvm_execute_engine, function, args.len() as u32, args.as_mut_ptr()) };
65 FuncallResult::new(func_result)
66 }
67}
68
69pub struct FuncallResult {
70 value: LLVMGenericValueRef
71}
72
73impl FuncallResult {
74 pub fn new(val: LLVMGenericValueRef) -> FuncallResult {
75 FuncallResult {
76 value: val
77 }
78 }
79
80 pub fn as_ref(&self) -> LLVMGenericValueRef {
81 self.value
82 }
83
84 #[inline]
85 pub fn to_int(&self) -> c_ulonglong {
86 unsafe { LLVMGenericValueToInt(self.value, 0) }
87 }
88
89 #[inline]
90 pub fn int_width(&self) -> c_uint {
91 unsafe { LLVMGenericValueIntWidth(self.value) }
92 }
93
94 #[inline]
95 pub fn to_ptr(&self) -> *mut c_void {
96 unsafe { LLVMGenericValueToPointer(self.value) }
97 }
98
99 #[inline]
100 pub fn to_float(&self) -> f32 {
101 unsafe { LLVMGenericValueToFloat(Type::Float(), self.value) as f32 }
102 }
103
104 #[inline]
105 pub fn to_double(&self) -> f64 {
106 unsafe { LLVMGenericValueToFloat(Type::Double(), self.value) }
107 }
108}