llvm_sys_wrapper/
engine.rs

1extern 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 { // error
28            let err_msg = unsafe { CString::from_raw(error).into_string().unwrap() };
29            Err(err_msg)
30
31        }else{           // ok
32            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 { // error
49            let err_msg = unsafe { CString::from_raw(error).into_string().unwrap() };
50            Err(err_msg)
51
52        }else{           // ok
53            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}