wasmer/entities/function/env/
mod.rs

1pub(crate) mod inner;
2pub(crate) use inner::*;
3
4#[cfg(feature = "experimental-async")]
5use crate::AsStoreAsync;
6use crate::{AsStoreMut, AsStoreRef, StoreMut, StoreRef, macros::backend::match_rt};
7use std::{any::Any, fmt::Debug, marker::PhantomData};
8
9#[derive(Debug, derive_more::From)]
10/// An opaque reference to a function environment.
11/// The function environment data is owned by the `Store`.
12pub struct FunctionEnv<T>(pub(crate) BackendFunctionEnv<T>);
13
14impl<T> Clone for FunctionEnv<T> {
15    fn clone(&self) -> Self {
16        Self(self.0.clone())
17    }
18}
19
20impl<T> FunctionEnv<T> {
21    /// Make a new FunctionEnv
22    pub fn new(store: &mut impl AsStoreMut, value: T) -> Self
23    where
24        T: Any + Send + 'static + Sized,
25    {
26        Self(BackendFunctionEnv::new(store, value))
27    }
28
29    //#[allow(dead_code)] // This function is only used in js
30    //pub(crate) fn from_handle(handle: StoreHandle<VMFunctionEnvironment>) -> Self {
31    //    todo!()
32    //}
33
34    /// Get the data as reference
35    pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T
36    where
37        T: Any + Send + 'static + Sized,
38    {
39        self.0.as_ref(store)
40    }
41
42    /// Get the data as mutable
43    pub fn as_mut<'a>(&self, store: &'a mut impl AsStoreMut) -> &'a mut T
44    where
45        T: Any + Send + 'static + Sized,
46    {
47        self.0.as_mut(store)
48    }
49
50    /// Convert it into a `FunctionEnvMut`
51    pub fn into_mut(self, store: &mut impl AsStoreMut) -> FunctionEnvMut<'_, T>
52    where
53        T: Any + Send + 'static + Sized,
54    {
55        self.0.into_mut(store)
56    }
57}
58
59/// A temporary handle to a [`FunctionEnv`].
60#[derive(derive_more::From)]
61pub struct FunctionEnvMut<'a, T: 'a>(pub(crate) BackendFunctionEnvMut<'a, T>);
62
63impl<T: Send + 'static> FunctionEnvMut<'_, T> {
64    /// Returns a reference to the host state in this function environement.
65    pub fn data(&self) -> &T {
66        self.0.data()
67    }
68
69    /// Returns a mutable- reference to the host state in this function environement.
70    pub fn data_mut(&mut self) -> &mut T {
71        self.0.data_mut()
72    }
73
74    /// Borrows a new immmutable reference
75    pub fn as_ref(&self) -> FunctionEnv<T> {
76        self.0.as_ref()
77    }
78
79    /// Borrows a new mutable reference
80    pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> {
81        self.0.as_mut()
82    }
83
84    /// Borrows a new mutable reference of both the attached Store and host state
85    pub fn data_and_store_mut(&mut self) -> (&mut T, StoreMut<'_>) {
86        self.0.data_and_store_mut()
87    }
88
89    /// Creates an [`AsStoreAsync`] from this [`FunctionEnvMut`] if the current
90    /// context is async.
91    #[cfg(feature = "experimental-async")]
92    pub fn as_store_async(&self) -> Option<impl AsStoreAsync + 'static> {
93        self.0.as_store_async()
94    }
95}
96
97impl<T> AsStoreRef for FunctionEnvMut<'_, T> {
98    fn as_store_ref(&self) -> StoreRef<'_> {
99        self.0.as_store_ref()
100    }
101}
102
103impl<T> AsStoreMut for FunctionEnvMut<'_, T> {
104    fn as_store_mut(&mut self) -> StoreMut<'_> {
105        self.0.as_store_mut()
106    }
107
108    fn objects_mut(&mut self) -> &mut crate::StoreObjects {
109        self.0.objects_mut()
110    }
111}
112
113impl<T> std::fmt::Debug for FunctionEnvMut<'_, T>
114where
115    T: Send + std::fmt::Debug + 'static,
116{
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        self.0.fmt(f)
119    }
120}
121
122/// A shared handle to a [`FunctionEnv`], suitable for use
123/// in async imports.
124#[cfg(feature = "experimental-async")]
125pub struct AsyncFunctionEnvMut<T>(pub(crate) BackendAsyncFunctionEnvMut<T>);
126
127/// A read-only handle to the [`FunctionEnv`] in an [`AsyncFunctionEnvMut`].
128#[cfg(feature = "experimental-async")]
129pub struct AsyncFunctionEnvHandle<T>(pub(crate) BackendAsyncFunctionEnvHandle<T>);
130
131/// A mutable handle to the [`FunctionEnv`] in an [`AsyncFunctionEnvMut`].
132#[cfg(feature = "experimental-async")]
133pub struct AsyncFunctionEnvHandleMut<T>(pub(crate) BackendAsyncFunctionEnvHandleMut<T>);
134
135#[cfg(feature = "experimental-async")]
136impl<T: 'static> AsyncFunctionEnvMut<T> {
137    /// Waits for a store lock and returns a read-only handle to the
138    /// function environment.
139    pub async fn read(&self) -> AsyncFunctionEnvHandle<T> {
140        AsyncFunctionEnvHandle(self.0.read().await)
141    }
142
143    /// Waits for a store lock and returns a mutable handle to the
144    /// function environment.
145    pub async fn write(&self) -> AsyncFunctionEnvHandleMut<T> {
146        AsyncFunctionEnvHandleMut(self.0.write().await)
147    }
148
149    /// Borrows a new immmutable reference
150    pub fn as_ref(&self) -> FunctionEnv<T> {
151        FunctionEnv(self.0.as_ref())
152    }
153
154    /// Borrows a new mutable reference
155    pub fn as_mut(&mut self) -> Self {
156        Self(self.0.as_mut())
157    }
158
159    /// Creates an [`AsStoreAsync`] from this [`AsyncFunctionEnvMut`].
160    pub fn as_store_async(&self) -> impl AsStoreAsync + 'static {
161        self.0.as_store_async()
162    }
163}
164
165#[cfg(feature = "experimental-async")]
166impl<T: 'static> AsyncFunctionEnvHandle<T> {
167    /// Returns a reference to the host state in this function environment.
168    pub fn data(&self) -> &T {
169        self.0.data()
170    }
171
172    /// Returns both the host state and the attached StoreRef
173    pub fn data_and_store(&self) -> (&T, &impl AsStoreRef) {
174        self.0.data_and_store()
175    }
176}
177
178#[cfg(feature = "experimental-async")]
179impl<T: 'static> AsStoreRef for AsyncFunctionEnvHandle<T> {
180    fn as_store_ref(&self) -> StoreRef<'_> {
181        AsStoreRef::as_store_ref(&self.0)
182    }
183}
184
185#[cfg(feature = "experimental-async")]
186impl<T: 'static> AsyncFunctionEnvHandleMut<T> {
187    /// Returns a mutable reference to the host state in this function environment.
188    pub fn data_mut(&mut self) -> &mut T {
189        self.0.data_mut()
190    }
191
192    /// Returns both the host state and the attached StoreMut
193    pub fn data_and_store_mut(&mut self) -> (&mut T, &mut impl AsStoreMut) {
194        self.0.data_and_store_mut()
195    }
196
197    /// Borrows a new [`FunctionEnvMut`] from this
198    /// [`AsyncFunctionEnvHandleMut`].
199    pub fn as_function_env_mut(&mut self) -> FunctionEnvMut<'_, T> {
200        FunctionEnvMut(self.0.as_function_env_mut())
201    }
202}
203
204#[cfg(feature = "experimental-async")]
205impl<T: 'static> AsStoreRef for AsyncFunctionEnvHandleMut<T> {
206    fn as_store_ref(&self) -> StoreRef<'_> {
207        AsStoreRef::as_store_ref(&self.0)
208    }
209}
210
211#[cfg(feature = "experimental-async")]
212impl<T: 'static> AsStoreMut for AsyncFunctionEnvHandleMut<T> {
213    fn as_store_mut(&mut self) -> StoreMut<'_> {
214        AsStoreMut::as_store_mut(&mut self.0)
215    }
216
217    fn objects_mut(&mut self) -> &mut crate::StoreObjects {
218        AsStoreMut::objects_mut(&mut self.0)
219    }
220}