wasm/execution/runtime_structure/memory_instances/
mod.rs

1use crate::{core::utils::ToUsizeExt, Limits, MemType, RuntimeError, TrapError};
2
3pub mod linear_memory;
4
5pub struct MemInst {
6    pub ty: MemType,
7    pub mem: linear_memory::LinearMemory,
8}
9impl core::fmt::Debug for MemInst {
10    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11        f.debug_struct("MemInst")
12            .field("ty", &self.ty)
13            .finish_non_exhaustive()
14    }
15}
16
17impl MemInst {
18    /// <https://webassembly.github.io/spec/core/exec/modules.html#growing-memories>
19    pub fn grow(&mut self, n: u32) -> Result<(), RuntimeError> {
20        // TODO refactor error, the spec Table.grow raises Memory.{SizeOverflow, SizeLimit, OutOfMemory}
21        let len = n + self.mem.pages() as u32;
22        if len > Limits::MAX_MEM_PAGES {
23            return Err(TrapError::MemoryOrDataAccessOutOfBounds.into());
24        }
25
26        // roughly matches step 4,5,6
27        // checks limits_prime.valid() for limits_prime := { min: len, max: self.ty.lim.max }
28        // https://webassembly.github.io/spec/core/valid/types.html#limits
29        if self.ty.limits.max.map(|max| len > max).unwrap_or(false) {
30            return Err(TrapError::MemoryOrDataAccessOutOfBounds.into());
31        }
32        let limits_prime = Limits {
33            min: len,
34            max: self.ty.limits.max,
35        };
36
37        self.mem.grow(n.try_into().unwrap());
38
39        self.ty.limits = limits_prime;
40        Ok(())
41    }
42
43    /// Can never be bigger than 65,356 pages
44    pub fn size(&self) -> usize {
45        self.mem.len() / (crate::Limits::MEM_PAGE_SIZE.into_usize())
46    }
47}