2019-02-26 02:07:22 +00:00
|
|
|
use crate::intrinsics::Intrinsics;
|
|
|
|
use dlopen::symbor::Library;
|
2019-02-16 00:02:20 +00:00
|
|
|
use inkwell::{
|
|
|
|
module::Module,
|
2019-02-26 02:07:22 +00:00
|
|
|
targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine},
|
|
|
|
OptimizationLevel,
|
2019-02-16 00:02:20 +00:00
|
|
|
};
|
2019-02-26 02:07:22 +00:00
|
|
|
use std::{io::Write, ptr::NonNull};
|
|
|
|
use tempfile::NamedTempFile;
|
2019-02-16 00:02:20 +00:00
|
|
|
use wasmer_runtime_core::{
|
2019-02-26 02:07:22 +00:00
|
|
|
backend::FuncResolver, module::ModuleInner, structures::TypedIndex, types::LocalFuncIndex, vm,
|
2019-02-16 00:02:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
pub struct LLVMBackend {
|
2019-02-26 02:07:22 +00:00
|
|
|
tempfile: NamedTempFile,
|
|
|
|
library: Library,
|
2019-02-16 00:02:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl LLVMBackend {
|
|
|
|
pub fn new(module: Module, intrinsics: Intrinsics) -> Self {
|
2019-02-26 02:07:22 +00:00
|
|
|
Target::initialize_x86(&InitializationConfig {
|
|
|
|
asm_parser: true,
|
|
|
|
asm_printer: true,
|
|
|
|
base: true,
|
|
|
|
disassembler: true,
|
|
|
|
info: true,
|
|
|
|
machine_code: true,
|
|
|
|
});
|
|
|
|
let triple = TargetMachine::get_default_triple().to_string();
|
|
|
|
let target = Target::from_triple(&triple).unwrap();
|
|
|
|
let target_machine = target
|
|
|
|
.create_target_machine(
|
|
|
|
&triple,
|
|
|
|
&TargetMachine::get_host_cpu_name().to_string(),
|
|
|
|
&TargetMachine::get_host_cpu_features().to_string(),
|
|
|
|
OptimizationLevel::Default,
|
|
|
|
RelocMode::PIC,
|
|
|
|
CodeModel::Default,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let memory_buffer = target_machine
|
|
|
|
.write_to_memory_buffer(&module, FileType::Object)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let mut tempfile = NamedTempFile::new().unwrap();
|
|
|
|
tempfile.write_all(memory_buffer.as_slice()).unwrap();
|
|
|
|
tempfile.flush().unwrap();
|
|
|
|
|
|
|
|
let library = Library::open(tempfile.path()).unwrap();
|
|
|
|
|
|
|
|
Self { tempfile, library }
|
2019-02-16 00:02:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FuncResolver for LLVMBackend {
|
2019-02-26 02:07:22 +00:00
|
|
|
fn get(
|
|
|
|
&self,
|
|
|
|
module: &ModuleInner,
|
|
|
|
local_func_index: LocalFuncIndex,
|
|
|
|
) -> Option<NonNull<vm::Func>> {
|
2019-02-16 00:02:20 +00:00
|
|
|
let index = module.info.imported_functions.len() + local_func_index.index();
|
2019-02-26 02:07:22 +00:00
|
|
|
let name = if cfg!(macos) {
|
|
|
|
format!("_fn{}", index)
|
|
|
|
} else {
|
|
|
|
format!("fn{}", index)
|
|
|
|
};
|
|
|
|
|
2019-02-16 00:02:20 +00:00
|
|
|
unsafe {
|
2019-02-26 02:07:22 +00:00
|
|
|
self.library
|
|
|
|
.symbol::<NonNull<vm::Func>>(&name)
|
|
|
|
.ok()
|
|
|
|
.map(|symbol| *symbol)
|
2019-02-16 00:02:20 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-26 02:07:22 +00:00
|
|
|
}
|