wasmer/entities/function/env/
inner.rs

1#[cfg(feature = "experimental-async")]
2use crate::AsStoreAsync;
3use crate::{
4    AsStoreMut, AsStoreRef, FunctionEnv, FunctionEnvMut, StoreMut, StoreRef,
5    macros::backend::match_rt,
6};
7use std::{any::Any, 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 enum BackendFunctionEnv<T> {
13    #[cfg(feature = "sys")]
14    /// The function environment for the `sys` runtime.
15    Sys(crate::backend::sys::function::env::FunctionEnv<T>),
16    #[cfg(feature = "wamr")]
17    /// The function environment for the `wamr` runtime.
18    Wamr(crate::backend::wamr::function::env::FunctionEnv<T>),
19    #[cfg(feature = "wasmi")]
20    /// The function environment for the `wasmi` runtime.
21    Wasmi(crate::backend::wasmi::function::env::FunctionEnv<T>),
22    #[cfg(feature = "v8")]
23    /// The function environment for the `v8` runtime.
24    V8(crate::backend::v8::function::env::FunctionEnv<T>),
25    #[cfg(feature = "js")]
26    /// The function environment for the `js` runtime.
27    Js(crate::backend::js::function::env::FunctionEnv<T>),
28    #[cfg(feature = "jsc")]
29    /// The function environment for the `jsc` runtime.
30    Jsc(crate::backend::jsc::function::env::FunctionEnv<T>),
31}
32
33impl<T> Clone for BackendFunctionEnv<T> {
34    fn clone(&self) -> Self {
35        match self {
36            #[cfg(feature = "sys")]
37            Self::Sys(s) => Self::Sys(s.clone()),
38            #[cfg(feature = "wamr")]
39            Self::Wamr(s) => Self::Wamr(s.clone()),
40
41            #[cfg(feature = "wasmi")]
42            Self::Wasmi(s) => Self::Wasmi(s.clone()),
43            #[cfg(feature = "v8")]
44            Self::V8(s) => Self::V8(s.clone()),
45            #[cfg(feature = "js")]
46            Self::Js(s) => Self::Js(s.clone()),
47            #[cfg(feature = "jsc")]
48            Self::Jsc(s) => Self::Jsc(s.clone()),
49        }
50    }
51}
52
53impl<T> BackendFunctionEnv<T> {
54    /// Make a new FunctionEnv
55    pub fn new(store: &mut impl AsStoreMut, value: T) -> Self
56    where
57        T: Any + Send + 'static + Sized,
58    {
59        match store.as_store_mut().inner.store {
60            #[cfg(feature = "sys")]
61            crate::BackendStore::Sys(_) => Self::Sys(
62                crate::backend::sys::function::env::FunctionEnv::new(store, value),
63            ),
64            #[cfg(feature = "wamr")]
65            crate::BackendStore::Wamr(_) => Self::Wamr(
66                crate::backend::wamr::function::env::FunctionEnv::new(store, value),
67            ),
68
69            #[cfg(feature = "wasmi")]
70            crate::BackendStore::Wasmi(_) => Self::Wasmi(
71                crate::backend::wasmi::function::env::FunctionEnv::new(store, value),
72            ),
73
74            #[cfg(feature = "v8")]
75            crate::BackendStore::V8(_) => Self::V8(
76                crate::backend::v8::function::env::FunctionEnv::new(store, value),
77            ),
78
79            #[cfg(feature = "js")]
80            crate::BackendStore::Js(_) => Self::Js(
81                crate::backend::js::function::env::FunctionEnv::new(store, value),
82            ),
83            #[cfg(feature = "jsc")]
84            crate::BackendStore::Jsc(_) => Self::Jsc(
85                crate::backend::jsc::function::env::FunctionEnv::new(store, value),
86            ),
87        }
88    }
89
90    /// Get the data as reference
91    pub fn as_ref<'a>(&self, store: &'a impl AsStoreRef) -> &'a T
92    where
93        T: Any + Send + 'static + Sized,
94    {
95        match_rt!(on self => f {
96            f.as_ref(store)
97        })
98    }
99
100    /// Get the data as mutable
101    pub fn as_mut<'a>(&self, store: &'a mut impl AsStoreMut) -> &'a mut T
102    where
103        T: Any + Send + 'static + Sized,
104    {
105        match_rt!(on self => s {
106            s.as_mut(store)
107        })
108    }
109
110    /// Convert it into a `FunctionEnvMut`
111    pub fn into_mut(self, store: &mut impl AsStoreMut) -> FunctionEnvMut<'_, T>
112    where
113        T: Any + Send + 'static + Sized,
114    {
115        match_rt!(on self => f {
116            f.into_mut(store).into()
117        })
118    }
119}
120
121/// A temporary handle to a [`FunctionEnv`].
122#[derive(derive_more::From)]
123pub enum BackendFunctionEnvMut<'a, T: 'a> {
124    #[cfg(feature = "sys")]
125    /// The function environment for the `sys` runtime.
126    Sys(crate::backend::sys::function::env::FunctionEnvMut<'a, T>),
127
128    #[cfg(feature = "wamr")]
129    /// The function environment for the `wamr` runtime.
130    Wamr(crate::backend::wamr::function::env::FunctionEnvMut<'a, T>),
131
132    #[cfg(feature = "wasmi")]
133    /// The function environment for the `wasmi` runtime.
134    Wasmi(crate::backend::wasmi::function::env::FunctionEnvMut<'a, T>),
135
136    #[cfg(feature = "v8")]
137    /// The function environment for the `v8` runtime.
138    V8(crate::backend::v8::function::env::FunctionEnvMut<'a, T>),
139
140    #[cfg(feature = "js")]
141    /// The function environment for the `js` runtime.
142    Js(crate::backend::js::function::env::FunctionEnvMut<'a, T>),
143
144    #[cfg(feature = "jsc")]
145    /// The function environment for the `jsc` runtime.
146    Jsc(crate::backend::jsc::function::env::FunctionEnvMut<'a, T>),
147}
148
149impl<T: Send + 'static> BackendFunctionEnvMut<'_, T> {
150    /// Returns a reference to the host state in this function environement.
151    pub fn data(&self) -> &T {
152        match_rt!(on self => f {
153            f.data()
154        })
155    }
156
157    /// Returns a mutable- reference to the host state in this function environement.
158    pub fn data_mut(&mut self) -> &mut T {
159        match_rt!(on self => f {
160            f.data_mut()
161        })
162    }
163
164    /// Borrows a new immmutable reference
165    pub fn as_ref(&self) -> FunctionEnv<T> {
166        match self {
167            #[cfg(feature = "sys")]
168            Self::Sys(f) => BackendFunctionEnv::Sys(f.as_ref()).into(),
169            #[cfg(feature = "wamr")]
170            Self::Wamr(f) => BackendFunctionEnv::Wamr(f.as_ref()).into(),
171            #[cfg(feature = "wasmi")]
172            Self::Wasmi(f) => BackendFunctionEnv::Wasmi(f.as_ref()).into(),
173            #[cfg(feature = "v8")]
174            Self::V8(f) => BackendFunctionEnv::V8(f.as_ref()).into(),
175            #[cfg(feature = "js")]
176            Self::Js(f) => BackendFunctionEnv::Js(f.as_ref()).into(),
177            #[cfg(feature = "jsc")]
178            Self::Jsc(f) => BackendFunctionEnv::Jsc(f.as_ref()).into(),
179        }
180    }
181
182    /// Borrows a new mutable reference
183    pub fn as_mut(&mut self) -> FunctionEnvMut<'_, T> {
184        match self {
185            #[cfg(feature = "sys")]
186            Self::Sys(f) => BackendFunctionEnvMut::Sys(f.as_mut()).into(),
187            #[cfg(feature = "wamr")]
188            Self::Wamr(f) => BackendFunctionEnvMut::Wamr(f.as_mut()).into(),
189            #[cfg(feature = "wasmi")]
190            Self::Wasmi(f) => BackendFunctionEnvMut::Wasmi(f.as_mut()).into(),
191            #[cfg(feature = "v8")]
192            Self::V8(f) => BackendFunctionEnvMut::V8(f.as_mut()).into(),
193            #[cfg(feature = "js")]
194            Self::Js(f) => BackendFunctionEnvMut::Js(f.as_mut()).into(),
195            #[cfg(feature = "jsc")]
196            Self::Jsc(f) => BackendFunctionEnvMut::Jsc(f.as_mut()).into(),
197        }
198    }
199
200    /// Borrows a new mutable reference of both the attached Store and host state
201    pub fn data_and_store_mut(&mut self) -> (&mut T, StoreMut<'_>) {
202        match_rt!(on self => f {
203            f.data_and_store_mut()
204        })
205    }
206
207    /// Creates an [`AsStoreAsync`] from this [`BackendFunctionEnvMut`] if the current
208    /// context is async.
209    #[cfg(feature = "experimental-async")]
210    pub fn as_store_async(&self) -> Option<impl AsStoreAsync + 'static> {
211        match self {
212            #[cfg(feature = "sys")]
213            Self::Sys(f) => f.as_store_async(),
214            #[cfg(feature = "sys")]
215            _ => unsupported_async_backend(),
216            #[cfg(not(feature = "sys"))]
217            _ => unsupported_async_backend::<Option<crate::StoreAsync>>(),
218        }
219    }
220}
221
222impl<T> AsStoreRef for BackendFunctionEnvMut<'_, T> {
223    fn as_store_ref(&self) -> StoreRef<'_> {
224        match_rt!(on self => s {
225            s.as_store_ref()
226        })
227    }
228}
229
230impl<T> AsStoreMut for BackendFunctionEnvMut<'_, T> {
231    fn as_store_mut(&mut self) -> StoreMut<'_> {
232        match_rt!(on self => s {
233            s.as_store_mut()
234        })
235    }
236
237    fn objects_mut(&mut self) -> &mut crate::StoreObjects {
238        match_rt!(on self => s {
239            s.objects_mut()
240        })
241    }
242}
243
244impl<T> std::fmt::Debug for BackendFunctionEnvMut<'_, T>
245where
246    T: Send + std::fmt::Debug + 'static,
247{
248    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249        match_rt!(on self => s {
250            write!(f, "{s:?}")
251        })
252    }
253}
254
255/// A shared handle to a [`FunctionEnv`], suitable for use
256/// in async imports.
257#[derive(derive_more::From)]
258#[cfg(feature = "experimental-async")]
259pub enum BackendAsyncFunctionEnvMut<T> {
260    #[cfg(feature = "sys")]
261    /// The function environment for the `sys` runtime.
262    Sys(crate::backend::sys::function::env::AsyncFunctionEnvMut<T>),
263    #[cfg(any(
264        feature = "wamr",
265        feature = "wasmi",
266        feature = "v8",
267        feature = "js",
268        feature = "jsc"
269    ))]
270    /// Placeholder for unsupported backends.
271    Unsupported(PhantomData<T>),
272}
273
274/// A read-only handle to the [`FunctionEnv`] in an [`BackendAsyncFunctionEnvMut`].
275#[cfg(feature = "experimental-async")]
276pub enum BackendAsyncFunctionEnvHandle<T> {
277    #[cfg(feature = "sys")]
278    /// The function environment handle for the `sys` runtime.
279    Sys(crate::backend::sys::function::env::AsyncFunctionEnvHandle<T>),
280    #[cfg(any(
281        feature = "wamr",
282        feature = "wasmi",
283        feature = "v8",
284        feature = "js",
285        feature = "jsc"
286    ))]
287    /// Placeholder for unsupported backends.
288    Unsupported(PhantomData<T>),
289}
290
291/// A mutable handle to the [`FunctionEnv`] in an [`BackendAsyncFunctionEnvMut`].
292#[cfg(feature = "experimental-async")]
293pub enum BackendAsyncFunctionEnvHandleMut<T> {
294    #[cfg(feature = "sys")]
295    /// The function environment handle for the `sys` runtime.
296    Sys(crate::backend::sys::function::env::AsyncFunctionEnvHandleMut<T>),
297    #[cfg(any(
298        feature = "wamr",
299        feature = "wasmi",
300        feature = "v8",
301        feature = "js",
302        feature = "jsc"
303    ))]
304    /// Placeholder for unsupported backends.
305    Unsupported(PhantomData<T>),
306}
307
308#[cfg(feature = "experimental-async")]
309impl<T: 'static> BackendAsyncFunctionEnvMut<T> {
310    /// Waits for a store lock and returns a read-only handle to the
311    /// function environment.
312    pub async fn read(&self) -> BackendAsyncFunctionEnvHandle<T> {
313        match self {
314            #[cfg(feature = "sys")]
315            Self::Sys(f) => BackendAsyncFunctionEnvHandle::Sys(f.read().await),
316            #[cfg(any(
317                feature = "wamr",
318                feature = "wasmi",
319                feature = "v8",
320                feature = "js",
321                feature = "jsc"
322            ))]
323            _ => unsupported_async_backend(),
324        }
325    }
326
327    /// Waits for a store lock and returns a mutable handle to the
328    /// function environment.
329    pub async fn write(&self) -> BackendAsyncFunctionEnvHandleMut<T> {
330        match self {
331            #[cfg(feature = "sys")]
332            Self::Sys(f) => BackendAsyncFunctionEnvHandleMut::Sys(f.write().await),
333            #[cfg(any(
334                feature = "wamr",
335                feature = "wasmi",
336                feature = "v8",
337                feature = "js",
338                feature = "jsc"
339            ))]
340            _ => unsupported_async_backend(),
341        }
342    }
343
344    /// Borrows a new immutable reference
345    pub fn as_ref(&self) -> BackendFunctionEnv<T> {
346        match self {
347            #[cfg(feature = "sys")]
348            Self::Sys(f) => BackendFunctionEnv::Sys(f.as_ref()),
349            #[cfg(any(
350                feature = "wamr",
351                feature = "wasmi",
352                feature = "v8",
353                feature = "js",
354                feature = "jsc"
355            ))]
356            _ => unsupported_async_backend(),
357        }
358    }
359
360    /// Borrows a new mutable reference
361    pub fn as_mut(&mut self) -> Self {
362        match self {
363            #[cfg(feature = "sys")]
364            Self::Sys(f) => Self::Sys(f.as_mut()),
365            #[cfg(any(
366                feature = "wamr",
367                feature = "wasmi",
368                feature = "v8",
369                feature = "js",
370                feature = "jsc"
371            ))]
372            _ => unsupported_async_backend(),
373        }
374    }
375
376    /// Creates an [`AsStoreAsync`] from this [`BackendAsyncFunctionEnvMut`].
377    pub fn as_store_async(&self) -> impl AsStoreAsync + 'static {
378        match self {
379            #[cfg(feature = "sys")]
380            Self::Sys(f) => f.as_store_async(),
381            #[cfg(all(
382                feature = "sys",
383                any(
384                    feature = "wamr",
385                    feature = "wasmi",
386                    feature = "v8",
387                    feature = "js",
388                    feature = "jsc"
389                )
390            ))]
391            _ => unsupported_async_backend(),
392            #[cfg(all(
393                not(feature = "sys"),
394                any(
395                    feature = "wamr",
396                    feature = "wasmi",
397                    feature = "v8",
398                    feature = "js",
399                    feature = "jsc"
400                )
401            ))]
402            _ => unsupported_async_backend::<crate::StoreAsync>(),
403        }
404    }
405}
406
407#[cfg(feature = "experimental-async")]
408impl<T: 'static> BackendAsyncFunctionEnvHandle<T> {
409    /// Returns a reference to the host state in this function environment.
410    pub fn data(&self) -> &T {
411        match self {
412            #[cfg(feature = "sys")]
413            Self::Sys(f) => f.data(),
414            #[cfg(any(
415                feature = "wamr",
416                feature = "wasmi",
417                feature = "v8",
418                feature = "js",
419                feature = "jsc"
420            ))]
421            _ => unsupported_async_backend(),
422        }
423    }
424
425    /// Returns both the host state and the attached StoreRef
426    pub fn data_and_store(&self) -> (&T, &impl AsStoreRef) {
427        match self {
428            #[cfg(feature = "sys")]
429            Self::Sys(f) => f.data_and_store(),
430            #[cfg(all(
431                feature = "sys",
432                any(
433                    feature = "wamr",
434                    feature = "wasmi",
435                    feature = "v8",
436                    feature = "js",
437                    feature = "jsc"
438                )
439            ))]
440            _ => unsupported_async_backend(),
441            #[cfg(all(
442                not(feature = "sys"),
443                any(
444                    feature = "wamr",
445                    feature = "wasmi",
446                    feature = "v8",
447                    feature = "js",
448                    feature = "jsc"
449                )
450            ))]
451            _ => unsupported_async_backend::<(&T, &StoreRef)>(),
452        }
453    }
454}
455
456#[cfg(feature = "experimental-async")]
457impl<T: 'static> AsStoreRef for BackendAsyncFunctionEnvHandle<T> {
458    fn as_store_ref(&self) -> StoreRef<'_> {
459        match self {
460            #[cfg(feature = "sys")]
461            Self::Sys(f) => AsStoreRef::as_store_ref(f),
462            #[cfg(any(
463                feature = "wamr",
464                feature = "wasmi",
465                feature = "v8",
466                feature = "js",
467                feature = "jsc"
468            ))]
469            _ => unsupported_async_backend(),
470        }
471    }
472}
473
474#[cfg(feature = "experimental-async")]
475impl<T: 'static> BackendAsyncFunctionEnvHandleMut<T> {
476    /// Returns a mutable reference to the host state in this function environment.
477    pub fn data_mut(&mut self) -> &mut T {
478        match self {
479            #[cfg(feature = "sys")]
480            Self::Sys(f) => f.data_mut(),
481            #[cfg(any(
482                feature = "wamr",
483                feature = "wasmi",
484                feature = "v8",
485                feature = "js",
486                feature = "jsc"
487            ))]
488            _ => unsupported_async_backend(),
489        }
490    }
491
492    /// Returns both the host state and the attached StoreMut
493    pub fn data_and_store_mut(&mut self) -> (&mut T, &mut impl AsStoreMut) {
494        match self {
495            #[cfg(feature = "sys")]
496            Self::Sys(f) => f.data_and_store_mut(),
497            #[cfg(all(
498                feature = "sys",
499                any(
500                    feature = "wamr",
501                    feature = "wasmi",
502                    feature = "v8",
503                    feature = "js",
504                    feature = "jsc"
505                )
506            ))]
507            _ => unsupported_async_backend(),
508            #[cfg(all(
509                not(feature = "sys"),
510                any(
511                    feature = "wamr",
512                    feature = "wasmi",
513                    feature = "v8",
514                    feature = "js",
515                    feature = "jsc"
516                )
517            ))]
518            _ => unsupported_async_backend::<(&mut T, &mut crate::StoreMut)>(),
519        }
520    }
521
522    /// Borrows a new [`BackendFunctionEnvMut`] from this
523    /// [`BackendAsyncFunctionEnvHandleMut`].
524    pub fn as_function_env_mut(&mut self) -> BackendFunctionEnvMut<'_, T> {
525        match self {
526            #[cfg(feature = "sys")]
527            Self::Sys(f) => BackendFunctionEnvMut::Sys(f.as_function_env_mut()),
528            #[cfg(any(
529                feature = "wamr",
530                feature = "wasmi",
531                feature = "v8",
532                feature = "js",
533                feature = "jsc"
534            ))]
535            _ => unsupported_async_backend(),
536        }
537    }
538}
539
540#[cfg(feature = "experimental-async")]
541impl<T: 'static> AsStoreRef for BackendAsyncFunctionEnvHandleMut<T> {
542    fn as_store_ref(&self) -> StoreRef<'_> {
543        match self {
544            #[cfg(feature = "sys")]
545            Self::Sys(f) => AsStoreRef::as_store_ref(f),
546            #[cfg(any(
547                feature = "wamr",
548                feature = "wasmi",
549                feature = "v8",
550                feature = "js",
551                feature = "jsc"
552            ))]
553            _ => unsupported_async_backend(),
554        }
555    }
556}
557
558#[cfg(feature = "experimental-async")]
559impl<T: 'static> AsStoreMut for BackendAsyncFunctionEnvHandleMut<T> {
560    fn as_store_mut(&mut self) -> StoreMut<'_> {
561        match self {
562            #[cfg(feature = "sys")]
563            Self::Sys(f) => AsStoreMut::as_store_mut(f),
564            #[cfg(any(
565                feature = "wamr",
566                feature = "wasmi",
567                feature = "v8",
568                feature = "js",
569                feature = "jsc"
570            ))]
571            _ => unsupported_async_backend(),
572        }
573    }
574
575    fn objects_mut(&mut self) -> &mut crate::StoreObjects {
576        match self {
577            #[cfg(feature = "sys")]
578            Self::Sys(f) => AsStoreMut::objects_mut(f),
579            #[cfg(any(
580                feature = "wamr",
581                feature = "wasmi",
582                feature = "v8",
583                feature = "js",
584                feature = "jsc"
585            ))]
586            _ => unsupported_async_backend(),
587        }
588    }
589}
590
591#[cfg(feature = "experimental-async")]
592fn unsupported_async_backend<T>() -> T {
593    panic!("async functions are only supported with the `sys` backend");
594}