feat(wasm-backend)!: split Function trait, improve naming (#347)

split function interface, improve naming
This commit is contained in:
Valery Antopol
2023-07-25 18:23:54 +03:00
committed by GitHub
parent 974f5931ab
commit 0f9979ae11
21 changed files with 113 additions and 87 deletions

View File

@ -18,10 +18,10 @@ use crate::AsContextMut;
use crate::FuncGetter;
use crate::WasmBackend;
/// `Caller` is a structure used to pass context to imports.
/// `ImportCallContext` is a structure used to pass context to imports.
/// It serves as a handle to `Store`, and also provides access to `Memory` and export functions
/// from the caller instance, if there is one.
pub trait Caller<WB: WasmBackend>:
pub trait ImportCallContext<WB: WasmBackend>:
FuncGetter<WB, (i32, i32), i32>
+ FuncGetter<WB, (i32, i32), ()>
+ FuncGetter<WB, i32, i32>

View File

@ -24,7 +24,7 @@ use crate::WasmBackend;
#[derive(Clone)]
pub enum Export<WB: WasmBackend> {
Memory(<WB as WasmBackend>::Memory),
Function(<WB as WasmBackend>::Function),
Function(<WB as WasmBackend>::ExportFunction),
Other,
}

View File

@ -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;
});
}

View File

@ -36,7 +36,7 @@ pub trait Imports<WB: WasmBackend>: Clone {
store: &impl AsContext<WB>,
module: impl Into<String>,
name: impl Into<String>,
func: <WB as WasmBackend>::Function,
func: <WB as WasmBackend>::HostFunction,
) -> Result<(), ImportError>;
/// Inserts several named functions to the same namespace `module` at once, an equivalent to multiple calls of `insert`.
@ -51,7 +51,7 @@ pub trait Imports<WB: WasmBackend>: Clone {
) -> Result<(), ImportError>
where
S: Into<String>,
I: IntoIterator<Item = (String, <WB as WasmBackend>::Function)>;
I: IntoIterator<Item = (String, <WB as WasmBackend>::HostFunction)>;
}
/// A type representing function signature.
@ -82,7 +82,7 @@ impl FuncSig {
}
}
pub type FuncFromCaller<WB, Args, Rets> = Box<
pub type FuncFromImportCallContext<WB, Args, Rets> = Box<
dyn FnMut(&mut <WB as WasmBackend>::ContextMut<'_>, Args) -> RuntimeResult<Rets>
+ Sync
+ Send
@ -91,5 +91,5 @@ pub type FuncFromCaller<WB, Args, Rets> = Box<
pub trait FuncGetter<WB: WasmBackend, Args, Rets> {
/// Gets an export function from the calling instance.
fn get_func(&mut self, name: &str) -> ResolveResult<FuncFromCaller<WB, Args, Rets>>;
fn get_func(&mut self, name: &str) -> ResolveResult<FuncFromImportCallContext<WB, Args, Rets>>;
}

View File

@ -52,5 +52,5 @@ pub trait Instance<WB: WasmBackend>: Clone {
&self,
store: &mut impl AsContextMut<WB>,
name: &str,
) -> ResolveResult<<WB as WasmBackend>::Function>;
) -> ResolveResult<<WB as WasmBackend>::ExportFunction>;
}

View File

@ -69,9 +69,11 @@ pub trait WasmBackend: Clone + Default + 'static {
/// A temporary mutable handle to `Store`
type ContextMut<'c>: ContextMut<Self>;
/// A type that is used to pass context to imports.
type Caller<'c>: Caller<Self>;
/// A function contained in `Store`, either host one or from wasm.
type Function: Function<Self> + FuncConstructor<Self>;
type ImportCallContext<'c>: ImportCallContext<Self>;
/// A host function prepared to be used as import for instantiating a module, contained in `Store`.
type HostFunction: HostFunction<Self> + FuncConstructor<Self>;
/// An export function from a wasm instance, contained in `Store`
type ExportFunction: ExportFunction<Self>;
/// A wasm memory.
type Memory: Memory<Self>;
/// A view to the wasm memory.