1use crate::engine::{AsEngineRef, Engine, EngineRef};
2use derivative::Derivative;
3use std::{
4 fmt,
5 ops::{Deref, DerefMut},
6};
7#[cfg(feature = "sys")]
8pub use wasmer_compiler::Tunables;
9pub use wasmer_types::{OnCalledAction, StoreId};
10#[cfg(feature = "sys")]
11use wasmer_vm::init_traps;
12#[cfg(feature = "sys")]
13pub use wasmer_vm::TrapHandlerFn;
14
15#[cfg(feature = "sys")]
16pub use wasmer_vm::{StoreHandle, StoreObjects};
17
18#[cfg(feature = "js")]
19pub use crate::js::store::{StoreHandle, StoreObjects};
20
21#[cfg(feature = "jsc")]
22pub use crate::jsc::store::{StoreHandle, StoreObjects};
23
24pub type OnCalledHandler = Box<
27 dyn FnOnce(StoreMut<'_>) -> Result<OnCalledAction, Box<dyn std::error::Error + Send + Sync>>,
28>;
29
30#[derive(Derivative)]
34#[derivative(Debug)]
35pub(crate) struct StoreInner {
36 pub(crate) objects: StoreObjects,
37 #[derivative(Debug = "ignore")]
38 pub(crate) engine: Engine,
39 #[cfg(feature = "sys")]
40 #[derivative(Debug = "ignore")]
41 pub(crate) trap_handler: Option<Box<TrapHandlerFn<'static>>>,
42 #[derivative(Debug = "ignore")]
43 pub(crate) on_called: Option<OnCalledHandler>,
44}
45
46pub struct Store {
56 pub(crate) inner: Box<StoreInner>,
57}
58
59impl Store {
60 pub fn new(engine: impl Into<Engine>) -> Self {
62 #[cfg(feature = "sys")]
65 init_traps();
66
67 Self {
68 inner: Box::new(StoreInner {
69 objects: Default::default(),
70 engine: engine.into(),
71 #[cfg(feature = "sys")]
72 trap_handler: None,
73 on_called: None,
74 }),
75 }
76 }
77
78 #[cfg(feature = "sys")]
79 pub fn set_trap_handler(&mut self, handler: Option<Box<TrapHandlerFn<'static>>>) {
81 self.inner.trap_handler = handler;
82 }
83
84 pub fn engine(&self) -> &Engine {
86 &self.inner.engine
87 }
88
89 pub fn engine_mut(&mut self) -> &mut Engine {
91 &mut self.inner.engine
92 }
93
94 pub fn same(a: &Self, b: &Self) -> bool {
97 a.id() == b.id()
98 }
99
100 pub fn id(&self) -> StoreId {
102 self.inner.objects.id()
103 }
104}
105
106impl PartialEq for Store {
107 fn eq(&self, other: &Self) -> bool {
108 Self::same(self, other)
109 }
110}
111
112unsafe impl Send for Store {}
115unsafe impl Sync for Store {}
116
117impl Default for Store {
118 fn default() -> Self {
119 Self::new(Engine::default())
120 }
121}
122
123impl AsStoreRef for Store {
124 fn as_store_ref(&self) -> StoreRef<'_> {
125 StoreRef { inner: &self.inner }
126 }
127}
128impl AsStoreMut for Store {
129 fn as_store_mut(&mut self) -> StoreMut<'_> {
130 StoreMut {
131 inner: &mut self.inner,
132 }
133 }
134 fn objects_mut(&mut self) -> &mut StoreObjects {
135 &mut self.inner.objects
136 }
137}
138
139impl AsEngineRef for Store {
140 fn as_engine_ref(&self) -> EngineRef<'_> {
141 EngineRef::new(&self.inner.engine)
142 }
143}
144
145impl AsEngineRef for StoreRef<'_> {
146 fn as_engine_ref(&self) -> EngineRef<'_> {
147 EngineRef::new(&self.inner.engine)
148 }
149}
150
151impl AsEngineRef for StoreMut<'_> {
152 fn as_engine_ref(&self) -> EngineRef<'_> {
153 EngineRef::new(&self.inner.engine)
154 }
155}
156
157impl fmt::Debug for Store {
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 f.debug_struct("Store").finish()
160 }
161}
162
163#[derive(Debug)]
165pub struct StoreRef<'a> {
166 pub(crate) inner: &'a StoreInner,
167}
168
169impl<'a> StoreRef<'a> {
170 pub(crate) fn objects(&self) -> &'a StoreObjects {
171 &self.inner.objects
172 }
173
174 pub fn engine(&self) -> &Engine {
176 &self.inner.engine
177 }
178
179 pub fn same(a: &Self, b: &Self) -> bool {
182 a.inner.objects.id() == b.inner.objects.id()
183 }
184
185 #[cfg(feature = "sys")]
187 #[inline]
188 pub fn signal_handler(&self) -> Option<*const TrapHandlerFn<'static>> {
189 self.inner
190 .trap_handler
191 .as_ref()
192 .map(|handler| handler.as_ref() as *const _)
193 }
194}
195
196pub struct StoreMut<'a> {
198 pub(crate) inner: &'a mut StoreInner,
199}
200
201impl<'a> StoreMut<'a> {
202 pub fn engine(&self) -> &Engine {
204 &self.inner.engine
205 }
206
207 pub fn same(a: &Self, b: &Self) -> bool {
210 a.inner.objects.id() == b.inner.objects.id()
211 }
212
213 #[allow(unused)]
214 pub(crate) fn engine_and_objects_mut(&mut self) -> (&Engine, &mut StoreObjects) {
215 (&self.inner.engine, &mut self.inner.objects)
216 }
217
218 pub(crate) fn as_raw(&self) -> *mut StoreInner {
219 self.inner as *const StoreInner as *mut StoreInner
220 }
221
222 pub(crate) unsafe fn from_raw(raw: *mut StoreInner) -> Self {
223 Self { inner: &mut *raw }
224 }
225
226 pub fn on_called<F>(&mut self, callback: F)
229 where
230 F: FnOnce(StoreMut<'_>) -> Result<OnCalledAction, Box<dyn std::error::Error + Send + Sync>>
231 + Send
232 + Sync
233 + 'static,
234 {
235 self.inner.on_called.replace(Box::new(callback));
236 }
237}
238
239pub trait AsStoreRef {
241 fn as_store_ref(&self) -> StoreRef<'_>;
243}
244
245pub trait AsStoreMut: AsStoreRef {
247 fn as_store_mut(&mut self) -> StoreMut<'_>;
249
250 fn objects_mut(&mut self) -> &mut StoreObjects;
252}
253
254impl AsStoreRef for StoreRef<'_> {
255 fn as_store_ref(&self) -> StoreRef<'_> {
256 StoreRef { inner: self.inner }
257 }
258}
259
260impl AsStoreRef for StoreMut<'_> {
261 fn as_store_ref(&self) -> StoreRef<'_> {
262 StoreRef { inner: self.inner }
263 }
264}
265impl AsStoreMut for StoreMut<'_> {
266 fn as_store_mut(&mut self) -> StoreMut<'_> {
267 StoreMut { inner: self.inner }
268 }
269 fn objects_mut(&mut self) -> &mut StoreObjects {
270 &mut self.inner.objects
271 }
272}
273
274impl<P> AsStoreRef for P
275where
276 P: Deref,
277 P::Target: AsStoreRef,
278{
279 fn as_store_ref(&self) -> StoreRef<'_> {
280 (**self).as_store_ref()
281 }
282}
283
284impl<P> AsStoreMut for P
285where
286 P: DerefMut,
287 P::Target: AsStoreMut,
288{
289 fn as_store_mut(&mut self) -> StoreMut<'_> {
290 (**self).as_store_mut()
291 }
292
293 fn objects_mut(&mut self) -> &mut StoreObjects {
294 (**self).objects_mut()
295 }
296}