#[cfg(feature = "experimental-async")]
use crate::AsStoreAsync;
use crate::{
AsStoreMut, AsStoreRef, FunctionEnv, FunctionEnvMut, StoreMut, StoreRef,
macros::backend::match_rt,
};
use std::{any::Any, marker::PhantomData};
#[derive(Debug, derive_more::From)]
pub enum BackendFunctionEnv<T> {
#[cfg(feature = "sys")]
Sys(crate::backend::sys::function::env::FunctionEnv<T>),
#[cfg(feature = "wamr")]
Wamr(crate::backend::wamr::function::env::FunctionEnv<T>),
#[cfg(feature = "wasmi")]
Wasmi(crate::backend::wasmi::function::env::FunctionEnv<T>),
#[cfg(feature = "v8")]
V8(crate::backend::v8::function::env::FunctionEnv<T>),
#[cfg(feature = "js")]
Js(crate::backend::js::function::env::FunctionEnv<T>),
#[cfg(feature = "jsc")]
Jsc(crate::backend::jsc::function::env::FunctionEnv<T>),
}
impl<T> Clone for BackendFunctionEnv<T> {
fn clone(&self) -> Self {
match self {
#[cfg(feature = "sys")]
Self::Sys(s) => Self::Sys(s.clone()),
#[cfg(feature = "wamr")]
Self::Wamr(s) => Self::Wamr(s.clone()),
#[cfg(feature = "wasmi")]
Self::Wasmi(s) => Self::Wasmi(s.clone()),
#[cfg(feature = "v8")]
Self::V8(s) => Self::V8(s.clone()),
#[cfg(feature = "js")]
Self::Js(s) => Self::Js(s.clone()),
#[cfg(feature = "jsc")]
Self::Jsc(s) => Self::Jsc(s.clone()),
}
}
}
impl<T> BackendFunctionEnv<T> {
pub fn new(store: &mut impl AsStoreMut, value: T) -> Self
where
T: Any + Send + 'static + Sized,
{
match store.as_store_mut().inner.store {
#[cfg(feature = "sys")]
crate::BackendStore::Sys(_) => Self::Sys(
crate::backend::sys::function::env::FunctionEnv::new(store, value),
),
#[cfg(feature = "wamr")]
crate::BackendStore::Wamr(_) => Self::Wamr(
crate::backend::wamr::function::env::FunctionEnv::new(store, value),
),
#[cfg(feature = "wasmi")]
crate::BackendStore::Wasmi(_) => Self::Wasmi(
crate::backend::wasmi::function::env::FunctionEnv::new(store, value),
),
#[cfg(feature = "v8")]
crate::BackendStore::V8(_) => Self::V8(
crate::backend::v8::function::env::FunctionEnv::new(store, value),
),
#[cfg(feature = "js")]
crate::BackendStore::Js(_) => Self::Js(
crate::backend::js::function::env::FunctionEnv::new(store, value),
),
#[cfg(feature = "jsc")]
crate::BackendStore::Jsc(_) => Self::Jsc(
crate::backend::jsc::function::env::FunctionEnv::new(store, value),
),
}
}
pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T
where
T: Any + Send + 'static + Sized,
{
match_rt!(on self => f {
f.as_ref(store)
})
}
pub fn as_mut<'a>(&self, store: &'a mut impl AsStoreMut) -> &'a mut T
where
T: Any + Send + 'static + Sized,
{
match_rt!(on self => s {
s.as_mut(store)
})
}
pub fn into_mut(self, store: &mut impl AsStoreMut) -> FunctionEnvMut<'_, T>
where
T: Any + Send + 'static + Sized,
{
match_rt!(on self => f {
f.into_mut(store).into()
})
}
}
#[derive(derive_more::From)]
pub enum BackendFunctionEnvMut<'a, T: 'a> {
#[cfg(feature = "sys")]
Sys(crate::backend::sys::function::env::FunctionEnvMut<'a, T>),
#[cfg(feature = "wamr")]
Wamr(crate::backend::wamr::function::env::FunctionEnvMut<'a, T>),
#[cfg(feature = "wasmi")]
Wasmi(crate::backend::wasmi::function::env::FunctionEnvMut<'a, T>),
#[cfg(feature = "v8")]
V8(crate::backend::v8::function::env::FunctionEnvMut<'a, T>),
#[cfg(feature = "js")]
Js(crate::backend::js::function::env::FunctionEnvMut<'a, T>),
#[cfg(feature = "jsc")]
Jsc(crate::backend::jsc::function::env::FunctionEnvMut<'a, T>),
}
impl<T: Send + 'static> BackendFunctionEnvMut<'_, T> {
pub fn data(&self) -> &T {
match_rt!(on self => f {
f.data()
})
}
pub fn data_mut(&mut self) -> &mut T {
match_rt!(on self => f {
f.data_mut()
})
}
pub fn as_ref(&self) -> FunctionEnv<T> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => BackendFunctionEnv::Sys(f.as_ref()).into(),
#[cfg(feature = "wamr")]
Self::Wamr(f) => BackendFunctionEnv::Wamr(f.as_ref()).into(),
#[cfg(feature = "wasmi")]
Self::Wasmi(f) => BackendFunctionEnv::Wasmi(f.as_ref()).into(),
#[cfg(feature = "v8")]
Self::V8(f) => BackendFunctionEnv::V8(f.as_ref()).into(),
#[cfg(feature = "js")]
Self::Js(f) => BackendFunctionEnv::Js(f.as_ref()).into(),
#[cfg(feature = "jsc")]
Self::Jsc(f) => BackendFunctionEnv::Jsc(f.as_ref()).into(),
}
}
pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => BackendFunctionEnvMut::Sys(f.as_mut()).into(),
#[cfg(feature = "wamr")]
Self::Wamr(f) => BackendFunctionEnvMut::Wamr(f.as_mut()).into(),
#[cfg(feature = "wasmi")]
Self::Wasmi(f) => BackendFunctionEnvMut::Wasmi(f.as_mut()).into(),
#[cfg(feature = "v8")]
Self::V8(f) => BackendFunctionEnvMut::V8(f.as_mut()).into(),
#[cfg(feature = "js")]
Self::Js(f) => BackendFunctionEnvMut::Js(f.as_mut()).into(),
#[cfg(feature = "jsc")]
Self::Jsc(f) => BackendFunctionEnvMut::Jsc(f.as_mut()).into(),
}
}
pub fn data_and_store_mut(&mut self) -> (&mut T, StoreMut<'_>) {
match_rt!(on self => f {
f.data_and_store_mut()
})
}
#[cfg(feature = "experimental-async")]
pub fn as_store_async(&self) -> Option<impl AsStoreAsync + 'static> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => f.as_store_async(),
#[cfg(feature = "sys")]
_ => unsupported_async_backend(),
#[cfg(not(feature = "sys"))]
_ => unsupported_async_backend::<Option<crate::StoreAsync>>(),
}
}
}
impl<T> AsStoreRef for BackendFunctionEnvMut<'_, T> {
fn as_store_ref(&self) -> StoreRef<'_> {
match_rt!(on self => s {
s.as_store_ref()
})
}
}
impl<T> AsStoreMut for BackendFunctionEnvMut<'_, T> {
fn as_store_mut(&mut self) -> StoreMut<'_> {
match_rt!(on self => s {
s.as_store_mut()
})
}
fn objects_mut(&mut self) -> &mut crate::StoreObjects {
match_rt!(on self => s {
s.objects_mut()
})
}
}
impl<T> std::fmt::Debug for BackendFunctionEnvMut<'_, T>
where
T: Send + std::fmt::Debug + 'static,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match_rt!(on self => s {
write!(f, "{s:?}")
})
}
}
#[derive(derive_more::From)]
#[cfg(feature = "experimental-async")]
pub enum BackendAsyncFunctionEnvMut<T> {
#[cfg(feature = "sys")]
Sys(crate::backend::sys::function::env::AsyncFunctionEnvMut<T>),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
Unsupported(PhantomData<T>),
}
#[cfg(feature = "experimental-async")]
pub enum BackendAsyncFunctionEnvHandle<T> {
#[cfg(feature = "sys")]
Sys(crate::backend::sys::function::env::AsyncFunctionEnvHandle<T>),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
Unsupported(PhantomData<T>),
}
#[cfg(feature = "experimental-async")]
pub enum BackendAsyncFunctionEnvHandleMut<T> {
#[cfg(feature = "sys")]
Sys(crate::backend::sys::function::env::AsyncFunctionEnvHandleMut<T>),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
Unsupported(PhantomData<T>),
}
#[cfg(feature = "experimental-async")]
impl<T: 'static> BackendAsyncFunctionEnvMut<T> {
pub async fn read(&self) -> BackendAsyncFunctionEnvHandle<T> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => BackendAsyncFunctionEnvHandle::Sys(f.read().await),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
pub async fn write(&self) -> BackendAsyncFunctionEnvHandleMut<T> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => BackendAsyncFunctionEnvHandleMut::Sys(f.write().await),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
pub fn as_ref(&self) -> BackendFunctionEnv<T> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => BackendFunctionEnv::Sys(f.as_ref()),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
pub fn as_mut(&mut self) -> Self {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => Self::Sys(f.as_mut()),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
pub fn as_store_async(&self) -> impl AsStoreAsync + 'static {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => f.as_store_async(),
#[cfg(all(
feature = "sys",
any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
)
))]
_ => unsupported_async_backend(),
#[cfg(all(
not(feature = "sys"),
any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
)
))]
_ => unsupported_async_backend::<crate::StoreAsync>(),
}
}
}
#[cfg(feature = "experimental-async")]
impl<T: 'static> BackendAsyncFunctionEnvHandle<T> {
pub fn data(&self) -> &T {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => f.data(),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
pub fn data_and_store(&self) -> (&T, &impl AsStoreRef) {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => f.data_and_store(),
#[cfg(all(
feature = "sys",
any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
)
))]
_ => unsupported_async_backend(),
#[cfg(all(
not(feature = "sys"),
any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
)
))]
_ => unsupported_async_backend::<(&T, &StoreRef)>(),
}
}
}
#[cfg(feature = "experimental-async")]
impl<T: 'static> AsStoreRef for BackendAsyncFunctionEnvHandle<T> {
fn as_store_ref(&self) -> StoreRef<'_> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => AsStoreRef::as_store_ref(f),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
}
#[cfg(feature = "experimental-async")]
impl<T: 'static> BackendAsyncFunctionEnvHandleMut<T> {
pub fn data_mut(&mut self) -> &mut T {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => f.data_mut(),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
pub fn data_and_store_mut(&mut self) -> (&mut T, &mut impl AsStoreMut) {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => f.data_and_store_mut(),
#[cfg(all(
feature = "sys",
any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
)
))]
_ => unsupported_async_backend(),
#[cfg(all(
not(feature = "sys"),
any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
)
))]
_ => unsupported_async_backend::<(&mut T, &mut crate::StoreMut)>(),
}
}
pub fn as_function_env_mut(&mut self) -> BackendFunctionEnvMut<'_, T> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => BackendFunctionEnvMut::Sys(f.as_function_env_mut()),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
}
#[cfg(feature = "experimental-async")]
impl<T: 'static> AsStoreRef for BackendAsyncFunctionEnvHandleMut<T> {
fn as_store_ref(&self) -> StoreRef<'_> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => AsStoreRef::as_store_ref(f),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
}
#[cfg(feature = "experimental-async")]
impl<T: 'static> AsStoreMut for BackendAsyncFunctionEnvHandleMut<T> {
fn as_store_mut(&mut self) -> StoreMut<'_> {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => AsStoreMut::as_store_mut(f),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
fn objects_mut(&mut self) -> &mut crate::StoreObjects {
match self {
#[cfg(feature = "sys")]
Self::Sys(f) => AsStoreMut::objects_mut(f),
#[cfg(any(
feature = "wamr",
feature = "wasmi",
feature = "v8",
feature = "js",
feature = "jsc"
))]
_ => unsupported_async_backend(),
}
}
}
#[cfg(feature = "experimental-async")]
fn unsupported_async_backend<T>() -> T {
panic!("async functions are only supported with the `sys` backend");
}