mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-13 00:51:20 +00:00
Merge remote-tracking branch 'private/master' into feature/dynasm-backend
This commit is contained in:
@ -83,6 +83,12 @@ pub trait ProtectedCaller: Send + Sync {
|
||||
vmctx: *mut vm::Ctx,
|
||||
_: Token,
|
||||
) -> RuntimeResult<Vec<Value>>;
|
||||
|
||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper>;
|
||||
}
|
||||
|
||||
pub trait UserTrapper {
|
||||
unsafe fn do_early_trap(&self, msg: String) -> !;
|
||||
}
|
||||
|
||||
pub trait FuncResolver: Send + Sync {
|
||||
|
@ -106,6 +106,9 @@ pub enum RuntimeError {
|
||||
table: TableIndex,
|
||||
},
|
||||
IllegalArithmeticOperation,
|
||||
User {
|
||||
msg: String,
|
||||
},
|
||||
Unknown {
|
||||
msg: String,
|
||||
},
|
||||
|
@ -7,7 +7,6 @@ use crate::{
|
||||
import::{ImportObject, LikeNamespace},
|
||||
memory::Memory,
|
||||
module::{ExportIndex, Module, ModuleInner},
|
||||
sig_registry::SigRegistry,
|
||||
table::Table,
|
||||
typed_func::{Func, Safe, WasmTypeList},
|
||||
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
|
||||
|
@ -3,6 +3,7 @@ use crate::{
|
||||
error::Result,
|
||||
import::ImportObject,
|
||||
structures::{Map, TypedIndex},
|
||||
typed_func::EARLY_TRAPPER,
|
||||
types::{
|
||||
FuncIndex, FuncSig, GlobalDescriptor, GlobalIndex, GlobalInit, ImportedFuncIndex,
|
||||
ImportedGlobalIndex, ImportedMemoryIndex, ImportedTableIndex, Initializer,
|
||||
@ -63,6 +64,10 @@ pub struct Module(#[doc(hidden)] pub Arc<ModuleInner>);
|
||||
|
||||
impl Module {
|
||||
pub(crate) fn new(inner: Arc<ModuleInner>) -> Self {
|
||||
unsafe {
|
||||
EARLY_TRAPPER
|
||||
.with(|ucell| *ucell.get() = Some(inner.protected_caller.get_early_trapper()));
|
||||
}
|
||||
Module(inner)
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,32 @@ pub struct Memory {
|
||||
}
|
||||
|
||||
impl Memory {
|
||||
pub fn with_size_protect(size: usize, protection: Protect) -> Result<Self, String> {
|
||||
if size == 0 {
|
||||
return Ok(Self {
|
||||
ptr: ptr::null_mut(),
|
||||
size: 0,
|
||||
protection,
|
||||
});
|
||||
}
|
||||
|
||||
let size = round_up_to_page_size(size, page_size::get());
|
||||
|
||||
let protect = protection.to_protect_const();
|
||||
|
||||
let ptr = unsafe { VirtualAlloc(ptr::null_mut(), size, MEM_RESERVE, protect) };
|
||||
|
||||
if ptr.is_null() {
|
||||
Err("unable to allocate memory".to_string())
|
||||
} else {
|
||||
Ok(Self {
|
||||
ptr: ptr as *mut u8,
|
||||
size,
|
||||
protection,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_size(size: usize) -> Result<Self, String> {
|
||||
if size == 0 {
|
||||
return Ok(Self {
|
||||
|
@ -1,11 +1,16 @@
|
||||
use crate::{
|
||||
backend::UserTrapper,
|
||||
error::RuntimeError,
|
||||
export::{Context, Export, FuncPointer},
|
||||
import::IsExport,
|
||||
types::{FuncSig, Type, WasmExternType},
|
||||
vm::Ctx,
|
||||
};
|
||||
use std::{marker::PhantomData, mem, ptr, sync::Arc};
|
||||
use std::{cell::UnsafeCell, fmt, marker::PhantomData, mem, panic, ptr, sync::Arc};
|
||||
|
||||
thread_local! {
|
||||
pub static EARLY_TRAPPER: UnsafeCell<Option<Box<dyn UserTrapper>>> = UnsafeCell::new(None);
|
||||
}
|
||||
|
||||
pub trait Safeness {}
|
||||
pub struct Safe;
|
||||
@ -28,9 +33,44 @@ where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
fn to_raw(self) -> *const ();
|
||||
fn to_raw(&self) -> *const ();
|
||||
}
|
||||
|
||||
pub trait TrapEarly<Rets>
|
||||
where
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
fn report(self) -> Result<Rets, String>;
|
||||
}
|
||||
|
||||
impl<Rets> TrapEarly<Rets> for Rets
|
||||
where
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
fn report(self) -> Result<Rets, String> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Rets, E> TrapEarly<Rets> for Result<Rets, E>
|
||||
where
|
||||
Rets: WasmTypeList,
|
||||
E: fmt::Debug,
|
||||
{
|
||||
fn report(self) -> Result<Rets, String> {
|
||||
self.map_err(|err| format!("Error: {:?}", err))
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn Func<'a, Args, Rets, F>(f: F) -> Func<'a, Args, Rets, Unsafe>
|
||||
// where
|
||||
// Args: WasmTypeList,
|
||||
// Rets: WasmTypeList,
|
||||
// F: ExternalFunction<Args, Rets>
|
||||
// {
|
||||
// Func::new(f)
|
||||
// }
|
||||
|
||||
pub struct Func<'a, Args = (), Rets = (), Safety: Safeness = Safe> {
|
||||
f: *const (),
|
||||
ctx: *mut Ctx,
|
||||
@ -143,18 +183,41 @@ macro_rules! impl_traits {
|
||||
}
|
||||
}
|
||||
|
||||
impl< $( $x: WasmExternType, )* Rets: WasmTypeList, FN: Fn( $( $x, )* &mut Ctx) -> Rets> ExternalFunction<($( $x ),*), Rets> for FN {
|
||||
impl< $( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( $( $x, )* &mut Ctx) -> Trap> ExternalFunction<($( $x ),*), Rets> for FN {
|
||||
#[allow(non_snake_case)]
|
||||
fn to_raw(self) -> *const () {
|
||||
fn to_raw(&self) -> *const () {
|
||||
assert_eq!(mem::size_of::<Self>(), 0, "you cannot use a closure that captures state for `Func`.");
|
||||
|
||||
extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, FN: Fn( $( $x, )* &mut Ctx) -> Rets>( $( $x: $x, )* ctx: &mut Ctx) -> Rets::CStruct {
|
||||
extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( $( $x, )* &mut Ctx) -> Trap>( $( $x: $x, )* ctx: &mut Ctx) -> Rets::CStruct {
|
||||
let f: FN = unsafe { mem::transmute_copy(&()) };
|
||||
let rets = f( $( $x, )* ctx);
|
||||
rets.into_c_struct()
|
||||
|
||||
let msg = match panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
f( $( $x, )* ctx).report()
|
||||
})) {
|
||||
Ok(Ok(returns)) => return returns.into_c_struct(),
|
||||
Ok(Err(err)) => err,
|
||||
Err(err) => {
|
||||
if let Some(s) = err.downcast_ref::<&str>() {
|
||||
s.to_string()
|
||||
} else if let Some(s) = err.downcast_ref::<String>() {
|
||||
s.clone()
|
||||
} else {
|
||||
"a panic occurred, but no additional information is available".to_string()
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
unsafe {
|
||||
if let Some(early_trapper) = &*EARLY_TRAPPER.with(|ucell| ucell.get()) {
|
||||
early_trapper.do_early_trap(msg)
|
||||
} else {
|
||||
eprintln!("panic handling not setup");
|
||||
std::process::exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wrap::<$( $x, )* Rets, Self> as *const ()
|
||||
wrap::<$( $x, )* Rets, Trap, Self> as *const ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -493,7 +493,7 @@ mod vm_ctx_tests {
|
||||
|
||||
fn generate_module() -> ModuleInner {
|
||||
use super::Func;
|
||||
use crate::backend::{Backend, FuncResolver, ProtectedCaller, Token};
|
||||
use crate::backend::{Backend, FuncResolver, ProtectedCaller, Token, UserTrapper};
|
||||
use crate::error::RuntimeResult;
|
||||
use crate::types::{FuncIndex, LocalFuncIndex, Value};
|
||||
use hashbrown::HashMap;
|
||||
@ -520,6 +520,9 @@ mod vm_ctx_tests {
|
||||
) -> RuntimeResult<Vec<Value>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
ModuleInner {
|
||||
|
Reference in New Issue
Block a user