mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-23 13:41:32 +00:00
Update llvm backend to new backend abstraction
This commit is contained in:
@ -18,15 +18,12 @@ use std::{
|
|||||||
sync::Once,
|
sync::Once,
|
||||||
};
|
};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
backend::{RunnableModule, UserTrapper},
|
||||||
error::{RuntimeError, RuntimeResult},
|
module::ModuleInfo,
|
||||||
export::Context,
|
|
||||||
module::{ModuleInfo, ModuleInner},
|
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
typed_func::{Wasm, WasmTrapInfo},
|
typed_func::{Wasm, WasmTrapInfo},
|
||||||
types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value},
|
types::{LocalFuncIndex, SigIndex},
|
||||||
vm::{self, ImportBacking},
|
vm, vmcalls,
|
||||||
vmcalls,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -216,7 +213,7 @@ pub struct LLVMBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LLVMBackend {
|
impl LLVMBackend {
|
||||||
pub fn new(module: Module, _intrinsics: Intrinsics) -> (Self, LLVMProtectedCaller) {
|
pub fn new(module: Module, _intrinsics: Intrinsics) -> Self {
|
||||||
Target::initialize_x86(&InitializationConfig {
|
Target::initialize_x86(&InitializationConfig {
|
||||||
asm_parser: true,
|
asm_parser: true,
|
||||||
asm_printer: true,
|
asm_printer: true,
|
||||||
@ -265,16 +262,21 @@ impl LLVMBackend {
|
|||||||
panic!("failed to load object")
|
panic!("failed to load object")
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
|
||||||
Self {
|
Self {
|
||||||
module,
|
module,
|
||||||
memory_buffer,
|
memory_buffer,
|
||||||
},
|
}
|
||||||
LLVMProtectedCaller { module },
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_func(
|
impl Drop for LLVMBackend {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { module_delete(self.module) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RunnableModule for LLVMBackend {
|
||||||
|
fn get_func(
|
||||||
&self,
|
&self,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
local_func_index: LocalFuncIndex,
|
local_func_index: LocalFuncIndex,
|
||||||
@ -291,126 +293,8 @@ impl LLVMBackend {
|
|||||||
|
|
||||||
NonNull::new(ptr as _)
|
NonNull::new(ptr as _)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for LLVMBackend {
|
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { module_delete(self.module) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FuncResolver for LLVMBackend {
|
|
||||||
fn get(
|
|
||||||
&self,
|
|
||||||
module: &ModuleInner,
|
|
||||||
local_func_index: LocalFuncIndex,
|
|
||||||
) -> Option<NonNull<vm::Func>> {
|
|
||||||
self.get_func(&module.info, local_func_index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Placeholder;
|
|
||||||
|
|
||||||
unsafe impl Send for LLVMProtectedCaller {}
|
|
||||||
unsafe impl Sync for LLVMProtectedCaller {}
|
|
||||||
|
|
||||||
pub struct LLVMProtectedCaller {
|
|
||||||
module: *mut LLVMModule,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProtectedCaller for LLVMProtectedCaller {
|
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
module: &ModuleInner,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
params: &[Value],
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
let (func_ptr, ctx, signature, sig_index) =
|
|
||||||
get_func_from_index(&module, import_backing, func_index);
|
|
||||||
|
|
||||||
let vmctx_ptr = match ctx {
|
|
||||||
Context::External(external_vmctx) => external_vmctx,
|
|
||||||
Context::Internal => vmctx,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
signature.returns().len() <= 1,
|
|
||||||
"multi-value returns not yet supported"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
signature.check_param_value_types(params),
|
|
||||||
"incorrect signature"
|
|
||||||
);
|
|
||||||
|
|
||||||
let param_vec: Vec<u64> = params
|
|
||||||
.iter()
|
|
||||||
.map(|val| match val {
|
|
||||||
Value::I32(x) => *x as u64,
|
|
||||||
Value::I64(x) => *x as u64,
|
|
||||||
Value::F32(x) => x.to_bits() as u64,
|
|
||||||
Value::F64(x) => x.to_bits(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut return_vec = vec![0; signature.returns().len()];
|
|
||||||
|
|
||||||
let trampoline: unsafe extern "C" fn(
|
|
||||||
*mut vm::Ctx,
|
|
||||||
NonNull<vm::Func>,
|
|
||||||
*const u64,
|
|
||||||
*mut u64,
|
|
||||||
) = unsafe {
|
|
||||||
let name = if cfg!(target_os = "macos") {
|
|
||||||
format!("_trmp{}", sig_index.index())
|
|
||||||
} else {
|
|
||||||
format!("trmp{}", sig_index.index())
|
|
||||||
};
|
|
||||||
|
|
||||||
let c_str = CString::new(name).unwrap();
|
|
||||||
let symbol = get_func_symbol(self.module, c_str.as_ptr());
|
|
||||||
assert!(!symbol.is_null());
|
|
||||||
|
|
||||||
mem::transmute(symbol)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut trap_out = WasmTrapInfo::Unknown;
|
|
||||||
|
|
||||||
// Here we go.
|
|
||||||
let success = unsafe {
|
|
||||||
invoke_trampoline(
|
|
||||||
trampoline,
|
|
||||||
vmctx_ptr,
|
|
||||||
func_ptr,
|
|
||||||
param_vec.as_ptr(),
|
|
||||||
return_vec.as_mut_ptr(),
|
|
||||||
&mut trap_out,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if success {
|
|
||||||
Ok(return_vec
|
|
||||||
.iter()
|
|
||||||
.zip(signature.returns().iter())
|
|
||||||
.map(|(&x, ty)| match ty {
|
|
||||||
Type::I32 => Value::I32(x as i32),
|
|
||||||
Type::I64 => Value::I64(x as i64),
|
|
||||||
Type::F32 => Value::F32(f32::from_bits(x as u32)),
|
|
||||||
Type::F64 => Value::F64(f64::from_bits(x as u64)),
|
|
||||||
})
|
|
||||||
.collect())
|
|
||||||
} else {
|
|
||||||
Err(RuntimeError::Trap {
|
|
||||||
msg: trap_out.to_string().into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_wasm_trampoline(&self, _module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
|
||||||
let trampoline: unsafe extern "C" fn(
|
let trampoline: unsafe extern "C" fn(
|
||||||
*mut vm::Ctx,
|
*mut vm::Ctx,
|
||||||
NonNull<vm::Func>,
|
NonNull<vm::Func>,
|
||||||
@ -438,46 +322,14 @@ impl ProtectedCaller for LLVMProtectedCaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Placeholder;
|
||||||
|
|
||||||
impl UserTrapper for Placeholder {
|
impl UserTrapper for Placeholder {
|
||||||
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
|
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
|
||||||
throw_any(Box::leak(data))
|
throw_any(Box::leak(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_func_from_index<'a>(
|
|
||||||
module: &'a ModuleInner,
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
) -> (NonNull<vm::Func>, Context, &'a FuncSig, SigIndex) {
|
|
||||||
let sig_index = *module
|
|
||||||
.info
|
|
||||||
.func_assoc
|
|
||||||
.get(func_index)
|
|
||||||
.expect("broken invariant, incorrect func index");
|
|
||||||
|
|
||||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
|
||||||
LocalOrImport::Local(local_func_index) => (
|
|
||||||
module
|
|
||||||
.func_resolver
|
|
||||||
.get(&module, local_func_index)
|
|
||||||
.expect("broken invariant, func resolver not synced with module.exports")
|
|
||||||
.cast(),
|
|
||||||
Context::Internal,
|
|
||||||
),
|
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
|
||||||
let imported_func = import_backing.imported_func(imported_func_index);
|
|
||||||
(
|
|
||||||
NonNull::new(imported_func.func as *mut _).unwrap(),
|
|
||||||
Context::External(imported_func.vmctx),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let signature = &module.info.signatures[sig_index];
|
|
||||||
|
|
||||||
(func_ptr, ctx, signature, sig_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "disasm")]
|
#[cfg(feature = "disasm")]
|
||||||
unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) {
|
unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) {
|
||||||
use capstone::arch::BuildsCapstone;
|
use capstone::arch::BuildsCapstone;
|
||||||
|
@ -38,7 +38,7 @@ impl Compiler for LLVMCompiler {
|
|||||||
let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap();
|
let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap();
|
||||||
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
||||||
|
|
||||||
let (backend, protected_caller) = backend::LLVMBackend::new(module, intrinsics);
|
let backend = backend::LLVMBackend::new(module, intrinsics);
|
||||||
|
|
||||||
// Create placeholder values here.
|
// Create placeholder values here.
|
||||||
let cache_gen = {
|
let cache_gen = {
|
||||||
@ -61,8 +61,7 @@ impl Compiler for LLVMCompiler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
func_resolver: Box::new(backend),
|
runnable_module: Box::new(backend),
|
||||||
protected_caller: Box::new(protected_caller),
|
|
||||||
cache_gen,
|
cache_gen,
|
||||||
|
|
||||||
info,
|
info,
|
||||||
|
Reference in New Issue
Block a user