mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-14 13:16:05 +00:00
Now we can run add
!
This commit is contained in:
parent
1526d35872
commit
bb52a4e6eb
@ -1,8 +1,9 @@
|
|||||||
|
use wasmer_runtime_core::backend::ProtectedCaller;
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
|
|
||||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator> {
|
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, PC: ProtectedCaller> {
|
||||||
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
||||||
fn finalize(&mut self) -> Result<(), CodegenError>;
|
fn finalize(self) -> Result<PC, CodegenError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FunctionCodeGenerator {
|
pub trait FunctionCodeGenerator {
|
||||||
|
@ -1,6 +1,19 @@
|
|||||||
use super::codegen::*;
|
use super::codegen::*;
|
||||||
use super::stack::{ValueInfo, ValueLocation, ValueStack};
|
use super::stack::{ValueInfo, ValueLocation, ValueStack};
|
||||||
use dynasmrt::{x64::Assembler, DynamicLabel, DynasmApi, DynasmLabelApi};
|
use dynasmrt::{
|
||||||
|
x64::Assembler, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi, ExecutableBuffer,
|
||||||
|
};
|
||||||
|
use wasmer_runtime_core::{
|
||||||
|
backend::{Backend, Compiler, FuncResolver, ProtectedCaller, Token, UserTrapper},
|
||||||
|
error::{CompileError, CompileResult, RuntimeError, RuntimeResult},
|
||||||
|
module::{ModuleInfo, ModuleInner, StringTable},
|
||||||
|
structures::{Map, TypedIndex},
|
||||||
|
types::{
|
||||||
|
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type,
|
||||||
|
Value,
|
||||||
|
},
|
||||||
|
vm::{self, ImportBacking},
|
||||||
|
};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
@ -49,6 +62,7 @@ pub struct X64ModuleCodeGenerator {
|
|||||||
pub struct X64FunctionCode {
|
pub struct X64FunctionCode {
|
||||||
id: usize,
|
id: usize,
|
||||||
begin_label: DynamicLabel,
|
begin_label: DynamicLabel,
|
||||||
|
begin_offset: AssemblyOffset,
|
||||||
cleanup_label: DynamicLabel,
|
cleanup_label: DynamicLabel,
|
||||||
assembler: Option<Assembler>,
|
assembler: Option<Assembler>,
|
||||||
returns: Vec<WpType>,
|
returns: Vec<WpType>,
|
||||||
@ -58,6 +72,55 @@ pub struct X64FunctionCode {
|
|||||||
value_stack: ValueStack,
|
value_stack: ValueStack,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct X64ExecutionContext {
|
||||||
|
code: ExecutableBuffer,
|
||||||
|
functions: Vec<X64FunctionCode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
let ptr = self.code.ptr(self.functions[index].begin_offset);
|
||||||
|
let return_ty = self.functions[index].returns.last().cloned();
|
||||||
|
|
||||||
|
if self.functions[index].num_params != _params.len() {
|
||||||
|
return Err(RuntimeError::User {
|
||||||
|
msg: "param count mismatch".into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.functions[index].num_params {
|
||||||
|
2 => unsafe {
|
||||||
|
let ptr: extern "C" fn(i64, i64) -> i64 = ::std::mem::transmute(ptr);
|
||||||
|
Ok(vec![Value::I32(
|
||||||
|
ptr(value_to_i64(&_params[0]), value_to_i64(&_params[1])) as i32,
|
||||||
|
)])
|
||||||
|
},
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
||||||
|
pub struct Trapper;
|
||||||
|
|
||||||
|
impl UserTrapper for Trapper {
|
||||||
|
unsafe fn do_early_trap(&self, msg: String) -> ! {
|
||||||
|
panic!("{}", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::new(Trapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct Local {
|
struct Local {
|
||||||
ty: WpType,
|
ty: WpType,
|
||||||
@ -70,7 +133,7 @@ impl X64ModuleCodeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleCodeGenerator<X64FunctionCode> for X64ModuleCodeGenerator {
|
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext> for X64ModuleCodeGenerator {
|
||||||
fn next_function(&mut self) -> Result<&mut X64FunctionCode, CodegenError> {
|
fn next_function(&mut self) -> Result<&mut X64FunctionCode, CodegenError> {
|
||||||
let mut assembler = match self.functions.last_mut() {
|
let mut assembler = match self.functions.last_mut() {
|
||||||
Some(x) => x.assembler.take().unwrap(),
|
Some(x) => x.assembler.take().unwrap(),
|
||||||
@ -84,6 +147,7 @@ impl ModuleCodeGenerator<X64FunctionCode> for X64ModuleCodeGenerator {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
let begin_label = assembler.new_dynamic_label();
|
let begin_label = assembler.new_dynamic_label();
|
||||||
|
let begin_offset = assembler.offset();
|
||||||
dynasm!(
|
dynasm!(
|
||||||
assembler
|
assembler
|
||||||
; => begin_label
|
; => begin_label
|
||||||
@ -93,6 +157,7 @@ impl ModuleCodeGenerator<X64FunctionCode> for X64ModuleCodeGenerator {
|
|||||||
let code = X64FunctionCode {
|
let code = X64FunctionCode {
|
||||||
id: self.functions.len(),
|
id: self.functions.len(),
|
||||||
begin_label: begin_label,
|
begin_label: begin_label,
|
||||||
|
begin_offset: begin_offset,
|
||||||
cleanup_label: assembler.new_dynamic_label(),
|
cleanup_label: assembler.new_dynamic_label(),
|
||||||
assembler: Some(assembler),
|
assembler: Some(assembler),
|
||||||
returns: vec![],
|
returns: vec![],
|
||||||
@ -105,13 +170,20 @@ impl ModuleCodeGenerator<X64FunctionCode> for X64ModuleCodeGenerator {
|
|||||||
Ok(self.functions.last_mut().unwrap())
|
Ok(self.functions.last_mut().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(&mut self) -> Result<(), CodegenError> {
|
fn finalize(mut self) -> Result<X64ExecutionContext, CodegenError> {
|
||||||
let mut assembler = match self.functions.last_mut() {
|
let mut assembler = match self.functions.last_mut() {
|
||||||
Some(x) => x.assembler.take().unwrap(),
|
Some(x) => x.assembler.take().unwrap(),
|
||||||
None => return Ok(()),
|
None => {
|
||||||
|
return Err(CodegenError {
|
||||||
|
message: "no function",
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let output = assembler.finalize().unwrap();
|
let output = assembler.finalize().unwrap();
|
||||||
Ok(())
|
Ok(X64ExecutionContext {
|
||||||
|
code: output,
|
||||||
|
functions: self.functions,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,3 +417,12 @@ fn get_size_of_type(ty: &WpType) -> Result<usize, CodegenError> {
|
|||||||
fn is_dword(n: usize) -> bool {
|
fn is_dword(n: usize) -> bool {
|
||||||
n == 4
|
n == 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn value_to_i64(v: &Value) -> i64 {
|
||||||
|
match *v {
|
||||||
|
Value::F32(x) => x.to_bits() as u64 as i64,
|
||||||
|
Value::F64(x) => x.to_bits() as u64 as i64,
|
||||||
|
Value::I32(x) => x as u64 as i64,
|
||||||
|
Value::I64(x) => x as u64 as i64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,8 @@ mod codegen_x64;
|
|||||||
mod parse;
|
mod parse;
|
||||||
mod stack;
|
mod stack;
|
||||||
|
|
||||||
|
use crate::codegen::{CodegenError, ModuleCodeGenerator};
|
||||||
|
use crate::parse::LoadError;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{Backend, Compiler, FuncResolver, ProtectedCaller, Token, UserTrapper},
|
backend::{Backend, Compiler, FuncResolver, ProtectedCaller, Token, UserTrapper},
|
||||||
@ -32,53 +34,38 @@ impl FuncResolver for Placeholder {
|
|||||||
_module: &ModuleInner,
|
_module: &ModuleInner,
|
||||||
_local_func_index: LocalFuncIndex,
|
_local_func_index: LocalFuncIndex,
|
||||||
) -> Option<NonNull<vm::Func>> {
|
) -> Option<NonNull<vm::Func>> {
|
||||||
|
panic!();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtectedCaller for Placeholder {
|
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_func_index: FuncIndex,
|
|
||||||
_params: &[Value],
|
|
||||||
_import_backing: &ImportBacking,
|
|
||||||
_vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
Ok(vec![])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
|
||||||
pub struct Trapper;
|
|
||||||
|
|
||||||
impl UserTrapper for Trapper {
|
|
||||||
unsafe fn do_early_trap(&self, msg: String) -> ! {
|
|
||||||
panic!("{}", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Box::new(Trapper)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SinglePassCompiler {}
|
pub struct SinglePassCompiler {}
|
||||||
|
|
||||||
impl Compiler for SinglePassCompiler {
|
impl Compiler for SinglePassCompiler {
|
||||||
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner> {
|
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner> {
|
||||||
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
||||||
let info = match parse::read_module(wasm, Backend::Dynasm, &mut mcg) {
|
let info = parse::read_module(wasm, Backend::Dynasm, &mut mcg)?;
|
||||||
Ok(x) => x,
|
let ec = mcg.finalize()?;
|
||||||
Err(e) => {
|
|
||||||
return Err(CompileError::InternalError {
|
|
||||||
msg: format!("{:?}", e),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
func_resolver: Box::new(Placeholder),
|
func_resolver: Box::new(Placeholder),
|
||||||
protected_caller: Box::new(Placeholder),
|
protected_caller: Box::new(ec),
|
||||||
info: info,
|
info: info,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<CodegenError> for CompileError {
|
||||||
|
fn from(other: CodegenError) -> CompileError {
|
||||||
|
CompileError::InternalError {
|
||||||
|
msg: other.message.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LoadError> for CompileError {
|
||||||
|
fn from(other: LoadError) -> CompileError {
|
||||||
|
CompileError::InternalError {
|
||||||
|
msg: format!("{:?}", other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user