wasmer/entities/store/
store_ref.rs

1use std::ops::{Deref, DerefMut};
2
3use super::{StoreObjects, inner::StoreInner};
4use crate::entities::engine::{AsEngineRef, Engine, EngineRef};
5#[cfg(feature = "experimental-async")]
6use crate::{AsStoreAsync, StoreAsync};
7use wasmer_types::{ExternType, OnCalledAction};
8//use wasmer_vm::{StoreObjects, TrapHandlerFn};
9
10#[cfg(feature = "sys")]
11use wasmer_vm::TrapHandlerFn;
12
13/// A temporary handle to a [`crate::Store`].
14#[derive(Debug)]
15pub struct StoreRef<'a> {
16    pub(crate) inner: &'a StoreInner,
17}
18
19impl<'a> StoreRef<'a> {
20    pub(crate) fn objects(&self) -> &'a StoreObjects {
21        &self.inner.objects
22    }
23
24    /// Returns the [`Engine`].
25    pub fn engine(&self) -> &Engine {
26        self.inner.store.engine()
27    }
28
29    /// Checks whether two stores are identical. A store is considered
30    /// equal to another store if both have the same engine.
31    pub fn same(a: &Self, b: &Self) -> bool {
32        StoreObjects::same(&a.inner.objects, &b.inner.objects)
33    }
34
35    /// The signal handler
36    #[cfg(feature = "sys")]
37    #[inline]
38    pub fn signal_handler(&self) -> Option<*const TrapHandlerFn<'static>> {
39        use crate::backend::sys::entities::store::NativeStoreExt;
40        self.inner.store.as_sys().signal_handler()
41    }
42}
43
44/// A temporary handle to a [`crate::Store`].
45pub struct StoreMut<'a> {
46    pub(crate) inner: &'a mut StoreInner,
47}
48
49impl StoreMut<'_> {
50    /// Returns the [`Engine`].
51    pub fn engine(&self) -> &Engine {
52        self.inner.store.engine()
53    }
54
55    /// Checks whether two stores are identical. A store is considered
56    /// equal to another store if both have the same engine.
57    pub fn same(a: &Self, b: &Self) -> bool {
58        StoreObjects::same(&a.inner.objects, &b.inner.objects)
59    }
60
61    #[allow(unused)]
62    pub(crate) fn as_raw(&self) -> *mut StoreInner {
63        self.inner as *const StoreInner as *mut StoreInner
64    }
65
66    #[allow(unused)]
67    pub(crate) unsafe fn from_raw(raw: *mut StoreInner) -> Self {
68        Self {
69            inner: unsafe { &mut *raw },
70        }
71    }
72
73    #[allow(unused)]
74    pub(crate) fn engine_and_objects_mut(&mut self) -> (&Engine, &mut StoreObjects) {
75        (self.inner.store.engine(), &mut self.inner.objects)
76    }
77
78    // TODO: OnCalledAction is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
79    /// Sets the unwind callback which will be invoked when the call finishes
80    pub fn on_called<F>(&mut self, callback: F)
81    where
82        F: FnOnce(StoreMut<'_>) -> Result<OnCalledAction, Box<dyn std::error::Error + Send + Sync>>
83            + Send
84            + Sync
85            + 'static,
86    {
87        self.inner.on_called.replace(Box::new(callback));
88    }
89}
90
91/// Helper trait for a value that is convertible to a [`StoreRef`].
92pub trait AsStoreRef {
93    /// Returns a `StoreRef` pointing to the underlying context.
94    fn as_store_ref(&self) -> StoreRef<'_>;
95
96    /// Returns a [`StoreAsync`] if the current
97    /// context is asynchronous. The store will be locked since
98    /// it's already active in the current context, but can be used
99    /// to spawn new coroutines via
100    /// [`Function::call_async`](crate::Function::call_async).
101    #[cfg(feature = "experimental-async")]
102    fn as_store_async(&self) -> Option<impl AsStoreAsync + 'static> {
103        let id = self.as_store_ref().inner.objects.id();
104        StoreAsync::from_context(id)
105    }
106}
107
108/// Helper trait for a value that is convertible to a [`StoreMut`].
109pub trait AsStoreMut: AsStoreRef {
110    /// Returns a `StoreMut` pointing to the underlying context.
111    fn as_store_mut(&mut self) -> StoreMut<'_>;
112
113    /// Returns the ObjectMutable
114    fn objects_mut(&mut self) -> &mut StoreObjects;
115}
116
117impl AsStoreRef for StoreRef<'_> {
118    fn as_store_ref(&self) -> StoreRef<'_> {
119        StoreRef { inner: self.inner }
120    }
121}
122
123impl AsEngineRef for StoreRef<'_> {
124    fn as_engine_ref(&self) -> EngineRef<'_> {
125        self.inner.store.as_engine_ref()
126    }
127}
128
129impl AsStoreRef for StoreMut<'_> {
130    fn as_store_ref(&self) -> StoreRef<'_> {
131        StoreRef { inner: self.inner }
132    }
133}
134impl AsStoreMut for StoreMut<'_> {
135    fn as_store_mut(&mut self) -> StoreMut<'_> {
136        StoreMut { inner: self.inner }
137    }
138
139    fn objects_mut(&mut self) -> &mut StoreObjects {
140        &mut self.inner.objects
141    }
142}
143
144impl<P> AsStoreRef for P
145where
146    P: Deref,
147    P::Target: AsStoreRef,
148{
149    fn as_store_ref(&self) -> StoreRef<'_> {
150        (**self).as_store_ref()
151    }
152}
153
154impl<P> AsStoreMut for P
155where
156    P: DerefMut,
157    P::Target: AsStoreMut,
158{
159    fn as_store_mut(&mut self) -> StoreMut<'_> {
160        (**self).as_store_mut()
161    }
162
163    fn objects_mut(&mut self) -> &mut StoreObjects {
164        (**self).objects_mut()
165    }
166}
167
168impl AsEngineRef for StoreMut<'_> {
169    fn as_engine_ref(&self) -> EngineRef<'_> {
170        self.inner.store.as_engine_ref()
171    }
172}