1use super::{SharedMemory, shared_memory_detach_error, view::*};
2use wasmer_types::{MemoryError, MemoryType, Pages};
3
4use crate::{
5 AsStoreMut, AsStoreRef, ExportError, Exportable, Extern, StoreMut, StoreRef,
6 macros::backend::{gen_rt_ty, match_rt},
7 vm::{VMExtern, VMExternMemory, VMMemory},
8};
9
10gen_rt_ty! {
11 #[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
12 #[derive(Debug, Clone, PartialEq, Eq, derive_more::From)]
13 pub BackendMemory(entities::memory::Memory);
14}
15
16impl BackendMemory {
17 #[inline]
31 pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
32 match &store.as_store_mut().inner.store {
33 #[cfg(feature = "sys")]
34 crate::BackendStore::Sys(s) => Ok(Self::Sys(
35 crate::backend::sys::entities::memory::Memory::new(store, ty)?,
36 )),
37 #[cfg(feature = "v8")]
38 crate::BackendStore::V8(s) => Ok(Self::V8(
39 crate::backend::v8::entities::memory::Memory::new(store, ty)?,
40 )),
41 #[cfg(feature = "js")]
42 crate::BackendStore::Js(s) => Ok(Self::Js(
43 crate::backend::js::entities::memory::Memory::new(store, ty)?,
44 )),
45 }
46 }
47
48 #[inline]
50 pub fn new_from_existing(new_store: &mut impl AsStoreMut, memory: VMMemory) -> Self {
51 match new_store.as_store_mut().inner.store {
52 #[cfg(feature = "sys")]
53 crate::BackendStore::Sys(_) => Self::Sys(
54 crate::backend::sys::entities::memory::Memory::new_from_existing(
55 new_store,
56 memory.unwrap_sys(),
57 ),
58 ),
59 #[cfg(feature = "v8")]
60 crate::BackendStore::V8(_) => Self::V8(
61 crate::backend::v8::entities::memory::Memory::new_from_existing(
62 new_store,
63 memory.unwrap_v_8(),
64 ),
65 ),
66 #[cfg(feature = "js")]
67 crate::BackendStore::Js(_) => Self::Js(
68 crate::backend::js::entities::memory::Memory::new_from_existing(
69 new_store,
70 memory.unwrap_js(),
71 ),
72 ),
73 }
74 }
75
76 #[inline]
90 pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType {
91 match_rt!(on self => s {
92 s.ty(store)
93 })
94 }
95
96 pub fn size(&self, store: &impl AsStoreRef) -> Pages {
98 match_rt!(on self => s {
99 s.size(store)
100 })
101 }
102
103 #[inline]
136 pub fn grow<IntoPages>(
137 &self,
138 store: &mut impl AsStoreMut,
139 delta: IntoPages,
140 ) -> Result<Pages, MemoryError>
141 where
142 IntoPages: Into<Pages>,
143 {
144 match_rt!(on self => s {
145 s.grow(store, delta)
146 })
147 }
148
149 #[inline]
155 pub fn grow_at_least(
156 &self,
157 store: &mut impl AsStoreMut,
158 min_size: u64,
159 ) -> Result<(), MemoryError> {
160 match_rt!(on self => s {
161 s.grow_at_least(store, min_size)
162 })
163 }
164
165 #[inline]
167 pub fn reset(&self, store: &mut impl AsStoreMut) -> Result<(), MemoryError> {
168 match_rt!(on self => s {
169 s.reset(store)
170 })
171 }
172
173 #[inline]
175 #[deprecated(
176 since = "8.0.0",
177 note = "Since `Store` is no longer `Send + Sync`, this method cannot be used meaningfully. \
178 Use `copy`, then `attach` on the thread owning the other `Store` instead."
179 )]
180 pub fn copy_to_store(
181 &self,
182 store: &impl AsStoreRef,
183 new_store: &mut impl AsStoreMut,
184 ) -> Result<Self, MemoryError> {
185 self.copy(store)
186 .map(|new_memory| new_memory.attach(new_store).0)
187 }
188
189 #[inline]
190 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExternMemory) -> Self {
191 match &store.as_store_mut().inner.store {
192 #[cfg(feature = "sys")]
193 crate::BackendStore::Sys(s) => Self::Sys(
194 crate::backend::sys::entities::memory::Memory::from_vm_extern(store, vm_extern),
195 ),
196 #[cfg(feature = "v8")]
197 crate::BackendStore::V8(s) => Self::V8(
198 crate::backend::v8::entities::memory::Memory::from_vm_extern(store, vm_extern),
199 ),
200 #[cfg(feature = "js")]
201 crate::BackendStore::Js(s) => Self::Js(
202 crate::backend::js::entities::memory::Memory::from_vm_extern(store, vm_extern),
203 ),
204 }
205 }
206
207 #[inline]
209 pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
210 match_rt!(on self => s {
211 s.is_from_store(store)
212 })
213 }
214
215 #[inline]
218 pub fn copy(&self, store: &impl AsStoreRef) -> Result<SharedMemory, MemoryError> {
219 match_rt!(on self => s {
220 s.copy(store)
221 })
222 }
223
224 #[inline]
227 #[deprecated(
228 since = "8.0.0",
229 note = "Since `Store` is no longer `Send + Sync`, this method cannot be used meaningfully. \
230 Use `as_shared`, then `attach` on the thread owning the other `Store` instead."
231 )]
232 pub fn share_in_store(
233 &self,
234 store: &impl AsStoreRef,
235 new_store: &mut impl AsStoreMut,
236 ) -> Result<Self, MemoryError> {
237 if !self.ty(store).shared {
238 return Err(MemoryError::MemoryNotShared);
239 }
240
241 self.as_shared(store)
242 .ok_or_else(shared_memory_detach_error)
243 .map(|new_memory| new_memory.attach(new_store).0)
244 }
245
246 #[inline]
253 pub fn as_shared(&self, store: &impl AsStoreRef) -> Option<SharedMemory> {
254 if !self.ty(store).shared {
255 return None;
256 }
257
258 match_rt!(on self => s {
259 s.as_shared(store).ok()
260 })
261 }
262
263 #[inline]
265 pub(crate) fn to_vm_extern(&self) -> VMExtern {
266 match_rt!(on self => s {
267 s.to_vm_extern()
268 })
269 }
270}