mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-29 18:01:19 +00:00
Update singlepass backend to new backend abstraction
This commit is contained in:
parent
75cc65a8c5
commit
4e17ff8571
@ -1,15 +1,15 @@
|
|||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{FuncResolver, ProtectedCaller},
|
backend::RunnableModule,
|
||||||
module::ModuleInfo,
|
module::ModuleInfo,
|
||||||
structures::Map,
|
structures::Map,
|
||||||
types::{FuncIndex, FuncSig, SigIndex},
|
types::{FuncIndex, FuncSig, SigIndex},
|
||||||
};
|
};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
|
|
||||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, PC: ProtectedCaller, FR: FuncResolver> {
|
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, RM: RunnableModule> {
|
||||||
fn check_precondition(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
fn check_precondition(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
||||||
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
||||||
fn finalize(self, module_info: &ModuleInfo) -> Result<(PC, FR), CodegenError>;
|
fn finalize(self, module_info: &ModuleInfo) -> Result<RM, CodegenError>;
|
||||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError>;
|
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError>;
|
||||||
fn feed_function_signatures(
|
fn feed_function_signatures(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -11,17 +11,16 @@ use smallvec::SmallVec;
|
|||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::{any::Any, collections::HashMap, sync::Arc};
|
use std::{any::Any, collections::HashMap, sync::Arc};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
backend::{RunnableModule, UserTrapper},
|
||||||
error::RuntimeResult,
|
|
||||||
memory::MemoryType,
|
memory::MemoryType,
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::ModuleInfo,
|
||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
typed_func::Wasm,
|
typed_func::Wasm,
|
||||||
types::{
|
types::{
|
||||||
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
||||||
TableIndex, Type, Value,
|
TableIndex, Type,
|
||||||
},
|
},
|
||||||
vm::{self, ImportBacking, LocalGlobal, LocalMemory, LocalTable},
|
vm::{self, LocalGlobal, LocalMemory, LocalTable},
|
||||||
vmcalls,
|
vmcalls,
|
||||||
};
|
};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
@ -132,7 +131,6 @@ pub struct X64FunctionCode {
|
|||||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||||
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
||||||
|
|
||||||
begin_offset: AssemblyOffset,
|
|
||||||
assembler: Option<Assembler>,
|
assembler: Option<Assembler>,
|
||||||
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
|
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
|
||||||
br_table_data: Option<Vec<Vec<usize>>>,
|
br_table_data: Option<Vec<Vec<usize>>>,
|
||||||
@ -154,7 +152,9 @@ unsafe impl Send for FuncPtr {}
|
|||||||
unsafe impl Sync for FuncPtr {}
|
unsafe impl Sync for FuncPtr {}
|
||||||
|
|
||||||
pub struct X64ExecutionContext {
|
pub struct X64ExecutionContext {
|
||||||
|
#[allow(dead_code)]
|
||||||
code: ExecutableBuffer,
|
code: ExecutableBuffer,
|
||||||
|
#[allow(dead_code)]
|
||||||
functions: Vec<X64FunctionCode>,
|
functions: Vec<X64FunctionCode>,
|
||||||
function_pointers: Vec<FuncPtr>,
|
function_pointers: Vec<FuncPtr>,
|
||||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||||
@ -162,10 +162,6 @@ pub struct X64ExecutionContext {
|
|||||||
func_import_count: usize,
|
func_import_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct X64RuntimeResolver {
|
|
||||||
local_function_pointers: Vec<FuncPtr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ControlFrame {
|
pub struct ControlFrame {
|
||||||
pub label: DynamicLabel,
|
pub label: DynamicLabel,
|
||||||
@ -182,86 +178,33 @@ pub enum IfElseState {
|
|||||||
Else,
|
Else,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl X64ExecutionContext {
|
impl RunnableModule for X64ExecutionContext {
|
||||||
fn get_runtime_resolver(
|
fn get_func(
|
||||||
&self,
|
&self,
|
||||||
_module_info: &ModuleInfo,
|
_: &ModuleInfo,
|
||||||
) -> Result<X64RuntimeResolver, CodegenError> {
|
local_func_index: LocalFuncIndex,
|
||||||
Ok(X64RuntimeResolver {
|
|
||||||
local_function_pointers: self.function_pointers[self.func_import_count..].to_vec(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FuncResolver for X64RuntimeResolver {
|
|
||||||
fn get(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_local_func_index: LocalFuncIndex,
|
|
||||||
) -> Option<NonNull<vm::Func>> {
|
) -> Option<NonNull<vm::Func>> {
|
||||||
NonNull::new(
|
self.function_pointers[self.func_import_count..]
|
||||||
self.local_function_pointers[_local_func_index.index() as usize].0 as *mut vm::Func,
|
.get(local_func_index.index())
|
||||||
)
|
.and_then(|ptr| NonNull::new(ptr.0 as *mut vm::Func))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProtectedCaller for X64ExecutionContext {
|
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_func_index: FuncIndex,
|
|
||||||
_params: &[Value],
|
|
||||||
_import_backing: &ImportBacking,
|
|
||||||
_vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
let index = _func_index.index() - self.func_import_count;
|
|
||||||
let ptr = self.code.ptr(self.functions[index].begin_offset);
|
|
||||||
let return_ty = self.functions[index].returns.last().cloned();
|
|
||||||
let buffer: Vec<u64> = _params
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.map(|x| match *x {
|
|
||||||
Value::I32(x) => x as u32 as u64,
|
|
||||||
Value::I64(x) => x as u64,
|
|
||||||
Value::F32(x) => f32::to_bits(x) as u64,
|
|
||||||
Value::F64(x) => f64::to_bits(x),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let ret = unsafe {
|
|
||||||
protect_unix::call_protected(|| {
|
|
||||||
CONSTRUCT_STACK_AND_CALL_WASM(
|
|
||||||
buffer.as_ptr(),
|
|
||||||
buffer.as_ptr().offset(buffer.len() as isize),
|
|
||||||
_vmctx,
|
|
||||||
ptr as _,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}?;
|
|
||||||
Ok(if let Some(ty) = return_ty {
|
|
||||||
vec![match ty {
|
|
||||||
WpType::I32 => Value::I32(ret as i32),
|
|
||||||
WpType::I64 => Value::I64(ret as i64),
|
|
||||||
WpType::F32 => Value::F32(f32::from_bits(ret as u32)),
|
|
||||||
WpType::F64 => Value::F64(f64::from_bits(ret as u64)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}]
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||||
|
|
||||||
unsafe extern "C" fn invoke(
|
unsafe extern "C" fn invoke(
|
||||||
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
|
_trampoline: unsafe extern "C" fn(
|
||||||
|
*mut vm::Ctx,
|
||||||
|
NonNull<vm::Func>,
|
||||||
|
*const u64,
|
||||||
|
*mut u64,
|
||||||
|
),
|
||||||
ctx: *mut vm::Ctx,
|
ctx: *mut vm::Ctx,
|
||||||
func: NonNull<vm::Func>,
|
func: NonNull<vm::Func>,
|
||||||
args: *const u64,
|
args: *const u64,
|
||||||
rets: *mut u64,
|
rets: *mut u64,
|
||||||
trap_info: *mut WasmTrapInfo,
|
_trap_info: *mut WasmTrapInfo,
|
||||||
num_params_plus_one: Option<NonNull<c_void>>,
|
num_params_plus_one: Option<NonNull<c_void>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let args = ::std::slice::from_raw_parts(
|
let args = ::std::slice::from_raw_parts(
|
||||||
@ -330,9 +273,7 @@ impl X64ModuleCodeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolver>
|
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext> for X64ModuleCodeGenerator {
|
||||||
for X64ModuleCodeGenerator
|
|
||||||
{
|
|
||||||
fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -367,7 +308,6 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
|||||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||||
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
||||||
|
|
||||||
begin_offset: begin_offset,
|
|
||||||
assembler: Some(assembler),
|
assembler: Some(assembler),
|
||||||
function_labels: Some(function_labels),
|
function_labels: Some(function_labels),
|
||||||
br_table_data: Some(br_table_data),
|
br_table_data: Some(br_table_data),
|
||||||
@ -384,10 +324,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
|||||||
Ok(self.functions.last_mut().unwrap())
|
Ok(self.functions.last_mut().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(
|
fn finalize(mut self, _: &ModuleInfo) -> Result<X64ExecutionContext, CodegenError> {
|
||||||
mut self,
|
|
||||||
module_info: &ModuleInfo,
|
|
||||||
) -> Result<(X64ExecutionContext, X64RuntimeResolver), CodegenError> {
|
|
||||||
let (assembler, mut br_table_data) = match self.functions.last_mut() {
|
let (assembler, mut br_table_data) = match self.functions.last_mut() {
|
||||||
Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()),
|
Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()),
|
||||||
None => {
|
None => {
|
||||||
@ -431,17 +368,14 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
|||||||
out_labels.push(FuncPtr(output.ptr(*offset) as _));
|
out_labels.push(FuncPtr(output.ptr(*offset) as _));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctx = X64ExecutionContext {
|
Ok(X64ExecutionContext {
|
||||||
code: output,
|
code: output,
|
||||||
functions: self.functions,
|
functions: self.functions,
|
||||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||||
_br_table_data: br_table_data,
|
_br_table_data: br_table_data,
|
||||||
func_import_count: self.func_import_count,
|
func_import_count: self.func_import_count,
|
||||||
function_pointers: out_labels,
|
function_pointers: out_labels,
|
||||||
};
|
})
|
||||||
let resolver = ctx.get_runtime_resolver(module_info)?;
|
|
||||||
|
|
||||||
Ok((ctx, resolver))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
|
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
|
||||||
|
@ -62,11 +62,10 @@ impl Compiler for SinglePassCompiler {
|
|||||||
) -> CompileResult<ModuleInner> {
|
) -> CompileResult<ModuleInner> {
|
||||||
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
||||||
let info = parse::read_module(wasm, Backend::Singlepass, &mut mcg, &compiler_config)?;
|
let info = parse::read_module(wasm, Backend::Singlepass, &mut mcg, &compiler_config)?;
|
||||||
let (ec, resolver) = mcg.finalize(&info)?;
|
let exec_context = mcg.finalize(&info)?;
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
cache_gen: Box::new(Placeholder),
|
cache_gen: Box::new(Placeholder),
|
||||||
func_resolver: Box::new(resolver),
|
runnable_module: Box::new(exec_context),
|
||||||
protected_caller: Box::new(ec),
|
|
||||||
info: info,
|
info: info,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller},
|
backend::{Backend, CompilerConfig, RunnableModule},
|
||||||
module::{
|
module::{
|
||||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
||||||
TableInitializer,
|
TableInitializer,
|
||||||
@ -63,10 +63,9 @@ fn validate(bytes: &[u8]) -> Result<(), LoadError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_module<
|
pub fn read_module<
|
||||||
MCG: ModuleCodeGenerator<FCG, PC, FR>,
|
MCG: ModuleCodeGenerator<FCG, RM>,
|
||||||
FCG: FunctionCodeGenerator,
|
FCG: FunctionCodeGenerator,
|
||||||
PC: ProtectedCaller,
|
RM: RunnableModule,
|
||||||
FR: FuncResolver,
|
|
||||||
>(
|
>(
|
||||||
wasm: &[u8],
|
wasm: &[u8],
|
||||||
backend: Backend,
|
backend: Backend,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user