near_vm_vm/memory/
mod.rs

1// This file contains code from external sources.
2// Attributions: https://github.com/wasmerio/wasmer/blob/2.3.0/ATTRIBUTIONS.md
3
4//! Memory management for linear memories.
5//!
6//! `LinearMemory` is to WebAssembly linear memories what `Table` is to WebAssembly tables.
7
8use near_vm_types::Pages;
9use thiserror::Error;
10
11mod linear_memory;
12
13pub use linear_memory::LinearMemory;
14
15/// Error type describing things that can go wrong when operating on Wasm Memories.
16#[derive(Error, Debug, Clone, PartialEq, Hash)]
17pub enum MemoryError {
18    /// Low level error with mmap.
19    #[error("Error when allocating memory: {0}")]
20    Region(String),
21    /// The operation would cause the size of the memory to exceed the maximum or would cause
22    /// an overflow leading to unindexable memory.
23    #[error("The memory could not grow: current size {} pages, requested increase: {} pages", current.0, attempted_delta.0)]
24    CouldNotGrow {
25        /// The current size in pages.
26        current: Pages,
27        /// The attempted amount to grow by in pages.
28        attempted_delta: Pages,
29    },
30    /// The operation would cause the size of the memory size exceed the maximum.
31    #[error("The memory is invalid because {}", reason)]
32    InvalidMemory {
33        /// The reason why the provided memory is invalid.
34        reason: String,
35    },
36    /// Caller asked for more minimum memory than we can give them.
37    #[error("The minimum requested ({} pages) memory is greater than the maximum allowed memory ({} pages)", min_requested.0, max_allowed.0)]
38    MinimumMemoryTooLarge {
39        /// The number of pages requested as the minimum amount of memory.
40        min_requested: Pages,
41        /// The maximum amount of memory we can allocate.
42        max_allowed: Pages,
43    },
44    /// Caller asked for a maximum memory greater than we can give them.
45    #[error("The maximum requested memory ({} pages) is greater than the maximum allowed memory ({} pages)", max_requested.0, max_allowed.0)]
46    MaximumMemoryTooLarge {
47        /// The number of pages requested as the maximum amount of memory.
48        max_requested: Pages,
49        /// The number of pages requested as the maximum amount of memory.
50        max_allowed: Pages,
51    },
52    /// A user defined error value, used for error cases not listed above.
53    #[error("A user-defined error occurred: {0}")]
54    Generic(String),
55}
56
57/// Implementation styles for WebAssembly linear memory.
58#[derive(Debug, Clone, PartialEq, Eq, Hash, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
59pub enum MemoryStyle {
60    /// The actual memory can be resized and moved.
61    Dynamic {
62        /// Our chosen offset-guard size.
63        ///
64        /// It represents the size in bytes of extra guard pages after the end
65        /// to optimize loads and stores with constant offsets.
66        offset_guard_size: u64,
67    },
68    /// Address space is allocated up front.
69    Static {
70        /// The number of mapped and unmapped pages.
71        bound: Pages,
72        /// Our chosen offset-guard size.
73        ///
74        /// It represents the size in bytes of extra guard pages after the end
75        /// to optimize loads and stores with constant offsets.
76        offset_guard_size: u64,
77    },
78}
79
80impl MemoryStyle {
81    /// Returns the offset-guard size
82    pub fn offset_guard_size(&self) -> u64 {
83        match self {
84            Self::Dynamic { offset_guard_size } => *offset_guard_size,
85            Self::Static { offset_guard_size, .. } => *offset_guard_size,
86        }
87    }
88}