diff --git a/lib/runtime-core-tests/tests/imports.rs b/lib/runtime-core-tests/tests/imports.rs index 42a09d84460..ce3cea2c4a9 100644 --- a/lib/runtime-core-tests/tests/imports.rs +++ b/lib/runtime-core-tests/tests/imports.rs @@ -154,7 +154,7 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) { Ok(n + 1) }), - "callback_closure_polymorphic" => Func::::new_polymorphic( + "callback_closure_polymorphic" => Func::new_polymorphic( Arc::new(FuncSig::new(vec![Type::I32], vec![Type::I32])), |_, params| -> Vec { match params[0] { diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index eca73f61b86..4abad5a1741 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -189,9 +189,21 @@ where /// Represents a function that can be used by WebAssembly. pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> { inner: Inner, + + /// The function pointer. func: NonNull, + + /// The function environment. func_env: Option>, + + /// The famous `vm::Ctx`. vmctx: *mut vm::Ctx, + + /// The signature is usually infered from `Args` and `Rets`. In + /// case of polymorphic function, the signature is only known at + /// runtime. + signature: Arc, + _phantom: PhantomData<(&'a (), Args, Rets)>, } @@ -214,6 +226,7 @@ where func, func_env, vmctx, + signature: Arc::new(FuncSig::new(Args::types(), Rets::types())), _phantom: PhantomData, } } @@ -225,7 +238,7 @@ where Rets: WasmTypeList, { /// Creates a new `Func`. - pub fn new(func: F) -> Func<'a, Args, Rets, Host> + pub fn new(func: F) -> Self where Kind: ExternalFunctionKind, F: ExternalFunction, @@ -237,14 +250,17 @@ where func, func_env, vmctx: ptr::null_mut(), + signature: Arc::new(FuncSig::new(Args::types(), Rets::types())), _phantom: PhantomData, } } +} +impl<'a> Func<'a, (), (), Host> { /// Creates a polymorphic function. #[allow(unused_variables)] #[cfg(all(unix, target_arch = "x86_64"))] - pub fn new_polymorphic(signature: Arc, func: F) -> Func<'a, Args, Rets, Host> + pub fn new_polymorphic(signature: Arc, func: F) -> Self where F: Fn(&mut vm::Ctx, &[crate::types::Value]) -> Vec + 'static, { @@ -305,11 +321,13 @@ where let ptr = builder .append_global() .expect("cannot bump-allocate global trampoline memory"); + Func { inner: Host(()), func: ptr.cast::(), func_env: None, vmctx: ptr::null_mut(), + signature, _phantom: PhantomData, } } @@ -751,12 +769,11 @@ where func_env @ Some(_) => Context::ExternalWithEnv(self.vmctx, func_env), None => Context::Internal, }; - let signature = Arc::new(FuncSig::new(Args::types(), Rets::types())); Export::Function { func, ctx, - signature, + signature: self.signature.clone(), } } }