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