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!(Memory
11 @cfg feature = "artifact-size" => derive(loupe::MemoryUsage)
12 @derives Debug, Clone, PartialEq, Eq, derive_more::From
13);
14
15impl BackendMemory {
16 #[inline]
30 pub fn new(store: &mut impl AsStoreMut, ty: MemoryType) -> Result<Self, MemoryError> {
31 match &store.as_store_mut().inner.store {
32 #[cfg(feature = "sys")]
33 crate::BackendStore::Sys(s) => Ok(Self::Sys(
34 crate::backend::sys::entities::memory::Memory::new(store, ty)?,
35 )),
36 #[cfg(feature = "wamr")]
37 crate::BackendStore::Wamr(s) => Ok(Self::Wamr(
38 crate::backend::wamr::entities::memory::Memory::new(store, ty)?,
39 )),
40 #[cfg(feature = "wasmi")]
41 crate::BackendStore::Wasmi(s) => Ok(Self::Wasmi(
42 crate::backend::wasmi::entities::memory::Memory::new(store, ty)?,
43 )),
44 #[cfg(feature = "v8")]
45 crate::BackendStore::V8(s) => Ok(Self::V8(
46 crate::backend::v8::entities::memory::Memory::new(store, ty)?,
47 )),
48 #[cfg(feature = "js")]
49 crate::BackendStore::Js(s) => Ok(Self::Js(
50 crate::backend::js::entities::memory::Memory::new(store, ty)?,
51 )),
52 #[cfg(feature = "jsc")]
53 crate::BackendStore::Jsc(s) => Ok(Self::Jsc(
54 crate::backend::jsc::entities::memory::Memory::new(store, ty)?,
55 )),
56 }
57 }
58
59 #[inline]
61 pub fn new_from_existing(new_store: &mut impl AsStoreMut, memory: VMMemory) -> Self {
62 match new_store.as_store_mut().inner.store {
63 #[cfg(feature = "sys")]
64 crate::BackendStore::Sys(_) => Self::Sys(
65 crate::backend::sys::entities::memory::Memory::new_from_existing(
66 new_store,
67 memory.into_sys(),
68 ),
69 ),
70 #[cfg(feature = "wamr")]
71 crate::BackendStore::Wamr(_) => Self::Wamr(
72 crate::backend::wamr::entities::memory::Memory::new_from_existing(
73 new_store,
74 memory.into_wamr(),
75 ),
76 ),
77 #[cfg(feature = "wasmi")]
78 crate::BackendStore::Wasmi(_) => Self::Wasmi(
79 crate::backend::wasmi::entities::memory::Memory::new_from_existing(
80 new_store,
81 memory.into_wasmi(),
82 ),
83 ),
84 #[cfg(feature = "v8")]
85 crate::BackendStore::V8(_) => Self::V8(
86 crate::backend::v8::entities::memory::Memory::new_from_existing(
87 new_store,
88 memory.into_v8(),
89 ),
90 ),
91 #[cfg(feature = "js")]
92 crate::BackendStore::Js(_) => Self::Js(
93 crate::backend::js::entities::memory::Memory::new_from_existing(
94 new_store,
95 memory.into_js(),
96 ),
97 ),
98 #[cfg(feature = "jsc")]
99 crate::BackendStore::Jsc(_) => Self::Jsc(
100 crate::backend::jsc::entities::memory::Memory::new_from_existing(
101 new_store,
102 memory.into_jsc(),
103 ),
104 ),
105 }
106 }
107
108 #[inline]
122 pub fn ty(&self, store: &impl AsStoreRef) -> MemoryType {
123 match_rt!(on self => s {
124 s.ty(store)
125 })
126 }
127
128 pub fn size(&self, store: &impl AsStoreRef) -> Pages {
130 match_rt!(on self => s {
131 s.size(store)
132 })
133 }
134
135 #[inline]
168 pub fn grow<IntoPages>(
169 &self,
170 store: &mut impl AsStoreMut,
171 delta: IntoPages,
172 ) -> Result<Pages, MemoryError>
173 where
174 IntoPages: Into<Pages>,
175 {
176 match_rt!(on self => s {
177 s.grow(store, delta)
178 })
179 }
180
181 #[inline]
187 pub fn grow_at_least(
188 &self,
189 store: &mut impl AsStoreMut,
190 min_size: u64,
191 ) -> Result<(), MemoryError> {
192 match_rt!(on self => s {
193 s.grow_at_least(store, min_size)
194 })
195 }
196
197 #[inline]
199 pub fn reset(&self, store: &mut impl AsStoreMut) -> Result<(), MemoryError> {
200 match_rt!(on self => s {
201 s.reset(store)
202 })
203 }
204
205 #[inline]
208 pub fn copy_to_store(
209 &self,
210 store: &impl AsStoreRef,
211 new_store: &mut impl AsStoreMut,
212 ) -> Result<Self, MemoryError> {
213 if !self.ty(store).shared {
214 return Err(MemoryError::InvalidMemory {
216 reason: "memory is not a shared memory type".to_string(),
217 });
218 }
219
220 match self {
221 #[cfg(feature = "sys")]
222 Self::Sys(s) => s.try_copy(store).map(|new_memory| {
223 Self::new_from_existing(
224 new_store,
225 VMMemory::Sys(crate::backend::sys::vm::VMMemory(new_memory)),
226 )
227 }),
228 #[cfg(feature = "wamr")]
229 Self::Wamr(s) => s
230 .try_copy(store)
231 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Wamr(new_memory))),
232 #[cfg(feature = "wasmi")]
233 Self::Wasmi(s) => s
234 .try_copy(store)
235 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Wasmi(new_memory))),
236
237 #[cfg(feature = "v8")]
238 Self::V8(s) => s
239 .try_copy(store)
240 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::V8(new_memory))),
241 #[cfg(feature = "js")]
242 Self::Js(s) => s
243 .try_copy(store)
244 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Js(new_memory))),
245 #[cfg(feature = "jsc")]
246 Self::Jsc(s) => s
247 .try_copy(store)
248 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Jsc(new_memory))),
249 }
250 }
251
252 #[inline]
253 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExternMemory) -> Self {
254 match &store.as_store_mut().inner.store {
255 #[cfg(feature = "sys")]
256 crate::BackendStore::Sys(s) => Self::Sys(
257 crate::backend::sys::entities::memory::Memory::from_vm_extern(store, vm_extern),
258 ),
259 #[cfg(feature = "wamr")]
260 crate::BackendStore::Wamr(s) => Self::Wamr(
261 crate::backend::wamr::entities::memory::Memory::from_vm_extern(store, vm_extern),
262 ),
263 #[cfg(feature = "wasmi")]
264 crate::BackendStore::Wasmi(s) => Self::Wasmi(
265 crate::backend::wasmi::entities::memory::Memory::from_vm_extern(store, vm_extern),
266 ),
267 #[cfg(feature = "v8")]
268 crate::BackendStore::V8(s) => Self::V8(
269 crate::backend::v8::entities::memory::Memory::from_vm_extern(store, vm_extern),
270 ),
271 #[cfg(feature = "js")]
272 crate::BackendStore::Js(s) => Self::Js(
273 crate::backend::js::entities::memory::Memory::from_vm_extern(store, vm_extern),
274 ),
275 #[cfg(feature = "jsc")]
276 crate::BackendStore::Jsc(s) => Self::Jsc(
277 crate::backend::jsc::entities::memory::Memory::from_vm_extern(store, vm_extern),
278 ),
279 }
280 }
281
282 #[inline]
284 pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
285 match_rt!(on self => s {
286 s.is_from_store(store)
287 })
288 }
289
290 #[inline]
297 pub fn try_clone(&self, store: &impl AsStoreRef) -> Result<VMMemory, MemoryError> {
298 match self {
299 #[cfg(feature = "sys")]
300 Self::Sys(s) => s.try_clone(store).map(VMMemory::Sys),
301 #[cfg(feature = "wamr")]
302 Self::Wamr(s) => s.try_clone(store).map(VMMemory::Wamr),
303 #[cfg(feature = "wasmi")]
304 Self::Wasmi(s) => s.try_clone(store).map(VMMemory::Wasmi),
305 #[cfg(feature = "v8")]
306 Self::V8(s) => s.try_clone(store).map(VMMemory::V8),
307 #[cfg(feature = "js")]
308 Self::Js(s) => s.try_clone(store).map(VMMemory::Js),
309 #[cfg(feature = "jsc")]
310 Self::Jsc(s) => s.try_clone(store).map(VMMemory::Jsc),
311 }
312 }
313
314 #[inline]
317 pub fn share_in_store(
318 &self,
319 store: &impl AsStoreRef,
320 new_store: &mut impl AsStoreMut,
321 ) -> Result<Self, MemoryError> {
322 if !self.ty(store).shared {
323 return Err(MemoryError::InvalidMemory {
325 reason: "memory is not a shared memory type".to_string(),
326 });
327 }
328
329 match self {
330 #[cfg(feature = "sys")]
331 Self::Sys(s) => s
332 .try_clone(store)
333 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Sys(new_memory))),
334 #[cfg(feature = "wamr")]
335 Self::Wamr(s) => s
336 .try_clone(store)
337 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Wamr(new_memory))),
338 #[cfg(feature = "wasmi")]
339 Self::Wasmi(s) => s
340 .try_clone(store)
341 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Wasmi(new_memory))),
342 #[cfg(feature = "v8")]
343 Self::V8(s) => s
344 .try_clone(store)
345 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::V8(new_memory))),
346 #[cfg(feature = "js")]
347 Self::Js(s) => s
348 .try_clone(store)
349 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Js(new_memory))),
350 #[cfg(feature = "jsc")]
351 Self::Jsc(s) => s
352 .try_clone(store)
353 .map(|new_memory| Self::new_from_existing(new_store, VMMemory::Jsc(new_memory))),
354 }
355 }
356
357 #[inline]
364 pub fn as_shared(&self, store: &impl AsStoreRef) -> Option<SharedMemory> {
365 if !self.ty(store).shared {
366 return None;
367 }
368
369 match_rt!(on self => s {
370 s.as_shared(store)
371 })
372 }
373
374 #[inline]
376 pub(crate) fn to_vm_extern(&self) -> VMExtern {
377 match_rt!(on self => s {
378 s.to_vm_extern()
379 })
380 }
381}