wasmer/entities/store/
mod.rs

1//! Defines the [`Store`] data type and various useful traits and data types to interact with a
2//! store.
3
4/// Defines the [`StoreInner`] data type.
5mod inner;
6
7/// Create temporary handles to engines.
8mod store_ref;
9pub use store_ref::*;
10
11mod obj;
12pub use obj::*;
13
14use crate::{AsEngineRef, BackendEngine, Engine, EngineRef};
15pub(crate) use inner::*;
16use wasmer_types::StoreId;
17
18#[cfg(feature = "sys")]
19use wasmer_vm::TrapHandlerFn;
20
21/// The store represents all global state that can be manipulated by
22/// WebAssembly programs. It consists of the runtime representation
23/// of all instances of functions, tables, memories, and globals that
24/// have been allocated during the lifetime of the abstract machine.
25///
26/// The [`Store`] is tied to the underlying [`Engine`] that is — among many things — used to
27/// compile the Wasm bytes into a valid module artifact.
28///
29/// For more informations, check out the [related WebAssembly specification]
30/// [related WebAssembly specification]: <https://webassembly.github.io/spec/core/exec/runtime.html#store>
31pub struct Store {
32    pub(crate) inner: Box<StoreInner>,
33}
34
35impl Store {
36    /// Creates a new `Store` with a specific [`Engine`].
37    pub fn new(engine: impl Into<Engine>) -> Self {
38        let engine: Engine = engine.into();
39
40        let store = match engine.be {
41            #[cfg(feature = "sys")]
42            BackendEngine::Sys(_) => {
43                BackendStore::Sys(crate::backend::sys::entities::store::Store::new(engine))
44            }
45            #[cfg(feature = "wamr")]
46            BackendEngine::Wamr(_) => {
47                BackendStore::Wamr(crate::backend::wamr::entities::store::Store::new(engine))
48            }
49            #[cfg(feature = "wasmi")]
50            BackendEngine::Wasmi(_) => {
51                BackendStore::Wasmi(crate::backend::wasmi::entities::store::Store::new(engine))
52            }
53            #[cfg(feature = "v8")]
54            BackendEngine::V8(_) => {
55                BackendStore::V8(crate::backend::v8::entities::store::Store::new(engine))
56            }
57            #[cfg(feature = "js")]
58            BackendEngine::Js(_) => {
59                BackendStore::Js(crate::backend::js::entities::store::Store::new(engine))
60            }
61            #[cfg(feature = "jsc")]
62            BackendEngine::Jsc(_) => {
63                BackendStore::Jsc(crate::backend::jsc::entities::store::Store::new(engine))
64            }
65        };
66
67        Self {
68            inner: Box::new(StoreInner {
69                objects: StoreObjects::from_store_ref(&store),
70                on_called: None,
71                store,
72            }),
73        }
74    }
75
76    #[cfg(feature = "sys")]
77    /// Set the [`TrapHandlerFn`] for this store.
78    ///
79    /// # Note
80    ///
81    /// Not every implementor allows changing the trap handler. In those store that
82    /// don't allow it, this function has no effect.
83    pub fn set_trap_handler(&mut self, handler: Option<Box<TrapHandlerFn<'static>>>) {
84        use crate::backend::sys::entities::store::NativeStoreExt;
85        #[allow(irrefutable_let_patterns)]
86        if let BackendStore::Sys(ref mut s) = self.inner.store {
87            s.set_trap_handler(handler)
88        }
89    }
90
91    /// Returns the [`Engine`].
92    pub fn engine(&self) -> &Engine {
93        self.inner.store.engine()
94    }
95
96    /// Returns mutable reference to [`Engine`].
97    pub fn engine_mut(&mut self) -> &mut Engine {
98        self.inner.store.engine_mut()
99    }
100
101    /// Checks whether two stores are identical. A store is considered
102    /// equal to another store if both have the same engine.
103    pub fn same(a: &Self, b: &Self) -> bool {
104        a.id() == b.id()
105    }
106
107    /// Returns the ID of this store
108    pub fn id(&self) -> StoreId {
109        self.inner.objects.id()
110    }
111}
112
113impl PartialEq for Store {
114    fn eq(&self, other: &Self) -> bool {
115        Self::same(self, other)
116    }
117}
118
119// This is required to be able to set the trap_handler in the
120// Store.
121unsafe impl Send for Store {}
122unsafe impl Sync for Store {}
123
124impl Default for Store {
125    fn default() -> Self {
126        Self::new(Engine::default())
127    }
128}
129
130impl std::fmt::Debug for Store {
131    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
132        f.debug_struct("Store").finish()
133    }
134}
135
136impl AsEngineRef for Store {
137    fn as_engine_ref(&self) -> EngineRef<'_> {
138        self.inner.store.as_engine_ref()
139    }
140
141    fn maybe_as_store(&self) -> Option<StoreRef<'_>> {
142        Some(self.as_store_ref())
143    }
144}
145
146impl AsStoreRef for Store {
147    fn as_store_ref(&self) -> StoreRef<'_> {
148        StoreRef { inner: &self.inner }
149    }
150}
151impl AsStoreMut for Store {
152    fn as_store_mut(&mut self) -> StoreMut<'_> {
153        StoreMut {
154            inner: &mut self.inner,
155        }
156    }
157
158    fn objects_mut(&mut self) -> &mut StoreObjects {
159        &mut self.inner.objects
160    }
161}