mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-13 00:51:20 +00:00
Merge branch 'master' into add-validate
This commit is contained in:
@ -119,7 +119,6 @@ impl std::error::Error for LinkError {}
|
||||
/// The main way to do this is `Instance.call`.
|
||||
///
|
||||
/// Comparing two `RuntimeError`s always evaluates to false.
|
||||
#[derive(Debug)]
|
||||
pub enum RuntimeError {
|
||||
Trap { msg: Box<str> },
|
||||
Exception { data: Box<[Value]> },
|
||||
@ -141,11 +140,27 @@ impl std::fmt::Display for RuntimeError {
|
||||
RuntimeError::Exception { ref data } => {
|
||||
write!(f, "Uncaught WebAssembly exception: {:?}", data)
|
||||
}
|
||||
RuntimeError::Panic { data: _ } => write!(f, "User-defined \"panic\""),
|
||||
RuntimeError::Panic { data } => {
|
||||
let msg = if let Some(s) = data.downcast_ref::<String>() {
|
||||
s
|
||||
} else if let Some(s) = data.downcast_ref::<&str>() {
|
||||
s
|
||||
} else {
|
||||
"user-defined, opaque"
|
||||
};
|
||||
|
||||
write!(f, "{}", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for RuntimeError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for RuntimeError {}
|
||||
|
||||
/// This error type is produced by resolving a wasm function
|
||||
@ -197,7 +212,6 @@ impl std::error::Error for ResolveError {}
|
||||
/// be the `CallError::Runtime(RuntimeError)` variant.
|
||||
///
|
||||
/// Comparing two `CallError`s always evaluates to false.
|
||||
#[derive(Debug)]
|
||||
pub enum CallError {
|
||||
Resolve(ResolveError),
|
||||
Runtime(RuntimeError),
|
||||
@ -218,6 +232,15 @@ impl std::fmt::Display for CallError {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for CallError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
CallError::Resolve(resolve_err) => write!(f, "ResolveError: {:?}", resolve_err),
|
||||
CallError::Runtime(runtime_err) => write!(f, "RuntimeError: {:?}", runtime_err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for CallError {}
|
||||
|
||||
/// This error type is produced when creating something,
|
||||
|
@ -3,6 +3,7 @@ use hashbrown::{hash_map::Entry, HashMap};
|
||||
use std::collections::VecDeque;
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
ffi::c_void,
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
@ -45,6 +46,7 @@ impl IsExport for Export {
|
||||
/// ```
|
||||
pub struct ImportObject {
|
||||
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
|
||||
state_creator: Option<Rc<Fn() -> (*mut c_void, fn(*mut c_void))>>,
|
||||
}
|
||||
|
||||
impl ImportObject {
|
||||
@ -52,9 +54,24 @@ impl ImportObject {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: Rc::new(RefCell::new(HashMap::new())),
|
||||
state_creator: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_data<F>(state_creator: F) -> Self
|
||||
where
|
||||
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static,
|
||||
{
|
||||
Self {
|
||||
map: Rc::new(RefCell::new(HashMap::new())),
|
||||
state_creator: Some(Rc::new(state_creator)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn call_state_creator(&self) -> Option<(*mut c_void, fn(*mut c_void))> {
|
||||
self.state_creator.as_ref().map(|state_gen| state_gen())
|
||||
}
|
||||
|
||||
/// Register anything that implements `LikeNamespace` as a namespace.
|
||||
///
|
||||
/// # Usage:
|
||||
@ -98,6 +115,7 @@ impl ImportObject {
|
||||
pub fn clone_ref(&self) -> Self {
|
||||
Self {
|
||||
map: Rc::clone(&self.map),
|
||||
state_creator: self.state_creator.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,16 @@ impl Instance {
|
||||
// Initialize the vm::Ctx in-place after the backing
|
||||
// has been boxed.
|
||||
unsafe {
|
||||
*inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module)
|
||||
*inner.vmctx = match imports.call_state_creator() {
|
||||
Some((data, dtor)) => vm::Ctx::new_with_data(
|
||||
&mut inner.backing,
|
||||
&mut inner.import_backing,
|
||||
&module,
|
||||
data,
|
||||
dtor,
|
||||
),
|
||||
None => vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module),
|
||||
};
|
||||
};
|
||||
|
||||
let instance = Instance {
|
||||
|
@ -38,6 +38,13 @@ macro_rules! func {
|
||||
/// },
|
||||
/// };
|
||||
///
|
||||
/// let imports_with_state = imports! {
|
||||
/// || (0 as _, |_a| {}),
|
||||
/// "env" => {
|
||||
/// "foo" => func!(foo),
|
||||
/// },
|
||||
/// };
|
||||
///
|
||||
/// fn foo(_: &mut Ctx, n: i32) -> i32 {
|
||||
/// n
|
||||
/// }
|
||||
@ -57,6 +64,21 @@ macro_rules! imports {
|
||||
import_object.register($ns_name, ns);
|
||||
})*
|
||||
|
||||
import_object
|
||||
}};
|
||||
($state_gen:expr, $( $ns_name:expr => $ns:tt, )* ) => {{
|
||||
use $crate::{
|
||||
import::{ImportObject, Namespace},
|
||||
};
|
||||
|
||||
let mut import_object = ImportObject::new_with_data($state_gen);
|
||||
|
||||
$({
|
||||
let ns = $crate::__imports_internal!($ns);
|
||||
|
||||
import_object.register($ns_name, ns);
|
||||
})*
|
||||
|
||||
import_object
|
||||
}};
|
||||
}
|
||||
|
@ -77,6 +77,19 @@ where
|
||||
{
|
||||
const TYPE: Type;
|
||||
}
|
||||
|
||||
unsafe impl WasmExternType for i8 {
|
||||
const TYPE: Type = Type::I32;
|
||||
}
|
||||
unsafe impl WasmExternType for u8 {
|
||||
const TYPE: Type = Type::I32;
|
||||
}
|
||||
unsafe impl WasmExternType for i16 {
|
||||
const TYPE: Type = Type::I32;
|
||||
}
|
||||
unsafe impl WasmExternType for u16 {
|
||||
const TYPE: Type = Type::I32;
|
||||
}
|
||||
unsafe impl WasmExternType for i32 {
|
||||
const TYPE: Type = Type::I32;
|
||||
}
|
||||
@ -113,34 +126,15 @@ unsafe impl WasmExternType for f64 {
|
||||
// fn swap(&self, other: Self::Primitive) -> Self::Primitive;
|
||||
// }
|
||||
|
||||
pub enum ValueError {
|
||||
BufferTooSmall,
|
||||
}
|
||||
|
||||
pub trait ValueType: Copy
|
||||
pub unsafe trait ValueType: Copy
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn into_le(self, buffer: &mut [u8]);
|
||||
fn from_le(buffer: &[u8]) -> Result<Self, ValueError>;
|
||||
}
|
||||
|
||||
macro_rules! convert_value_impl {
|
||||
($t:ty) => {
|
||||
impl ValueType for $t {
|
||||
fn into_le(self, buffer: &mut [u8]) {
|
||||
buffer[..mem::size_of::<Self>()].copy_from_slice(&self.to_le_bytes());
|
||||
}
|
||||
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
|
||||
if buffer.len() >= mem::size_of::<Self>() {
|
||||
let mut array = [0u8; mem::size_of::<Self>()];
|
||||
array.copy_from_slice(&buffer[..mem::size_of::<Self>()]);
|
||||
Ok(Self::from_le_bytes(array))
|
||||
} else {
|
||||
Err(ValueError::BufferTooSmall)
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe impl ValueType for $t {}
|
||||
};
|
||||
( $($t:ty),* ) => {
|
||||
$(
|
||||
@ -149,25 +143,7 @@ macro_rules! convert_value_impl {
|
||||
};
|
||||
}
|
||||
|
||||
convert_value_impl!(u8, i8, u16, i16, u32, i32, u64, i64);
|
||||
|
||||
impl ValueType for f32 {
|
||||
fn into_le(self, buffer: &mut [u8]) {
|
||||
self.to_bits().into_le(buffer);
|
||||
}
|
||||
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
|
||||
Ok(f32::from_bits(<u32 as ValueType>::from_le(buffer)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueType for f64 {
|
||||
fn into_le(self, buffer: &mut [u8]) {
|
||||
self.to_bits().into_le(buffer);
|
||||
}
|
||||
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
|
||||
Ok(f64::from_bits(<u64 as ValueType>::from_le(buffer)?))
|
||||
}
|
||||
}
|
||||
convert_value_impl!(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ElementType {
|
||||
|
@ -25,7 +25,7 @@ pub struct Ctx {
|
||||
module: *const ModuleInner,
|
||||
|
||||
pub data: *mut c_void,
|
||||
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
|
||||
pub data_finalizer: Option<fn(data: *mut c_void)>,
|
||||
}
|
||||
|
||||
/// The internal context of the currently running WebAssembly instance.
|
||||
@ -100,7 +100,7 @@ impl Ctx {
|
||||
import_backing: &mut ImportBacking,
|
||||
module: &ModuleInner,
|
||||
data: *mut c_void,
|
||||
data_finalizer: extern "C" fn(*mut c_void),
|
||||
data_finalizer: fn(*mut c_void),
|
||||
) -> Self {
|
||||
Self {
|
||||
internal: InternalCtx {
|
||||
@ -481,7 +481,7 @@ mod vm_ctx_tests {
|
||||
str: String,
|
||||
}
|
||||
|
||||
extern "C" fn test_data_finalizer(data: *mut c_void) {
|
||||
fn test_data_finalizer(data: *mut c_void) {
|
||||
let test_data: &mut TestData = unsafe { &mut *(data as *mut TestData) };
|
||||
assert_eq!(test_data.x, 10);
|
||||
assert_eq!(test_data.y, true);
|
||||
|
Reference in New Issue
Block a user