1use super::{shared::SharedMemory, 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 #[cfg(feature = "jsc")]
46 crate::BackendStore::Jsc(s) => Ok(Self::Jsc(
47 crate::backend::jsc::entities::memory::Memory::new(store, ty)?,
48 )),
49 }
50 }
51
52 #[inline]
54 pub fn new_from_existing(new_store: &mut impl AsStoreMut, memory: VMMemory) -> Self {
55 match new_store.as_store_mut().inner.store {
56 #[cfg(feature = "sys")]
57 crate::BackendStore::Sys(_) => Self::Sys(
58 crate::backend::sys::entities::memory::Memory::new_from_existing(
59 new_store,
60 memory.unwrap_sys(),
61 ),
62 ),
63 #[cfg(feature = "v8")]
64 crate::BackendStore::V8(_) => Self::V8(
65 crate::backend::v8::entities::memory::Memory::new_from_existing(
66 new_store,
67 memory.unwrap_v_8(),
68 ),
69 ),
70 #[cfg(feature = "js")]
71 crate::BackendStore::Js(_) => Self::Js(
72 crate::backend::js::entities::memory::Memory::new_from_existing(
73 new_store,
74 memory.unwrap_js(),
75 ),
76 ),
77 #[cfg(feature = "jsc")]
78 crate::BackendStore::Jsc(_) => Self::Jsc(
79 crate::backend::jsc::entities::memory::Memory::new_from_existing(
80 new_store,
81 memory.unwrap_jsc(),
82 ),
83 ),
84 }
85 }
86
87 #[inline]
101 pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType {
102 match_rt!(on self => s {
103 s.ty(store)
104 })
105 }
106
107 pub fn size(&self, store: &impl AsStoreRef) -> Pages {
109 match_rt!(on self => s {
110 s.size(store)
111 })
112 }
113
114 #[inline]
147 pub fn grow<IntoPages>(
148 &self,
149 store: &mut impl AsStoreMut,
150 delta: IntoPages,
151 ) -> Result<Pages, MemoryError>
152 where
153 IntoPages: Into<Pages>,
154 {
155 match_rt!(on self => s {
156 s.grow(store, delta)
157 })
158 }
159
160 #[inline]
166 pub fn grow_at_least(
167 &self,
168 store: &mut impl AsStoreMut,
169 min_size: u64,
170 ) -> Result<(), MemoryError> {
171 match_rt!(on self => s {
172 s.grow_at_least(store, min_size)
173 })
174 }
175
176 #[inline]
178 pub fn reset(&self, store: &mut impl AsStoreMut) -> Result<(), MemoryError> {
179 match_rt!(on self => s {
180 s.reset(store)
181 })
182 }
183
184 #[inline]
187 pub fn copy_to_store(
188 &self,
189 store: &impl AsStoreRef,
190 new_store: &mut impl AsStoreMut,
191 ) -> Result<Self, MemoryError> {
192 if !self.ty(store).shared {
193 return Err(MemoryError::InvalidMemory {
195 reason: "memory is not a shared memory type".to_string(),
196 });
197 }
198
199 match self {
200 #[cfg(feature = "sys")]
201 Self::Sys(s) => s.try_copy(store).map(|new_memory| {
202 Self::new_from_existing(
203 new_store,
204 VMMemory::Sys(crate::backend::sys::vm::VMMemory(new_memory)),
205 )
206 }),
207
208 #[cfg(feature = "v8")]
209 Self::V8(s) => s
210 .try_copy(store)
211 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::V8(new_memory))),
212 #[cfg(feature = "js")]
213 Self::Js(s) => s
214 .try_copy(store)
215 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Js(new_memory))),
216 #[cfg(feature = "jsc")]
217 Self::Jsc(s) => s
218 .try_copy(store)
219 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Jsc(new_memory))),
220 }
221 }
222
223 #[inline]
224 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExternMemory) -> Self {
225 match &store.as_store_mut().inner.store {
226 #[cfg(feature = "sys")]
227 crate::BackendStore::Sys(s) => Self::Sys(
228 crate::backend::sys::entities::memory::Memory::from_vm_extern(store, vm_extern),
229 ),
230 #[cfg(feature = "v8")]
231 crate::BackendStore::V8(s) => Self::V8(
232 crate::backend::v8::entities::memory::Memory::from_vm_extern(store, vm_extern),
233 ),
234 #[cfg(feature = "js")]
235 crate::BackendStore::Js(s) => Self::Js(
236 crate::backend::js::entities::memory::Memory::from_vm_extern(store, vm_extern),
237 ),
238 #[cfg(feature = "jsc")]
239 crate::BackendStore::Jsc(s) => Self::Jsc(
240 crate::backend::jsc::entities::memory::Memory::from_vm_extern(store, vm_extern),
241 ),
242 }
243 }
244
245 #[inline]
247 pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
248 match_rt!(on self => s {
249 s.is_from_store(store)
250 })
251 }
252
253 #[inline]
260 pub fn try_clone(&self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
261 match self {
262 #[cfg(feature = "sys")]
263 Self::Sys(s) => s.try_clone(store).map(VMMemory::Sys),
264 #[cfg(feature = "v8")]
265 Self::V8(s) => s.try_clone(store).map(VMMemory::V8),
266 #[cfg(feature = "js")]
267 Self::Js(s) => s.try_clone(store).map(VMMemory::Js),
268 #[cfg(feature = "jsc")]
269 Self::Jsc(s) => s.try_clone(store).map(VMMemory::Jsc),
270 }
271 }
272
273 #[inline]
276 pub fn share_in_store(
277 &self,
278 store: &impl AsStoreRef,
279 new_store: &mut impl AsStoreMut,
280 ) -> Result<Self, MemoryError> {
281 if !self.ty(store).shared {
282 return Err(MemoryError::InvalidMemory {
284 reason: "memory is not a shared memory type".to_string(),
285 });
286 }
287
288 match self {
289 #[cfg(feature = "sys")]
290 Self::Sys(s) => s
291 .try_clone(store)
292 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Sys(new_memory))),
293 #[cfg(feature = "v8")]
294 Self::V8(s) => s
295 .try_clone(store)
296 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::V8(new_memory))),
297 #[cfg(feature = "js")]
298 Self::Js(s) => s
299 .try_clone(store)
300 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Js(new_memory))),
301 #[cfg(feature = "jsc")]
302 Self::Jsc(s) => s
303 .try_clone(store)
304 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Jsc(new_memory))),
305 }
306 }
307
308 #[inline]
315 pub fn as_shared(&self, store: &impl AsStoreRef) -> Option<SharedMemory> {
316 if !self.ty(store).shared {
317 return None;
318 }
319
320 match_rt!(on self => s {
321 s.as_shared(store)
322 })
323 }
324
325 #[inline]
327 pub(crate) fn to_vm_extern(&self) -> VMExtern {
328 match_rt!(on self => s {
329 s.to_vm_extern()
330 })
331 }
332}