From 50ba29d6eb92dc10b104e9149f7e01c108d6c500 Mon Sep 17 00:00:00 2001 From: Wolfgang Silbermayr Date: Thu, 4 Aug 2022 13:16:49 +0200 Subject: [PATCH] =?UTF-8?q?No=20longer=20require=20FunctionEnvMut=20for=20?= =?UTF-8?q?new=5Ftyped(=E2=80=A6)=20callback=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/early_exit.rs | 4 +- examples/hello_world.rs | 4 +- examples/table.rs | 5 +- lib/api/src/js/exports.rs | 2 +- lib/api/src/js/externals/function.rs | 127 +++++++++++++++++++-- lib/api/src/js/native.rs | 10 +- lib/api/src/lib.rs | 2 +- lib/api/src/sys/externals/function.rs | 155 ++++++++++++++++++++++++-- lib/api/src/sys/imports.rs | 9 +- lib/api/tests/js_externals.rs | 32 ++---- lib/api/tests/js_instance.rs | 33 +++--- lib/api/tests/sys_externals.rs | 23 ++-- lib/api/tests/sys_module.rs | 16 +-- lib/api/tests/sys_reference_types.rs | 2 +- tests/compilers/imports.rs | 72 +++++------- tests/compilers/traps.rs | 8 +- tests/compilers/typed_functions.rs | 27 +---- tests/lib/wast/src/spectest.rs | 22 ++-- 18 files changed, 364 insertions(+), 189 deletions(-) diff --git a/examples/early_exit.rs b/examples/early_exit.rs index 1a0ec8e37b5..17d1b2ef9f2 100644 --- a/examples/early_exit.rs +++ b/examples/early_exit.rs @@ -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)) } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 0b5221f4733..35a10f4b2e2 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -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!") } diff --git a/examples/table.rs b/examples/table.rs index c3b9b35b7d6..65dc3f4f45d 100644 --- a/examples/table.rs +++ b/examples/table.rs @@ -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 } diff --git a/lib/api/src/js/exports.rs b/lib/api/src/js/exports.rs index 6c4a8a9deb5..024ab8b9696 100644 --- a/lib/api/src/js/exports.rs +++ b/lib/api/src/js/exports.rs @@ -162,7 +162,7 @@ impl Exports { Rets: WasmTypeList, { self.get_function(name)? - .native(store) + .typed(store) .map_err(|_| ExportError::IncompatibleType) } diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index c02a3285fca..3c7bd3017c9 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -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(store: &mut impl AsStoreMut, ty: FT, func: F) -> Self where FT: Into, @@ -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(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(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::() != 0 { + Self::closures_unsupported_panic(); + } + let function = inner::Function::::new(func); + let address = function.address() as usize as u32; + + let ft = wasm_bindgen::function_table(); + let as_table = ft.unchecked_ref::(); + 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, + F: HostFunction, Args: WasmTypeList, Rets: WasmTypeList, { @@ -223,7 +265,7 @@ impl Function { func: F, ) -> Self where - F: HostFunction, + F: HostFunction, 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 + pub trait HostFunction 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(function: F) -> Self + pub fn new(function: F) -> Self where - F: HostFunction, + F: HostFunction, 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 + HostFunction 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, + 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, + 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 + } + } }; } diff --git a/lib/api/src/js/native.rs b/lib/api/src/js/native.rs index d2056323d03..0e9066edac8 100644 --- a/lib/api/src/js/native.rs +++ b/lib/api/src/js/native.rs @@ -5,7 +5,7 @@ //! //! ```ignore //! let add_one = instance.exports.get_function("function_name")?; -//! let add_one_native: TypedFunction = add_one.native().unwrap(); +//! let add_one_native: TypedFunction = add_one.typed().unwrap(); //! ``` use std::marker::PhantomData; @@ -37,11 +37,7 @@ where Rets: WasmTypeList, { #[allow(dead_code)] - pub(crate) fn new( - store: &mut impl AsStoreMut, - _env: &FunctionEnv, - vm_function: VMFunction, - ) -> Self { + pub(crate) fn new(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 { 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) } } }; diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs index 777ace97093..663903104ba 100644 --- a/lib/api/src/lib.rs +++ b/lib/api/src/lib.rs @@ -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, //! } //! } diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index f5419cc2f05..1aa1c5f03c9 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -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(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(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 = >::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 = + >::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 + 'static + Send + Sync, + F: HostFunction + 'static + Send + Sync, Args: WasmTypeList, Rets: WasmTypeList, { @@ -251,7 +283,7 @@ impl Function { func: F, ) -> Self where - F: HostFunction + 'static + Send + Sync, + F: HostFunction + '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 = >::function_body_ptr(); + let func_ptr = >::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 = >::call_trampoline_address(); + let call_trampoline = + >::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 + pub trait HostFunction 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 + HostFunction 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, + 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, $( $x: <$x::Native as NativeWasmType>::Abi, )* ) -> Rets::CStruct + where + $( $x: FromToNativeWasmType, )* + Rets: WasmTypeList, + RetsAsResult: IntoResult, + 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> + } + + } }; } diff --git a/lib/api/src/sys/imports.rs b/lib/api/src/sys/imports.rs index c6e279bf533..c9a9f22b917 100644 --- a/lib/api/src/sys/imports.rs +++ b/lib/api/src/sys/imports.rs @@ -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 } diff --git a/lib/api/tests/js_externals.rs b/lib/api/tests/js_externals.rs index 71b81cff0c1..4795c1ba49e 100644 --- a/lib/api/tests/js_externals.rs +++ b/lib/api/tests/js_externals.rs @@ -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); diff --git a/lib/api/tests/js_instance.rs b/lib/api/tests/js_instance.rs index c61519801c1..4b829ab810d 100644 --- a/lib/api/tests/js_instance.rs +++ b/lib/api/tests/js_instance.rs @@ -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,12 +238,13 @@ 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| { - log!("Calling `imported`..."); - let result = args[0].unwrap_i32() * env.data().multiplier; - log!("Result of `imported`: {:?}", result); - Ok(vec![Value::I32(result)]) - }); + 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); + Ok(vec![Value::I32(result)]) + }); let import_object = imports! { "env" => { @@ -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, RuntimeError> { + fn imported_fn(env: FunctionEnvMut, args: &[Val]) -> Result, 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)) } diff --git a/lib/api/tests/sys_externals.rs b/lib/api/tests/sys_externals.rs index 9bb6630b8bf..1719dc4b5cb 100644 --- a/lib/api/tests/sys_externals.rs +++ b/lib/api/tests/sys_externals.rs @@ -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]) diff --git a/lib/api/tests/sys_module.rs b/lib/api/tests/sys_module.rs index 521ad320741..633fa7a477e 100644 --- a/lib/api/tests/sys_module.rs +++ b/lib/api/tests/sys_module.rs @@ -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()); }), diff --git a/lib/api/tests/sys_reference_types.rs b/lib/api/tests/sys_reference_types.rs index f2cf89b3a81..ca063dbf084 100644 --- a/lib/api/tests/sys_reference_types.rs +++ b/lib/api/tests/sys_reference_types.rs @@ -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); diff --git a/tests/compilers/imports.rs b/tests/compilers/imports.rs index 696a86b8594..60d452ac62f 100644 --- a/tests/compilers/imports.rs +++ b/tests/compilers/imports.rs @@ -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| { - 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); - }, - ); + 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 { - 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 f1 = Function::new_typed(&mut store, |x: i32| -> Result { + assert_eq!(x, 0); + assert_eq!(HITS.fetch_add(1, SeqCst), 1); + Ok(1) + }); + 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| { - 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); - }, - ); + 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 { - Err(RuntimeError::new("oops")) - }, - ); + let f0 = Function::new_typed(&mut store, || -> Result { + Err(RuntimeError::new("oops")) + }); let result = Instance::new( &mut store, &module, diff --git a/tests/compilers/traps.rs b/tests/compilers/traps.rs index 7f7dbc2bd6d..5c0e6a20d08 100644 --- a/tests/compilers/traps.rs +++ b/tests/compilers/traps.rs @@ -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, diff --git a/tests/compilers/typed_functions.rs b/tests/compilers/typed_functions.rs index 6cee8ad9110..c6c09b07272 100644 --- a/tests/compilers/typed_functions.rs +++ b/tests/compilers/typed_functions.rs @@ -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, diff --git a/tests/lib/wast/src/spectest.rs b/tests/lib/wast/src/spectest.rs index 16e3aea21ed..9c2433ecd48 100644 --- a/tests/lib/wast/src/spectest.rs +++ b/tests/lib/wast/src/spectest.rs @@ -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); });