llvm_sys_wrapper/
module.rs1#![allow(dead_code)]
2
3extern crate llvm_sys;
4
5use self::llvm_sys::core::*;
6use self::llvm_sys::prelude::*;
7use self::llvm_sys::analysis::{LLVMVerifyModule, LLVMVerifierFailureAction};
8use cstring_manager::CStringManager;
9use std::ffi::CString;
10use std::os::raw::c_char;
11use function;
12use engine::Engine;
13
14#[derive(Debug)]
15pub struct Module {
16 llvm_module: LLVMModuleRef
17}
18
19impl Module {
20 pub fn new(name: &str) -> Module {
21 let mod_name_ptr = CStringManager::new_cstring_as_ptr(name);
22 let module = unsafe { LLVMModuleCreateWithName(mod_name_ptr) };
23 Module {
24 llvm_module: module
25 }
26 }
27
28 pub fn new_in_context(name: &str, context: LLVMContextRef) -> Module {
29 let mod_name_ptr = CStringManager::new_cstring_as_ptr(name);
30 let module = unsafe { LLVMModuleCreateWithNameInContext(mod_name_ptr, context) };
31 Module {
32 llvm_module: module
33 }
34 }
35
36 pub fn as_ref(&self) -> LLVMModuleRef {
37 self.llvm_module
38 }
39
40 pub fn add_function(&self, name: &str, function_type: LLVMTypeRef) -> function::Function {
41 function::Function::new(self.llvm_module, name, function_type)
42 }
43
44 #[inline]
45 pub fn named_function(&self, name: &str) -> function::Function {
46 let func_name_ptr = CStringManager::new_cstring_as_ptr(name);
47 let named_function = unsafe { LLVMGetNamedFunction(self.llvm_module, func_name_ptr) };
48 function::Function::from_ptr(named_function)
49 }
50
51 pub fn get_or_add_function(&self, name: &str, function_type: LLVMTypeRef) -> function::Function {
52 let func_name_ptr = CStringManager::new_cstring_as_ptr(name);
53 let named_function = unsafe { LLVMGetNamedFunction(self.llvm_module, func_name_ptr) };
54 if named_function.is_null() {
55 function::Function::new(self.llvm_module, name, function_type)
56 }else{
57 function::Function::from_ptr(named_function)
58 }
59 }
60
61 pub fn verify(&self) -> Result<(), String> {
62 let mut error: *mut c_char = 0 as *mut c_char;
63 let ok = unsafe {
64 let buf: *mut *mut c_char = &mut error;
65 LLVMVerifyModule(self.llvm_module, LLVMVerifierFailureAction::LLVMReturnStatusAction, buf)
66 };
67 if ok == 1 { let err_msg = unsafe { CString::from_raw(error).into_string().unwrap() };
69 Err(err_msg)
70 }else{ Ok(())
72 }
73 }
74
75 #[inline]
76 pub fn dump(&self){
77 unsafe { LLVMDumpModule(self.llvm_module) }
78 }
79
80 pub fn print_module_to_string(&self) -> String {
81 let ptr = unsafe { LLVMPrintModuleToString(self.llvm_module) };
82 let string = unsafe { CString::from_raw(ptr).into_string().unwrap() };
83 unsafe { LLVMDisposeMessage(ptr); }
84 string
85 }
86
87 pub fn print_module_to_file(&self, filename: &str) -> Result<(), String> {
88 let fname_ptr = CStringManager::new_cstring_as_ptr(filename);
89 let mut error: *mut c_char = 0 as *mut c_char;
90 let ok = unsafe {
91 let buf: *mut *mut c_char = &mut error;
92 LLVMPrintModuleToFile(self.llvm_module, fname_ptr, buf)
93 };
94 if ok == 1 { let err_msg = unsafe { CString::from_raw(error).into_string().unwrap() };
96 unsafe { LLVMDisposeMessage(error) }
97 Err(err_msg)
98 }else{ Ok(())
100 }
101 }
102
103 #[inline]
104 pub fn create_interpreter(&self) -> Result<Engine, String> {
105 Engine::create_interpreter(self.as_ref())
106 }
107
108 #[inline]
109 pub fn create_jit_engine(&self) -> Result<Engine, String> {
110 Engine::create_jit_engine(self.as_ref())
111 }
112}
113
114impl Drop for Module {
115 #[inline]
116 fn drop(&mut self) {
117 unsafe { LLVMDisposeModule(self.llvm_module) }
118 }
119}