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::{
|
||||
backend::{FuncResolver, ProtectedCaller},
|
||||
backend::RunnableModule,
|
||||
module::ModuleInfo,
|
||||
structures::Map,
|
||||
types::{FuncIndex, FuncSig, SigIndex},
|
||||
};
|
||||
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 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_function_signatures(
|
||||
&mut self,
|
||||
|
@ -11,17 +11,16 @@ use smallvec::SmallVec;
|
||||
use std::ptr::NonNull;
|
||||
use std::{any::Any, collections::HashMap, sync::Arc};
|
||||
use wasmer_runtime_core::{
|
||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
||||
error::RuntimeResult,
|
||||
backend::{RunnableModule, UserTrapper},
|
||||
memory::MemoryType,
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
module::ModuleInfo,
|
||||
structures::{Map, TypedIndex},
|
||||
typed_func::Wasm,
|
||||
types::{
|
||||
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
||||
TableIndex, Type, Value,
|
||||
TableIndex, Type,
|
||||
},
|
||||
vm::{self, ImportBacking, LocalGlobal, LocalMemory, LocalTable},
|
||||
vm::{self, LocalGlobal, LocalMemory, LocalTable},
|
||||
vmcalls,
|
||||
};
|
||||
use wasmparser::{Operator, Type as WpType};
|
||||
@ -132,7 +131,6 @@ pub struct X64FunctionCode {
|
||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
||||
|
||||
begin_offset: AssemblyOffset,
|
||||
assembler: Option<Assembler>,
|
||||
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
|
||||
br_table_data: Option<Vec<Vec<usize>>>,
|
||||
@ -154,7 +152,9 @@ unsafe impl Send for FuncPtr {}
|
||||
unsafe impl Sync for FuncPtr {}
|
||||
|
||||
pub struct X64ExecutionContext {
|
||||
#[allow(dead_code)]
|
||||
code: ExecutableBuffer,
|
||||
#[allow(dead_code)]
|
||||
functions: Vec<X64FunctionCode>,
|
||||
function_pointers: Vec<FuncPtr>,
|
||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||
@ -162,10 +162,6 @@ pub struct X64ExecutionContext {
|
||||
func_import_count: usize,
|
||||
}
|
||||
|
||||
pub struct X64RuntimeResolver {
|
||||
local_function_pointers: Vec<FuncPtr>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ControlFrame {
|
||||
pub label: DynamicLabel,
|
||||
@ -182,86 +178,33 @@ pub enum IfElseState {
|
||||
Else,
|
||||
}
|
||||
|
||||
impl X64ExecutionContext {
|
||||
fn get_runtime_resolver(
|
||||
impl RunnableModule for X64ExecutionContext {
|
||||
fn get_func(
|
||||
&self,
|
||||
_module_info: &ModuleInfo,
|
||||
) -> Result<X64RuntimeResolver, CodegenError> {
|
||||
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,
|
||||
_: &ModuleInfo,
|
||||
local_func_index: LocalFuncIndex,
|
||||
) -> Option<NonNull<vm::Func>> {
|
||||
NonNull::new(
|
||||
self.local_function_pointers[_local_func_index.index() as usize].0 as *mut vm::Func,
|
||||
)
|
||||
}
|
||||
self.function_pointers[self.func_import_count..]
|
||||
.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 wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||
|
||||
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,
|
||||
func: NonNull<vm::Func>,
|
||||
args: *const u64,
|
||||
rets: *mut u64,
|
||||
trap_info: *mut WasmTrapInfo,
|
||||
_trap_info: *mut WasmTrapInfo,
|
||||
num_params_plus_one: Option<NonNull<c_void>>,
|
||||
) -> bool {
|
||||
let args = ::std::slice::from_raw_parts(
|
||||
@ -330,9 +273,7 @@ impl X64ModuleCodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolver>
|
||||
for X64ModuleCodeGenerator
|
||||
{
|
||||
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext> for X64ModuleCodeGenerator {
|
||||
fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -367,7 +308,6 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
||||
|
||||
begin_offset: begin_offset,
|
||||
assembler: Some(assembler),
|
||||
function_labels: Some(function_labels),
|
||||
br_table_data: Some(br_table_data),
|
||||
@ -384,10 +324,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
||||
Ok(self.functions.last_mut().unwrap())
|
||||
}
|
||||
|
||||
fn finalize(
|
||||
mut self,
|
||||
module_info: &ModuleInfo,
|
||||
) -> Result<(X64ExecutionContext, X64RuntimeResolver), CodegenError> {
|
||||
fn finalize(mut self, _: &ModuleInfo) -> Result<X64ExecutionContext, CodegenError> {
|
||||
let (assembler, mut br_table_data) = match self.functions.last_mut() {
|
||||
Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()),
|
||||
None => {
|
||||
@ -431,17 +368,14 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
||||
out_labels.push(FuncPtr(output.ptr(*offset) as _));
|
||||
}
|
||||
|
||||
let ctx = X64ExecutionContext {
|
||||
Ok(X64ExecutionContext {
|
||||
code: output,
|
||||
functions: self.functions,
|
||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||
_br_table_data: br_table_data,
|
||||
func_import_count: self.func_import_count,
|
||||
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> {
|
||||
|
@ -62,11 +62,10 @@ impl Compiler for SinglePassCompiler {
|
||||
) -> CompileResult<ModuleInner> {
|
||||
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
||||
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 {
|
||||
cache_gen: Box::new(Placeholder),
|
||||
func_resolver: Box::new(resolver),
|
||||
protected_caller: Box::new(ec),
|
||||
runnable_module: Box::new(exec_context),
|
||||
info: info,
|
||||
})
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
||||
use hashbrown::HashMap;
|
||||
use wasmer_runtime_core::{
|
||||
backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller},
|
||||
backend::{Backend, CompilerConfig, RunnableModule},
|
||||
module::{
|
||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
||||
TableInitializer,
|
||||
@ -63,10 +63,9 @@ fn validate(bytes: &[u8]) -> Result<(), LoadError> {
|
||||
}
|
||||
|
||||
pub fn read_module<
|
||||
MCG: ModuleCodeGenerator<FCG, PC, FR>,
|
||||
MCG: ModuleCodeGenerator<FCG, RM>,
|
||||
FCG: FunctionCodeGenerator,
|
||||
PC: ProtectedCaller,
|
||||
FR: FuncResolver,
|
||||
RM: RunnableModule,
|
||||
>(
|
||||
wasm: &[u8],
|
||||
backend: Backend,
|
||||
|
Loading…
x
Reference in New Issue
Block a user