mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-12 05:18:43 +00:00
No longer require FunctionEnvMut for new_typed(…) callback function
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
use anyhow::bail;
|
||||
use std::fmt;
|
||||
use wasmer::{imports, wat2wasm, Function, FunctionEnvMut, Instance, Module, Store, TypedFunction};
|
||||
use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, TypedFunction};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
|
||||
// First we need to create an error type that we'll use to signal the end of execution.
|
||||
@@ -61,7 +61,7 @@ fn main() -> anyhow::Result<()> {
|
||||
let module = Module::new(&store, wasm_bytes)?;
|
||||
|
||||
// We declare the host function that we'll use to terminate execution.
|
||||
fn early_exit(_env: FunctionEnvMut<()>) -> Result<(), ExitCode> {
|
||||
fn early_exit() -> Result<(), ExitCode> {
|
||||
// This is where it happens.
|
||||
Err(ExitCode(1))
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! cargo run --example hello-world --release --features "cranelift"
|
||||
//! ```
|
||||
|
||||
use wasmer::{imports, wat2wasm, Function, FunctionEnvMut, Instance, Module, Store, TypedFunction};
|
||||
use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, TypedFunction};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
@@ -51,7 +51,7 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
// We define a function to act as our "env" "say_hello" function imported in the
|
||||
// Wasm program above.
|
||||
fn say_hello_world(_env: FunctionEnvMut<'_, ()>) {
|
||||
fn say_hello_world() {
|
||||
println!("Hello, world!")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use wasmer::{
|
||||
imports, wat2wasm, Function, FunctionEnvMut, Instance, Module, Store, TableType, Type,
|
||||
TypedFunction, Value,
|
||||
imports, wat2wasm, Function, Instance, Module, Store, TableType, Type, TypedFunction, Value,
|
||||
};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
|
||||
/// A function we'll call through a table.
|
||||
fn host_callback(_env: FunctionEnvMut<()>, arg1: i32, arg2: i32) -> i32 {
|
||||
fn host_callback(arg1: i32, arg2: i32) -> i32 {
|
||||
arg1 + arg2
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ impl Exports {
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
self.get_function(name)?
|
||||
.native(store)
|
||||
.typed(store)
|
||||
.map_err(|_| ExportError::IncompatibleType)
|
||||
}
|
||||
|
||||
|
||||
127
lib/api/src/js/externals/function.rs
vendored
127
lib/api/src/js/externals/function.rs
vendored
@@ -1,4 +1,4 @@
|
||||
pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList};
|
||||
pub use self::inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, WithoutEnv};
|
||||
use crate::js::exports::{ExportError, Exportable};
|
||||
use crate::js::externals::Extern;
|
||||
use crate::js::function_env::FunctionEnvMut;
|
||||
@@ -65,7 +65,6 @@ impl Function {
|
||||
///
|
||||
/// If you know the signature of the host function at compile time,
|
||||
/// consider using [`Function::new_typed`] for less runtime overhead.
|
||||
#[cfg(feature = "compiler")]
|
||||
pub fn new<FT, F>(store: &mut impl AsStoreMut, ty: FT, func: F) -> Self
|
||||
where
|
||||
FT: Into<FunctionType>,
|
||||
@@ -182,6 +181,49 @@ impl Function {
|
||||
Self::from_vm_export(&mut store, vm_function)
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "3.0.0",
|
||||
note = "new_native() has been renamed to new_typed()."
|
||||
)]
|
||||
/// Creates a new host `Function` from a native function.
|
||||
pub fn new_native<F, Args, Rets>(store: &mut impl AsStoreMut, func: F) -> Self
|
||||
where
|
||||
F: HostFunction<(), Args, Rets, WithoutEnv> + 'static + Send + Sync,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
Self::new_typed(store, func)
|
||||
}
|
||||
|
||||
/// Creates a new host `Function` from a native function.
|
||||
pub fn new_typed<F, Args, Rets>(store: &mut impl AsStoreMut, func: F) -> Self
|
||||
where
|
||||
F: HostFunction<(), Args, Rets, WithoutEnv> + 'static + Send + Sync,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
let mut store = store.as_store_mut();
|
||||
if std::mem::size_of::<F>() != 0 {
|
||||
Self::closures_unsupported_panic();
|
||||
}
|
||||
let function = inner::Function::<Args, Rets>::new(func);
|
||||
let address = function.address() as usize as u32;
|
||||
|
||||
let ft = wasm_bindgen::function_table();
|
||||
let as_table = ft.unchecked_ref::<js_sys::WebAssembly::Table>();
|
||||
let func = as_table.get(address).unwrap();
|
||||
|
||||
let binded_func = func.bind1(
|
||||
&JsValue::UNDEFINED,
|
||||
&JsValue::from_f64(store.as_raw() as *mut u8 as usize as f64),
|
||||
);
|
||||
let ty = function.ty();
|
||||
let vm_function = VMFunction::new(binded_func, ty);
|
||||
Self {
|
||||
handle: StoreHandle::new(store.objects_mut(), vm_function),
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "3.0.0",
|
||||
note = "new_native_with_env() has been renamed to new_typed_with_env()."
|
||||
@@ -193,7 +235,7 @@ impl Function {
|
||||
func: F,
|
||||
) -> Self
|
||||
where
|
||||
F: HostFunction<T, Args, Rets>,
|
||||
F: HostFunction<T, Args, Rets, WithEnv>,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
@@ -223,7 +265,7 @@ impl Function {
|
||||
func: F,
|
||||
) -> Self
|
||||
where
|
||||
F: HostFunction<T, Args, Rets>,
|
||||
F: HostFunction<T, Args, Rets, WithEnv>,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
@@ -840,10 +882,11 @@ mod inner {
|
||||
/// can be used as host function. To uphold this statement, it is
|
||||
/// necessary for a function to be transformed into a pointer to
|
||||
/// `VMFunctionBody`.
|
||||
pub trait HostFunction<T, Args, Rets>
|
||||
pub trait HostFunction<T, Args, Rets, Kind>
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
Kind: HostFunctionKind,
|
||||
T: Sized,
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -851,6 +894,27 @@ mod inner {
|
||||
fn function_body_ptr(self) -> *const VMFunctionBody;
|
||||
}
|
||||
|
||||
/// Empty trait to specify the kind of `HostFunction`: With or
|
||||
/// without an environment.
|
||||
///
|
||||
/// This trait is never aimed to be used by a user. It is used by
|
||||
/// the trait system to automatically generate the appropriate
|
||||
/// host functions.
|
||||
#[doc(hidden)]
|
||||
pub trait HostFunctionKind {}
|
||||
|
||||
/// An empty struct to help Rust typing to determine
|
||||
/// when a `HostFunction` does have an environment.
|
||||
pub struct WithEnv;
|
||||
|
||||
impl HostFunctionKind for WithEnv {}
|
||||
|
||||
/// An empty struct to help Rust typing to determine
|
||||
/// when a `HostFunction` does not have an environment.
|
||||
pub struct WithoutEnv;
|
||||
|
||||
impl HostFunctionKind for WithoutEnv {}
|
||||
|
||||
/// Represents a low-level Wasm static host function. See
|
||||
/// `super::Function::new` and `super::Function::new_env` to learn
|
||||
/// more.
|
||||
@@ -869,9 +933,9 @@ mod inner {
|
||||
{
|
||||
/// Creates a new `Function`.
|
||||
#[allow(dead_code)]
|
||||
pub fn new<F, T>(function: F) -> Self
|
||||
pub fn new<F, T, Kind: HostFunctionKind>(function: F) -> Self
|
||||
where
|
||||
F: HostFunction<T, Args, Rets>,
|
||||
F: HostFunction<T, Args, Rets, Kind>,
|
||||
T: Sized,
|
||||
{
|
||||
Self {
|
||||
@@ -1013,10 +1077,11 @@ mod inner {
|
||||
}
|
||||
}
|
||||
|
||||
// Implement `HostFunction` for a function that has the same arity than the tuple.
|
||||
// Implement `HostFunction` for a function with a [`FunctionEnvMut`] that has the same
|
||||
// arity than the tuple.
|
||||
#[allow(unused_parens)]
|
||||
impl< $( $x, )* Rets, RetsAsResult, T, Func >
|
||||
HostFunction<T, ( $( $x ),* ), Rets>
|
||||
HostFunction<T, ( $( $x ),* ), Rets, WithEnv>
|
||||
for
|
||||
Func
|
||||
where
|
||||
@@ -1061,6 +1126,50 @@ mod inner {
|
||||
func_wrapper::< T, $( $x, )* Rets, RetsAsResult, Self > as *const VMFunctionBody
|
||||
}
|
||||
}
|
||||
|
||||
// Implement `HostFunction` for a function that has the same arity than the tuple.
|
||||
#[allow(unused_parens)]
|
||||
impl< $( $x, )* Rets, RetsAsResult, Func >
|
||||
HostFunction<(), ( $( $x ),* ), Rets, WithoutEnv>
|
||||
for
|
||||
Func
|
||||
where
|
||||
$( $x: FromToNativeWasmType, )*
|
||||
Rets: WasmTypeList,
|
||||
RetsAsResult: IntoResult<Rets>,
|
||||
Func: Fn($( $x , )*) -> RetsAsResult + 'static,
|
||||
{
|
||||
#[allow(non_snake_case)]
|
||||
fn function_body_ptr(self) -> *const VMFunctionBody {
|
||||
/// This is a function that wraps the real host
|
||||
/// function. Its address will be used inside the
|
||||
/// runtime.
|
||||
unsafe extern "C" fn func_wrapper<$( $x, )* Rets, RetsAsResult, Func>( store_ptr: usize, $( $x: <$x::Native as NativeWasmType>::Abi, )* ) -> Rets::CStruct
|
||||
where
|
||||
$( $x: FromToNativeWasmType, )*
|
||||
Rets: WasmTypeList,
|
||||
RetsAsResult: IntoResult<Rets>,
|
||||
Func: Fn($( $x , )*) -> RetsAsResult + 'static,
|
||||
{
|
||||
// let env: &Env = unsafe { &*(ptr as *const u8 as *const Env) };
|
||||
let func: &Func = &*(&() as *const () as *const Func);
|
||||
let mut store = StoreMut::from_raw(store_ptr as *mut _);
|
||||
|
||||
let result = panic::catch_unwind(AssertUnwindSafe(|| {
|
||||
func($( FromToNativeWasmType::from_native(NativeWasmTypeInto::from_abi(&mut store, $x)) ),* ).into_result()
|
||||
}));
|
||||
|
||||
match result {
|
||||
Ok(Ok(result)) => return result.into_c_struct(&mut store),
|
||||
#[allow(deprecated)]
|
||||
Ok(Err(trap)) => RuntimeError::raise(Box::new(trap)),
|
||||
Err(_panic) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
func_wrapper::< $( $x, )* Rets, RetsAsResult, Self > as *const VMFunctionBody
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//!
|
||||
//! ```ignore
|
||||
//! let add_one = instance.exports.get_function("function_name")?;
|
||||
//! let add_one_native: TypedFunction<i32, i32> = add_one.native().unwrap();
|
||||
//! let add_one_native: TypedFunction<i32, i32> = add_one.typed().unwrap();
|
||||
//! ```
|
||||
use std::marker::PhantomData;
|
||||
|
||||
@@ -37,11 +37,7 @@ where
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn new<T>(
|
||||
store: &mut impl AsStoreMut,
|
||||
_env: &FunctionEnv<T>,
|
||||
vm_function: VMFunction,
|
||||
) -> Self {
|
||||
pub(crate) fn new<T>(store: &mut impl AsStoreMut, vm_function: VMFunction) -> Self {
|
||||
Self {
|
||||
handle: StoreHandle::new(store.as_store_mut().objects_mut(), vm_function),
|
||||
_phantom: PhantomData,
|
||||
@@ -108,7 +104,7 @@ macro_rules! impl_native_traits {
|
||||
{
|
||||
fn get_self_from_extern_with_generics(store: &impl AsStoreRef, _extern: &crate::js::externals::Extern) -> Result<Self, crate::js::exports::ExportError> {
|
||||
use crate::js::exports::Exportable;
|
||||
crate::js::Function::get_self_from_extern(_extern)?.native(store).map_err(|_| crate::js::exports::ExportError::IncompatibleType)
|
||||
crate::js::Function::get_self_from_extern(_extern)?.typed(store).map_err(|_| crate::js::exports::ExportError::IncompatibleType)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
//! let memory = Memory::new(&mut store, MemoryType::new(1, None, false)).unwrap();
|
||||
//! imports! {
|
||||
//! "env" => {
|
||||
//! "my_function" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>| println!("Hello")),
|
||||
//! "my_function" => Function::new_typed(&mut store, || println!("Hello")),
|
||||
//! "memory" => memory,
|
||||
//! }
|
||||
//! }
|
||||
|
||||
155
lib/api/src/sys/externals/function.rs
vendored
155
lib/api/src/sys/externals/function.rs
vendored
@@ -7,7 +7,7 @@ use crate::sys::TypedFunction;
|
||||
|
||||
use crate::{FunctionEnv, FunctionEnvMut, Value};
|
||||
use inner::StaticFunction;
|
||||
pub use inner::{FromToNativeWasmType, HostFunction, WasmTypeList};
|
||||
pub use inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, WithoutEnv};
|
||||
use std::cell::UnsafeCell;
|
||||
use std::cmp::max;
|
||||
use std::ffi::c_void;
|
||||
@@ -188,7 +188,7 @@ impl Function {
|
||||
/// Creates a new host `Function` from a native function.
|
||||
pub fn new_native<F, Args, Rets>(store: &mut impl AsStoreMut, func: F) -> Self
|
||||
where
|
||||
F: HostFunction<(), Args, Rets> + 'static + Send + Sync,
|
||||
F: HostFunction<(), Args, Rets, WithoutEnv> + 'static + Send + Sync,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
@@ -199,12 +199,44 @@ impl Function {
|
||||
/// Creates a new host `Function` from a native function.
|
||||
pub fn new_typed<F, Args, Rets>(store: &mut impl AsStoreMut, func: F) -> Self
|
||||
where
|
||||
F: HostFunction<(), Args, Rets> + 'static + Send + Sync,
|
||||
F: HostFunction<(), Args, Rets, WithoutEnv> + 'static + Send + Sync,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
let env = FunctionEnv::new(store, ());
|
||||
Self::new_typed_with_env(store, &env, func)
|
||||
let host_data = Box::new(StaticFunction {
|
||||
raw_store: store.as_store_mut().as_raw() as *mut u8,
|
||||
env,
|
||||
func,
|
||||
});
|
||||
let function_type = FunctionType::new(Args::wasm_types(), Rets::wasm_types());
|
||||
|
||||
let func_ptr = <F as HostFunction<(), Args, Rets, WithoutEnv>>::function_body_ptr();
|
||||
let type_index = store
|
||||
.as_store_mut()
|
||||
.engine()
|
||||
.register_signature(&function_type);
|
||||
let vmctx = VMFunctionContext {
|
||||
host_env: host_data.as_ref() as *const _ as *mut c_void,
|
||||
};
|
||||
let call_trampoline =
|
||||
<F as HostFunction<(), Args, Rets, WithoutEnv>>::call_trampoline_address();
|
||||
let anyfunc = VMCallerCheckedAnyfunc {
|
||||
func_ptr,
|
||||
type_index,
|
||||
vmctx,
|
||||
call_trampoline,
|
||||
};
|
||||
|
||||
let vm_function = VMFunction {
|
||||
anyfunc: MaybeInstanceOwned::Host(Box::new(UnsafeCell::new(anyfunc))),
|
||||
kind: VMFunctionKind::Static,
|
||||
signature: function_type,
|
||||
host_data,
|
||||
};
|
||||
Self {
|
||||
handle: StoreHandle::new(store.as_store_mut().objects_mut(), vm_function),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "compiler")]
|
||||
@@ -219,7 +251,7 @@ impl Function {
|
||||
func: F,
|
||||
) -> Self
|
||||
where
|
||||
F: HostFunction<T, Args, Rets> + 'static + Send + Sync,
|
||||
F: HostFunction<T, Args, Rets, WithEnv> + 'static + Send + Sync,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
@@ -251,7 +283,7 @@ impl Function {
|
||||
func: F,
|
||||
) -> Self
|
||||
where
|
||||
F: HostFunction<T, Args, Rets> + 'static + Send + Sync,
|
||||
F: HostFunction<T, Args, Rets, WithEnv> + 'static + Send + Sync,
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
@@ -264,7 +296,7 @@ impl Function {
|
||||
});
|
||||
let function_type = FunctionType::new(Args::wasm_types(), Rets::wasm_types());
|
||||
|
||||
let func_ptr = <F as HostFunction<T, Args, Rets>>::function_body_ptr();
|
||||
let func_ptr = <F as HostFunction<T, Args, Rets, WithEnv>>::function_body_ptr();
|
||||
let type_index = store
|
||||
.as_store_mut()
|
||||
.engine()
|
||||
@@ -272,7 +304,8 @@ impl Function {
|
||||
let vmctx = VMFunctionContext {
|
||||
host_env: host_data.as_ref() as *const _ as *mut c_void,
|
||||
};
|
||||
let call_trampoline = <F as HostFunction<T, Args, Rets>>::call_trampoline_address();
|
||||
let call_trampoline =
|
||||
<F as HostFunction<T, Args, Rets, WithEnv>>::call_trampoline_address();
|
||||
let anyfunc = VMCallerCheckedAnyfunc {
|
||||
func_ptr,
|
||||
type_index,
|
||||
@@ -1052,10 +1085,11 @@ mod inner {
|
||||
/// can be used as host function. To uphold this statement, it is
|
||||
/// necessary for a function to be transformed into a pointer to
|
||||
/// `VMFunctionBody`.
|
||||
pub trait HostFunction<T, Args, Rets>
|
||||
pub trait HostFunction<T, Args, Rets, Kind>
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
Kind: HostFunctionKind,
|
||||
{
|
||||
/// Get the pointer to the function body.
|
||||
fn function_body_ptr() -> *const VMFunctionBody;
|
||||
@@ -1064,6 +1098,27 @@ mod inner {
|
||||
fn call_trampoline_address() -> VMTrampoline;
|
||||
}
|
||||
|
||||
/// Empty trait to specify the kind of `HostFunction`: With or
|
||||
/// without an environment.
|
||||
///
|
||||
/// This trait is never aimed to be used by a user. It is used by
|
||||
/// the trait system to automatically generate the appropriate
|
||||
/// host functions.
|
||||
#[doc(hidden)]
|
||||
pub trait HostFunctionKind {}
|
||||
|
||||
/// An empty struct to help Rust typing to determine
|
||||
/// when a `HostFunction` does have an environment.
|
||||
pub struct WithEnv;
|
||||
|
||||
impl HostFunctionKind for WithEnv {}
|
||||
|
||||
/// An empty struct to help Rust typing to determine
|
||||
/// when a `HostFunction` does not have an environment.
|
||||
pub struct WithoutEnv;
|
||||
|
||||
impl HostFunctionKind for WithoutEnv {}
|
||||
|
||||
/// Represents a low-level Wasm static host function. See
|
||||
/// [`super::Function::new_typed`] and
|
||||
/// [`super::Function::new_typed_with_env`] to learn more.
|
||||
@@ -1189,10 +1244,11 @@ mod inner {
|
||||
}
|
||||
}
|
||||
|
||||
// Implement `HostFunction` for a function that has the same arity than the tuple.
|
||||
// Implement `HostFunction` for a function with a [`FunctionEnvMut`] that has the same
|
||||
// arity than the tuple.
|
||||
#[allow(unused_parens)]
|
||||
impl< $( $x, )* Rets, RetsAsResult, T: Send + 'static, Func >
|
||||
HostFunction<T, ( $( $x ),* ), Rets>
|
||||
HostFunction<T, ( $( $x ),* ), Rets, WithEnv>
|
||||
for
|
||||
Func
|
||||
where
|
||||
@@ -1272,6 +1328,83 @@ mod inner {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Implement `HostFunction` for a function that has the same arity than the tuple.
|
||||
#[allow(unused_parens)]
|
||||
impl< $( $x, )* Rets, RetsAsResult, Func >
|
||||
HostFunction<(), ( $( $x ),* ), Rets, WithoutEnv>
|
||||
for
|
||||
Func
|
||||
where
|
||||
$( $x: FromToNativeWasmType, )*
|
||||
Rets: WasmTypeList,
|
||||
RetsAsResult: IntoResult<Rets>,
|
||||
Func: Fn($( $x , )*) -> RetsAsResult + 'static,
|
||||
{
|
||||
#[allow(non_snake_case)]
|
||||
fn function_body_ptr() -> *const VMFunctionBody {
|
||||
/// This is a function that wraps the real host
|
||||
/// function. Its address will be used inside the
|
||||
/// runtime.
|
||||
unsafe extern "C" fn func_wrapper<$( $x, )* Rets, RetsAsResult, Func>( env: &StaticFunction<Func, ()>, $( $x: <$x::Native as NativeWasmType>::Abi, )* ) -> Rets::CStruct
|
||||
where
|
||||
$( $x: FromToNativeWasmType, )*
|
||||
Rets: WasmTypeList,
|
||||
RetsAsResult: IntoResult<Rets>,
|
||||
Func: Fn($( $x , )*) -> RetsAsResult + 'static,
|
||||
{
|
||||
// println!("func wrapper");
|
||||
let mut store = StoreMut::from_raw(env.raw_store as *mut _);
|
||||
let result = on_host_stack(|| {
|
||||
// println!("func wrapper1");
|
||||
panic::catch_unwind(AssertUnwindSafe(|| {
|
||||
$(
|
||||
let $x = FromToNativeWasmType::from_native(NativeWasmTypeInto::from_abi(&mut store, $x));
|
||||
)*
|
||||
(env.func)($($x),* ).into_result()
|
||||
}))
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(Ok(result)) => return result.into_c_struct(&mut store),
|
||||
Ok(Err(trap)) => raise_user_trap(Box::new(trap)),
|
||||
Err(panic) => resume_panic(panic) ,
|
||||
}
|
||||
}
|
||||
|
||||
func_wrapper::< $( $x, )* Rets, RetsAsResult, Self > as *const VMFunctionBody
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn call_trampoline_address() -> VMTrampoline {
|
||||
unsafe extern "C" fn call_trampoline<
|
||||
$( $x: FromToNativeWasmType, )*
|
||||
Rets: WasmTypeList,
|
||||
>(
|
||||
vmctx: *mut VMContext,
|
||||
body: *const VMFunctionBody,
|
||||
args: *mut RawValue,
|
||||
) {
|
||||
let body: unsafe extern "C" fn(
|
||||
vmctx: *mut VMContext,
|
||||
$( $x: <$x::Native as NativeWasmType>::Abi, )*
|
||||
) -> Rets::CStruct
|
||||
= std::mem::transmute(body);
|
||||
|
||||
let mut _n = 0;
|
||||
$(
|
||||
let $x = *args.add(_n).cast();
|
||||
_n += 1;
|
||||
)*
|
||||
|
||||
let results = body(vmctx, $( $x ),*);
|
||||
Rets::write_c_struct_to_ptr(results, args);
|
||||
}
|
||||
|
||||
call_trampoline::<$( $x, )* Rets>
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ use wasmer_types::ImportError;
|
||||
///
|
||||
/// let instance = Instance::new(&mut store, &module, &import_object).expect("Could not instantiate module.");
|
||||
///
|
||||
/// fn foo(_env: FunctionEnvMut<()>, n: i32) -> i32 {
|
||||
/// fn foo(n: i32) -> i32 {
|
||||
/// n
|
||||
/// }
|
||||
///
|
||||
@@ -100,7 +100,7 @@ impl Imports {
|
||||
/// # use wasmer::{FunctionEnv, Store};
|
||||
/// # let mut store: Store = Default::default();
|
||||
/// use wasmer::{StoreMut, Imports, Function, FunctionEnvMut};
|
||||
/// fn foo(_env: FunctionEnvMut<()>, n: i32) -> i32 {
|
||||
/// fn foo(n: i32) -> i32 {
|
||||
/// n
|
||||
/// }
|
||||
/// let mut import_object = Imports::new();
|
||||
@@ -219,7 +219,7 @@ impl fmt::Debug for Imports {
|
||||
/// },
|
||||
/// };
|
||||
///
|
||||
/// fn foo(_env: FunctionEnvMut<()>, n: i32) -> i32 {
|
||||
/// fn foo(n: i32) -> i32 {
|
||||
/// n
|
||||
/// }
|
||||
/// ```
|
||||
@@ -297,11 +297,10 @@ mod test {
|
||||
#[test]
|
||||
fn imports_macro_allows_trailing_comma_and_none() {
|
||||
use crate::sys::Function;
|
||||
use crate::sys::FunctionEnvMut;
|
||||
|
||||
let mut store: Store = Default::default();
|
||||
|
||||
fn func(_env: FunctionEnvMut<()>, arg: i32) -> i32 {
|
||||
fn func(arg: i32) -> i32 {
|
||||
arg + 1
|
||||
}
|
||||
|
||||
|
||||
@@ -259,49 +259,43 @@ mod js {
|
||||
#[wasm_bindgen_test]
|
||||
fn function_new_dynamic() {
|
||||
let mut store = Store::default();
|
||||
let env = FunctionEnv::new(&mut store, ());
|
||||
|
||||
// Using &FunctionType signature
|
||||
let function_type = FunctionType::new(vec![], vec![]);
|
||||
let function = Function::new(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
|_env: FunctionEnvMut<'_, ()>, _values: &[Value]| unimplemented!(),
|
||||
|_values: &[Value]| unimplemented!(),
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type = FunctionType::new(vec![Type::I32], vec![]);
|
||||
let function = Function::new(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
|_env: FunctionEnvMut<'_, ()>, _values: &[Value]| unimplemented!(),
|
||||
|_values: &[Value]| unimplemented!(),
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type =
|
||||
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]);
|
||||
let function = Function::new(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
|_env: FunctionEnvMut<'_, ()>, _values: &[Value]| unimplemented!(),
|
||||
|_values: &[Value]| unimplemented!(),
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type = FunctionType::new(vec![], vec![Type::I32]);
|
||||
let function = Function::new(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
|_env: FunctionEnvMut<'_, ()>, _values: &[Value]| unimplemented!(),
|
||||
|_values: &[Value]| unimplemented!(),
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type =
|
||||
FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]);
|
||||
let function = Function::new(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
|_env: FunctionEnvMut<'_, ()>, _values: &[Value]| unimplemented!(),
|
||||
|_values: &[Value]| unimplemented!(),
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
|
||||
@@ -309,9 +303,8 @@ mod js {
|
||||
let function_type = ([Type::V128], [Type::I32, Type::F32, Type::F64]);
|
||||
let function = Function::new(
|
||||
&mut store,
|
||||
&env,
|
||||
function_type,
|
||||
|_env: FunctionEnvMut<'_, ()>, _values: &[Value]| unimplemented!(),
|
||||
|_values: &[Value]| unimplemented!(),
|
||||
);
|
||||
assert_eq!(function.ty(&store).params(), [Type::V128]);
|
||||
assert_eq!(
|
||||
@@ -331,7 +324,7 @@ mod js {
|
||||
|
||||
// Using &FunctionType signature
|
||||
let function_type = FunctionType::new(vec![], vec![]);
|
||||
let function = Function::new(
|
||||
let function = Function::new_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
@@ -339,7 +332,7 @@ mod js {
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type = FunctionType::new(vec![Type::I32], vec![]);
|
||||
let function = Function::new(
|
||||
let function = Function::new_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
@@ -348,7 +341,7 @@ mod js {
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type =
|
||||
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]);
|
||||
let function = Function::new(
|
||||
let function = Function::new_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
@@ -356,7 +349,7 @@ mod js {
|
||||
);
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type = FunctionType::new(vec![], vec![Type::I32]);
|
||||
let function = Function::new(
|
||||
let function = Function::new_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
@@ -365,7 +358,7 @@ mod js {
|
||||
assert_eq!(function.ty(&store).clone(), function_type);
|
||||
let function_type =
|
||||
FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]);
|
||||
let function = Function::new(
|
||||
let function = Function::new_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
&function_type,
|
||||
@@ -375,7 +368,7 @@ mod js {
|
||||
|
||||
// Using array signature
|
||||
let function_type = ([Type::V128], [Type::I32, Type::F32, Type::F64]);
|
||||
let function = Function::new(
|
||||
let function = Function::new_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
function_type,
|
||||
@@ -391,7 +384,6 @@ mod js {
|
||||
#[wasm_bindgen_test]
|
||||
fn native_function_works() {
|
||||
let mut store = Store::default();
|
||||
let mut env = FunctionEnv::new(&mut store, ());
|
||||
let function = Function::new_typed(&mut store, || {});
|
||||
let typed_function: TypedFunction<(), ()> = function.typed(&mut store).unwrap();
|
||||
let result = typed_function.call(&mut store);
|
||||
|
||||
@@ -119,11 +119,10 @@ mod js {
|
||||
))],
|
||||
})
|
||||
.unwrap();
|
||||
let env = FunctionEnv::new(&mut store, ());
|
||||
|
||||
let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
|
||||
|
||||
let imported = Function::new(&mut store, &env, imported_signature, |_env, args| {
|
||||
let imported = Function::new(&mut store, imported_signature, |args| {
|
||||
log!("Calling `imported`...");
|
||||
let result = args[0].unwrap_i32() * 2;
|
||||
log!("Result of `imported`: {:?}", result);
|
||||
@@ -239,7 +238,8 @@ mod js {
|
||||
let env = FunctionEnv::new(&mut store, Env { multiplier: 3 });
|
||||
|
||||
let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
|
||||
let imported = Function::new(&mut store, &env, &imported_signature, |env, args| {
|
||||
let imported =
|
||||
Function::new_with_env(&mut store, &env, &imported_signature, |env, args| {
|
||||
log!("Calling `imported`...");
|
||||
let result = args[0].unwrap_i32() * env.data().multiplier;
|
||||
log!("Result of `imported`: {:?}", result);
|
||||
@@ -287,7 +287,7 @@ mod js {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
fn imported_fn(_: FunctionEnvMut<'_, ()>, arg: u32) -> u32 {
|
||||
fn imported_fn(arg: u32) -> u32 {
|
||||
return arg + 1;
|
||||
}
|
||||
|
||||
@@ -453,16 +453,13 @@ mod js {
|
||||
|
||||
let env = FunctionEnv::new(&mut store, Env { multiplier: 3 });
|
||||
|
||||
fn imported_fn(
|
||||
env: FunctionEnvMut<'_, Env>,
|
||||
args: &[Val],
|
||||
) -> Result<Vec<Val>, RuntimeError> {
|
||||
fn imported_fn(env: FunctionEnvMut<Env>, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
|
||||
let value = env.data().multiplier * args[0].unwrap_i32() as u32;
|
||||
return Ok(vec![Val::I32(value as _)]);
|
||||
}
|
||||
|
||||
let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
|
||||
let imported = Function::new(&mut store, &env, imported_signature, imported_fn);
|
||||
let imported = Function::new_with_env(&mut store, &env, imported_signature, imported_fn);
|
||||
|
||||
let expected = vec![Val::I32(12)].into_boxed_slice();
|
||||
assert_eq!(imported.call(&mut store, &[Val::I32(4)]), Ok(expected));
|
||||
@@ -522,7 +519,7 @@ mod js {
|
||||
);
|
||||
|
||||
let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
|
||||
let imported = Function::new(&mut store, &env, imported_signature, imported_fn);
|
||||
let imported = Function::new_with_env(&mut store, &env, imported_signature, imported_fn);
|
||||
|
||||
let import_object = imports! {
|
||||
"env" => {
|
||||
@@ -625,7 +622,7 @@ mod js {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
fn sum(_: FunctionEnvMut<'_, ()>, a: i32, b: i32) -> i32 {
|
||||
fn sum(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
@@ -664,7 +661,7 @@ mod js {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
fn early_exit(_: FunctionEnvMut<'_, ()>) {
|
||||
fn early_exit() {
|
||||
panic!("Do panic")
|
||||
}
|
||||
|
||||
@@ -727,7 +724,7 @@ mod js {
|
||||
|
||||
impl std::error::Error for ExitCode {}
|
||||
|
||||
fn early_exit(_: FunctionEnvMut<'_, ()>) -> Result<(), ExitCode> {
|
||||
fn early_exit() -> Result<(), ExitCode> {
|
||||
Err(ExitCode(1))
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ mod sys {
|
||||
minimum: 0,
|
||||
maximum: None,
|
||||
};
|
||||
let f = Function::new_typed(&mut store, |_env: FunctionEnvMut<()>| {});
|
||||
let f = Function::new_typed(&mut store, || {});
|
||||
let table = Table::new(&mut store, table_type, Value::FuncRef(Some(f)))?;
|
||||
assert_eq!(table.ty(&mut store), table_type);
|
||||
|
||||
@@ -94,7 +94,7 @@ mod sys {
|
||||
minimum: 0,
|
||||
maximum: Some(1),
|
||||
};
|
||||
let f = Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, num: i32| num + 1);
|
||||
let f = Function::new_typed(&mut store, |num: i32| num + 1);
|
||||
let table = Table::new(&mut store, table_type, Value::FuncRef(Some(f)))?;
|
||||
assert_eq!(table.ty(&mut store), table_type);
|
||||
let _elem = table.get(&mut store, 0).unwrap();
|
||||
@@ -117,7 +117,7 @@ mod sys {
|
||||
minimum: 0,
|
||||
maximum: Some(10),
|
||||
};
|
||||
let f = Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, num: i32| num + 1);
|
||||
let f = Function::new_typed(&mut store, |num: i32| num + 1);
|
||||
let table = Table::new(&mut store, table_type, Value::FuncRef(Some(f.clone())))?;
|
||||
// Growing to a bigger maximum should return None
|
||||
let old_len = table.grow(&mut store, 12, Value::FuncRef(Some(f.clone())));
|
||||
@@ -182,33 +182,28 @@ mod sys {
|
||||
#[test]
|
||||
fn function_new() -> Result<()> {
|
||||
let mut store = Store::default();
|
||||
let function = Function::new_typed(&mut store, |_env: FunctionEnvMut<()>| {});
|
||||
let function = Function::new_typed(&mut store, || {});
|
||||
assert_eq!(
|
||||
function.ty(&mut store).clone(),
|
||||
FunctionType::new(vec![], vec![])
|
||||
);
|
||||
let function = Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, _a: i32| {});
|
||||
let function = Function::new_typed(&mut store, |_a: i32| {});
|
||||
assert_eq!(
|
||||
function.ty(&mut store).clone(),
|
||||
FunctionType::new(vec![Type::I32], vec![])
|
||||
);
|
||||
let function = Function::new_typed(
|
||||
&mut store,
|
||||
|_env: FunctionEnvMut<()>, _a: i32, _b: i64, _c: f32, _d: f64| {},
|
||||
);
|
||||
let function = Function::new_typed(&mut store, |_a: i32, _b: i64, _c: f32, _d: f64| {});
|
||||
assert_eq!(
|
||||
function.ty(&mut store).clone(),
|
||||
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![])
|
||||
);
|
||||
let function = Function::new_typed(&mut store, |_env: FunctionEnvMut<()>| -> i32 { 1 });
|
||||
let function = Function::new_typed(&mut store, || -> i32 { 1 });
|
||||
assert_eq!(
|
||||
function.ty(&mut store).clone(),
|
||||
FunctionType::new(vec![], vec![Type::I32])
|
||||
);
|
||||
let function = Function::new_typed(
|
||||
&mut store,
|
||||
|_env: FunctionEnvMut<()>| -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) },
|
||||
);
|
||||
let function =
|
||||
Function::new_typed(&mut store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) });
|
||||
assert_eq!(
|
||||
function.ty(&mut store).clone(),
|
||||
FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64])
|
||||
|
||||
@@ -192,35 +192,35 @@ mod sys {
|
||||
let module = Module::new(&store, wat)?;
|
||||
let imports = imports! {
|
||||
"host" => {
|
||||
"host_func1" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: u64| {
|
||||
"host_func1" => Function::new_typed(&mut store, |p: u64| {
|
||||
println!("host_func1: Found number {}", p);
|
||||
assert_eq!(p, u64::max_value());
|
||||
}),
|
||||
"host_func2" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: u32| {
|
||||
"host_func2" => Function::new_typed(&mut store, |p: u32| {
|
||||
println!("host_func2: Found number {}", p);
|
||||
assert_eq!(p, u32::max_value());
|
||||
}),
|
||||
"host_func3" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: i64| {
|
||||
"host_func3" => Function::new_typed(&mut store, |p: i64| {
|
||||
println!("host_func3: Found number {}", p);
|
||||
assert_eq!(p, -1);
|
||||
}),
|
||||
"host_func4" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: i32| {
|
||||
"host_func4" => Function::new_typed(&mut store, |p: i32| {
|
||||
println!("host_func4: Found number {}", p);
|
||||
assert_eq!(p, -1);
|
||||
}),
|
||||
"host_func5" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: i16| {
|
||||
"host_func5" => Function::new_typed(&mut store, |p: i16| {
|
||||
println!("host_func5: Found number {}", p);
|
||||
assert_eq!(p, -1);
|
||||
}),
|
||||
"host_func6" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: u16| {
|
||||
"host_func6" => Function::new_typed(&mut store, |p: u16| {
|
||||
println!("host_func6: Found number {}", p);
|
||||
assert_eq!(p, u16::max_value());
|
||||
}),
|
||||
"host_func7" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: i8| {
|
||||
"host_func7" => Function::new_typed(&mut store, |p: i8| {
|
||||
println!("host_func7: Found number {}", p);
|
||||
assert_eq!(p, -1);
|
||||
}),
|
||||
"host_func8" => Function::new_typed(&mut store, |_env: FunctionEnvMut<()>, p: u8| {
|
||||
"host_func8" => Function::new_typed(&mut store, |p: u8| {
|
||||
println!("host_func8: Found number {}", p);
|
||||
assert_eq!(p, u8::max_value());
|
||||
}),
|
||||
|
||||
@@ -109,7 +109,7 @@ mod sys {
|
||||
|
||||
let instance = Instance::new(&mut store, &module, &imports)?;
|
||||
{
|
||||
fn sum(_env: FunctionEnvMut<()>, a: i32, b: i32) -> i32 {
|
||||
fn sum(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
let sum_func = Function::new_typed(&mut store, sum);
|
||||
|
||||
@@ -180,30 +180,27 @@ fn static_function(config: crate::Config) -> Result<()> {
|
||||
let module = get_module(&store)?;
|
||||
|
||||
static HITS: AtomicUsize = AtomicUsize::new(0);
|
||||
let f0 = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>| {
|
||||
let f0 = Function::new_typed(&mut store, || {
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 0);
|
||||
});
|
||||
let f1 = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>, x: i32| -> i32 {
|
||||
let f1 = Function::new_typed(&mut store, |x: i32| -> i32 {
|
||||
assert_eq!(x, 0);
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 1);
|
||||
1
|
||||
});
|
||||
let f2 = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>, x: i32, y: i64| {
|
||||
let f2 = Function::new_typed(&mut store, |x: i32, y: i64| {
|
||||
assert_eq!(x, 2);
|
||||
assert_eq!(y, 3);
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 2);
|
||||
});
|
||||
let f3 = Function::new_typed(
|
||||
&mut store,
|
||||
|_env: FunctionEnvMut<_>, a: i32, b: i64, c: i32, d: f32, e: f64| {
|
||||
let f3 = Function::new_typed(&mut store, |a: i32, b: i64, c: i32, d: f32, e: f64| {
|
||||
assert_eq!(a, 100);
|
||||
assert_eq!(b, 200);
|
||||
assert_eq!(c, 300);
|
||||
assert_eq!(d, 400.0);
|
||||
assert_eq!(e, 500.0);
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 3);
|
||||
},
|
||||
);
|
||||
});
|
||||
Instance::new(
|
||||
&mut store,
|
||||
&module,
|
||||
@@ -227,33 +224,27 @@ fn static_function_with_results(config: crate::Config) -> Result<()> {
|
||||
let module = get_module(&store)?;
|
||||
|
||||
static HITS: AtomicUsize = AtomicUsize::new(0);
|
||||
let f0 = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>| {
|
||||
let f0 = Function::new_typed(&mut store, || {
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 0);
|
||||
});
|
||||
let f1 = Function::new_typed(
|
||||
&mut store,
|
||||
|_env: FunctionEnvMut<_>, x: i32| -> Result<i32, Infallible> {
|
||||
let f1 = Function::new_typed(&mut store, |x: i32| -> Result<i32, Infallible> {
|
||||
assert_eq!(x, 0);
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 1);
|
||||
Ok(1)
|
||||
},
|
||||
);
|
||||
let f2 = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>, x: i32, y: i64| {
|
||||
});
|
||||
let f2 = Function::new_typed(&mut store, |x: i32, y: i64| {
|
||||
assert_eq!(x, 2);
|
||||
assert_eq!(y, 3);
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 2);
|
||||
});
|
||||
let f3 = Function::new_typed(
|
||||
&mut store,
|
||||
|_env: FunctionEnvMut<_>, a: i32, b: i64, c: i32, d: f32, e: f64| {
|
||||
let f3 = Function::new_typed(&mut store, |a: i32, b: i64, c: i32, d: f32, e: f64| {
|
||||
assert_eq!(a, 100);
|
||||
assert_eq!(b, 200);
|
||||
assert_eq!(c, 300);
|
||||
assert_eq!(d, 400.0);
|
||||
assert_eq!(e, 500.0);
|
||||
assert_eq!(HITS.fetch_add(1, SeqCst), 3);
|
||||
},
|
||||
);
|
||||
});
|
||||
Instance::new(
|
||||
&mut store,
|
||||
&module,
|
||||
@@ -349,14 +340,9 @@ fn static_function_that_fails(config: crate::Config) -> Result<()> {
|
||||
"#;
|
||||
|
||||
let module = Module::new(&store, &wat)?;
|
||||
let mut env = FunctionEnv::new(&mut store, ());
|
||||
let f0 = Function::new_typed_with_env(
|
||||
&mut store,
|
||||
&env,
|
||||
|_env: FunctionEnvMut<_>| -> Result<Infallible, RuntimeError> {
|
||||
let f0 = Function::new_typed(&mut store, || -> Result<Infallible, RuntimeError> {
|
||||
Err(RuntimeError::new("oops"))
|
||||
},
|
||||
);
|
||||
});
|
||||
let result = Instance::new(
|
||||
&mut store,
|
||||
&module,
|
||||
|
||||
@@ -305,9 +305,7 @@ fn rust_panic_import(config: crate::Config) -> Result<()> {
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let sig = FunctionType::new(vec![], vec![]);
|
||||
let func = Function::new(&mut store, &sig, |_| panic!("this is a panic"));
|
||||
let f0 = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>| {
|
||||
panic!("this is another panic")
|
||||
});
|
||||
let f0 = Function::new_typed(&mut store, || panic!("this is another panic"));
|
||||
let instance = Instance::new(
|
||||
&mut store,
|
||||
&module,
|
||||
@@ -366,9 +364,7 @@ fn rust_panic_start_function(config: crate::Config) -> Result<()> {
|
||||
.unwrap_err();
|
||||
assert_eq!(err.downcast_ref::<&'static str>(), Some(&"this is a panic"));
|
||||
|
||||
let func = Function::new_typed(&mut store, |_env: FunctionEnvMut<_>| {
|
||||
panic!("this is another panic")
|
||||
});
|
||||
let func = Function::new_typed(&mut store, || panic!("this is another panic"));
|
||||
let err = panic::catch_unwind(AssertUnwindSafe(|| {
|
||||
drop(Instance::new(
|
||||
&mut store,
|
||||
|
||||
@@ -6,19 +6,7 @@ use wasmer::FunctionEnv;
|
||||
use wasmer::Type as ValueType;
|
||||
use wasmer::*;
|
||||
|
||||
fn long_f(
|
||||
_env: FunctionEnvMut<()>,
|
||||
a: u32,
|
||||
b: u32,
|
||||
c: u32,
|
||||
d: u32,
|
||||
e: u32,
|
||||
f: u16,
|
||||
g: u64,
|
||||
h: u64,
|
||||
i: u16,
|
||||
j: u32,
|
||||
) -> u64 {
|
||||
fn long_f(a: u32, b: u32, c: u32, d: u32, e: u32, f: u16, g: u64, h: u64, i: u16, j: u32) -> u64 {
|
||||
j as u64
|
||||
+ i as u64 * 10
|
||||
+ h * 100
|
||||
@@ -95,7 +83,7 @@ fn typed_function_works_for_wasm(config: crate::Config) -> anyhow::Result<()> {
|
||||
fn typed_host_function_closure_panics(config: crate::Config) {
|
||||
let mut store = config.store();
|
||||
let state = 3;
|
||||
Function::new_typed(&mut store, move |_env: FunctionEnvMut<_>, _: i32| {
|
||||
Function::new_typed(&mut store, move |_: i32| {
|
||||
println!("{}", state);
|
||||
});
|
||||
}
|
||||
@@ -255,22 +243,15 @@ fn typed_function_works_for_wasm_function_manyparams_dynamic(
|
||||
fn static_host_function_without_env(config: crate::Config) -> anyhow::Result<()> {
|
||||
let mut store = config.store();
|
||||
|
||||
fn f(_env: FunctionEnvMut<()>, a: i32, b: i64, c: f32, d: f64) -> (f64, f32, i64, i32) {
|
||||
fn f(a: i32, b: i64, c: f32, d: f64) -> (f64, f32, i64, i32) {
|
||||
(d * 4.0, c * 3.0, b * 2, a * 1)
|
||||
}
|
||||
|
||||
fn f_ok(
|
||||
_env: FunctionEnvMut<()>,
|
||||
a: i32,
|
||||
b: i64,
|
||||
c: f32,
|
||||
d: f64,
|
||||
) -> Result<(f64, f32, i64, i32), Infallible> {
|
||||
fn f_ok(a: i32, b: i64, c: f32, d: f64) -> Result<(f64, f32, i64, i32), Infallible> {
|
||||
Ok((d * 4.0, c * 3.0, b * 2, a * 1))
|
||||
}
|
||||
|
||||
fn long_f(
|
||||
_env: FunctionEnvMut<()>,
|
||||
a: u32,
|
||||
b: u32,
|
||||
c: u32,
|
||||
|
||||
@@ -3,24 +3,16 @@ use wasmer::*;
|
||||
/// Return an instance implementing the "spectest" interface used in the
|
||||
/// spec testsuite.
|
||||
pub fn spectest_importobject(store: &mut Store) -> Imports {
|
||||
let print = Function::new_typed(store, |_: FunctionEnvMut<()>| {});
|
||||
let print_i32 = Function::new_typed(store, |_: FunctionEnvMut<()>, val: i32| {
|
||||
println!("{}: i32", val)
|
||||
});
|
||||
let print_i64 = Function::new_typed(store, |_: FunctionEnvMut<()>, val: i64| {
|
||||
println!("{}: i64", val)
|
||||
});
|
||||
let print_f32 = Function::new_typed(store, |_: FunctionEnvMut<()>, val: f32| {
|
||||
println!("{}: f32", val)
|
||||
});
|
||||
let print_f64 = Function::new_typed(store, |_: FunctionEnvMut<()>, val: f64| {
|
||||
println!("{}: f64", val)
|
||||
});
|
||||
let print_i32_f32 = Function::new_typed(store, |_: FunctionEnvMut<()>, i: i32, f: f32| {
|
||||
let print = Function::new_typed(store, || {});
|
||||
let print_i32 = Function::new_typed(store, |val: i32| println!("{}: i32", val));
|
||||
let print_i64 = Function::new_typed(store, |val: i64| println!("{}: i64", val));
|
||||
let print_f32 = Function::new_typed(store, |val: f32| println!("{}: f32", val));
|
||||
let print_f64 = Function::new_typed(store, |val: f64| println!("{}: f64", val));
|
||||
let print_i32_f32 = Function::new_typed(store, |i: i32, f: f32| {
|
||||
println!("{}: i32", i);
|
||||
println!("{}: f32", f);
|
||||
});
|
||||
let print_f64_f64 = Function::new_typed(store, |_: FunctionEnvMut<()>, f1: f64, f2: f64| {
|
||||
let print_f64_f64 = Function::new_typed(store, |f1: f64, f2: f64| {
|
||||
println!("{}: f64", f1);
|
||||
println!("{}: f64", f2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user