|
|
|
@ -21,9 +21,9 @@ use crate::RuntimeResult;
|
|
|
|
|
use crate::WasmBackend;
|
|
|
|
|
use crate::WValue;
|
|
|
|
|
|
|
|
|
|
/// A Wasm function handle, it can be either a function from a host or an export from an `Instance`.
|
|
|
|
|
/// As it is only a handle to an object in `Store`, cloning is cheap
|
|
|
|
|
pub trait Function<WB: WasmBackend>: Send + Sync + Clone {
|
|
|
|
|
/// A host function ready to be used as an import for instantiating a module.
|
|
|
|
|
/// As it is only a handle to an object in `Store`, cloning is cheap.
|
|
|
|
|
pub trait HostFunction<WB: WasmBackend>: Send + Sync + Clone {
|
|
|
|
|
/// Creates a new function with dynamic signature.
|
|
|
|
|
/// The signature check is performed at runtime.
|
|
|
|
|
fn new<F>(store: &mut impl AsContextMut<WB>, sig: FuncSig, func: F) -> Self
|
|
|
|
@ -33,7 +33,7 @@ pub trait Function<WB: WasmBackend>: Send + Sync + Clone {
|
|
|
|
|
/// Creates a new function with dynamic signature that needs a context.
|
|
|
|
|
fn new_with_caller<F>(store: &mut impl AsContextMut<WB>, sig: FuncSig, func: F) -> Self
|
|
|
|
|
where
|
|
|
|
|
F: for<'c> Fn(<WB as WasmBackend>::Caller<'c>, &[WValue]) -> Vec<WValue>
|
|
|
|
|
F: for<'c> Fn(<WB as WasmBackend>::ImportCallContext<'c>, &[WValue]) -> Vec<WValue>
|
|
|
|
|
+ Sync
|
|
|
|
|
+ Send
|
|
|
|
|
+ 'static;
|
|
|
|
@ -49,6 +49,15 @@ pub trait Function<WB: WasmBackend>: Send + Sync + Clone {
|
|
|
|
|
/// The signature is constructed each time this function is called, so
|
|
|
|
|
/// it is not recommended to use this function extensively.
|
|
|
|
|
fn signature(&self, store: &mut impl AsContextMut<WB>) -> FuncSig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A Wasm function handle, it can be either a function from a host or an export from an `Instance`.
|
|
|
|
|
/// As it is only a handle to an object in `Store`, cloning is cheap
|
|
|
|
|
pub trait ExportFunction<WB: WasmBackend>: Send + Sync + Clone {
|
|
|
|
|
/// Returns the signature of the function.
|
|
|
|
|
/// The signature is constructed each time this function is called, so
|
|
|
|
|
/// it is not recommended to use this function extensively.
|
|
|
|
|
fn signature(&self, store: &mut impl AsContextMut<WB>) -> FuncSig;
|
|
|
|
|
|
|
|
|
|
/// Calls the wasm function.
|
|
|
|
|
/// # Panics:
|
|
|
|
@ -66,17 +75,17 @@ pub trait Function<WB: WasmBackend>: Send + Sync + Clone {
|
|
|
|
|
/// Should not be implemented by users.
|
|
|
|
|
/// Implemented for all functions that meet the following criteria:
|
|
|
|
|
/// * implement Send + Sync + 'static
|
|
|
|
|
/// * take or not take Caller as first parameter
|
|
|
|
|
/// * take or not take ImportCallContext as first parameter
|
|
|
|
|
/// * take from 0 to 16 i32 parameters
|
|
|
|
|
/// * return () or i32
|
|
|
|
|
pub trait IntoFunc<WB: WasmBackend, Params, Results, Env> {
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::Function;
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::HostFunction;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An indicator of using Caller argument.
|
|
|
|
|
/// An indicator of using ImportCallContext argument.
|
|
|
|
|
pub struct WithEnv {}
|
|
|
|
|
|
|
|
|
|
/// An indicator of using Caller argument.
|
|
|
|
|
/// An indicator of using ImportCallContext argument.
|
|
|
|
|
pub struct WithoutEnv {}
|
|
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
@ -94,8 +103,8 @@ macro_rules! impl_into_func {
|
|
|
|
|
WB: WasmBackend,
|
|
|
|
|
F: Fn($(replace_with!($args -> i32),)*) + Send + Sync + 'static,
|
|
|
|
|
{
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::Function {
|
|
|
|
|
<WB as WasmBackend>::Function:: [< new_typed_ $num >] (ctx.as_context_mut(), self)
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::HostFunction {
|
|
|
|
|
<WB as WasmBackend>::HostFunction:: [< new_typed_ $num >] (ctx.as_context_mut(), self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -103,10 +112,10 @@ macro_rules! impl_into_func {
|
|
|
|
|
impl<WB, F> IntoFunc<WB, ($(replace_with!($args -> i32),)*), (), WithEnv> for F
|
|
|
|
|
where
|
|
|
|
|
WB: WasmBackend,
|
|
|
|
|
F: Fn(<WB as WasmBackend>::Caller<'_>, $(replace_with!($args -> i32),)*) + Send + Sync + 'static,
|
|
|
|
|
F: Fn(<WB as WasmBackend>::ImportCallContext<'_>, $(replace_with!($args -> i32),)*) + Send + Sync + 'static,
|
|
|
|
|
{
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::Function {
|
|
|
|
|
<WB as WasmBackend>::Function:: [< new_typed_with_env_ $num >] (ctx.as_context_mut(), self)
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::HostFunction {
|
|
|
|
|
<WB as WasmBackend>::HostFunction:: [< new_typed_with_env_ $num >] (ctx.as_context_mut(), self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -116,8 +125,8 @@ macro_rules! impl_into_func {
|
|
|
|
|
WB: WasmBackend,
|
|
|
|
|
F: Fn($(replace_with!($args -> i32),)*) -> i32 + Send + Sync + 'static,
|
|
|
|
|
{
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::Function {
|
|
|
|
|
<WB as WasmBackend>::Function:: [< new_typed_ $num _r >] (ctx.as_context_mut(), self)
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::HostFunction {
|
|
|
|
|
<WB as WasmBackend>::HostFunction:: [< new_typed_ $num _r >] (ctx.as_context_mut(), self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -125,10 +134,10 @@ macro_rules! impl_into_func {
|
|
|
|
|
impl<WB, F> IntoFunc<WB, ($(replace_with!($args -> i32),)*), i32, WithEnv> for F
|
|
|
|
|
where
|
|
|
|
|
WB: WasmBackend,
|
|
|
|
|
F: Fn(<WB as WasmBackend>::Caller<'_>, $(replace_with!($args -> i32),)*) -> i32 + Send + Sync + 'static,
|
|
|
|
|
F: Fn(<WB as WasmBackend>::ImportCallContext<'_>, $(replace_with!($args -> i32),)*) -> i32 + Send + Sync + 'static,
|
|
|
|
|
{
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::Function {
|
|
|
|
|
<WB as WasmBackend>::Function:: [< new_typed_with_env_ $num _r >] (ctx.as_context_mut(), self)
|
|
|
|
|
fn into_func(self, ctx: &mut impl AsContextMut<WB>) -> <WB as WasmBackend>::HostFunction {
|
|
|
|
|
<WB as WasmBackend>::HostFunction:: [< new_typed_with_env_ $num _r >] (ctx.as_context_mut(), self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -139,28 +148,28 @@ impl_for_each_function_signature!(impl_into_func);
|
|
|
|
|
macro_rules! declare_func_construction {
|
|
|
|
|
($num:tt $($args:ident)*) => (paste::paste!{
|
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
|
fn [< new_typed_ $num >]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::Function
|
|
|
|
|
fn [< new_typed_ $num >]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::HostFunction
|
|
|
|
|
where F: Fn($(replace_with!($args -> i32),)*) + Send + Sync + 'static
|
|
|
|
|
{
|
|
|
|
|
let func = move |_: <WB as WasmBackend>::Caller<'_>, $($args,)*| { func($($args,)*)};
|
|
|
|
|
let func = move |_: <WB as WasmBackend>::ImportCallContext<'_>, $($args,)*| { func($($args,)*)};
|
|
|
|
|
Self:: [< new_typed_with_env_ $num >] (ctx, func)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
|
fn [< new_typed_with_env_ $num >]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::Function
|
|
|
|
|
where F: Fn(<WB as WasmBackend>::Caller<'_>, $(replace_with!($args -> i32),)*) + Send + Sync + 'static;
|
|
|
|
|
fn [< new_typed_with_env_ $num >]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::HostFunction
|
|
|
|
|
where F: Fn(<WB as WasmBackend>::ImportCallContext<'_>, $(replace_with!($args -> i32),)*) + Send + Sync + 'static;
|
|
|
|
|
|
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
|
fn [< new_typed_ $num _r>]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::Function
|
|
|
|
|
fn [< new_typed_ $num _r>]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::HostFunction
|
|
|
|
|
where F: Fn($(replace_with!($args -> i32),)*) -> i32 + Send + Sync + 'static
|
|
|
|
|
{
|
|
|
|
|
let func = move |_: <WB as WasmBackend>::Caller<'_>, $($args,)*| -> i32 { func($($args,)*)};
|
|
|
|
|
let func = move |_: <WB as WasmBackend>::ImportCallContext<'_>, $($args,)*| -> i32 { func($($args,)*)};
|
|
|
|
|
Self:: [< new_typed_with_env_ $num _r >] (ctx, func)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
|
fn [< new_typed_with_env_ $num _r>]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::Function
|
|
|
|
|
where F: Fn(<WB as WasmBackend>::Caller<'_>, $(replace_with!($args -> i32),)*) -> i32 + Send + Sync + 'static;
|
|
|
|
|
fn [< new_typed_with_env_ $num _r>]<F>(ctx: <WB as WasmBackend>::ContextMut<'_>, func: F) -> <WB as WasmBackend>::HostFunction
|
|
|
|
|
where F: Fn(<WB as WasmBackend>::ImportCallContext<'_>, $(replace_with!($args -> i32),)*) -> i32 + Send + Sync + 'static;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|