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}