wasmer_types/
memory.rs

1use crate::{Pages, ValueType};
2use core::ops::SubAssign;
3use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
4#[cfg(feature = "enable-serde")]
5use serde::{Deserialize, Serialize};
6use std::convert::{TryFrom, TryInto};
7use std::iter::Sum;
8use std::ops::{Add, AddAssign};
9
10/// Implementation styles for WebAssembly linear memory.
11#[derive(
12    Debug,
13    Clone,
14    Copy,
15    PartialEq,
16    Eq,
17    Hash,
18    RkyvSerialize,
19    RkyvDeserialize,
20    Archive,
21    rkyv::CheckBytes,
22)]
23#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
24#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
25#[archive(as = "Self")]
26#[repr(u8)]
27pub enum MemoryStyle {
28    /// The actual memory can be resized and moved.
29    Dynamic {
30        /// Our chosen offset-guard size.
31        ///
32        /// It represents the size in bytes of extra guard pages after the end
33        /// to optimize loads and stores with constant offsets.
34        offset_guard_size: u64,
35    },
36    /// Address space is allocated up front.
37    Static {
38        /// The number of mapped and unmapped pages.
39        bound: Pages,
40        /// Our chosen offset-guard size.
41        ///
42        /// It represents the size in bytes of extra guard pages after the end
43        /// to optimize loads and stores with constant offsets.
44        offset_guard_size: u64,
45    },
46}
47
48impl MemoryStyle {
49    /// Returns the offset-guard size
50    pub fn offset_guard_size(&self) -> u64 {
51        match self {
52            Self::Dynamic { offset_guard_size } => *offset_guard_size,
53            Self::Static {
54                offset_guard_size, ..
55            } => *offset_guard_size,
56        }
57    }
58}
59
60/// Trait for the `Memory32` and `Memory64` marker types.
61///
62/// This allows code to be generic over 32-bit and 64-bit memories.
63/// # Safety
64/// Direct memory access is unsafe
65pub unsafe trait MemorySize: Copy {
66    /// Type used to represent an offset into a memory. This is `u32` or `u64`.
67    type Offset: Default
68        + std::fmt::Debug
69        + std::fmt::Display
70        + Eq
71        + Ord
72        + PartialEq<Self::Offset>
73        + PartialOrd<Self::Offset>
74        + Clone
75        + Copy
76        + Sync
77        + Send
78        + ValueType
79        + Into<u64>
80        + From<u32>
81        + From<u16>
82        + From<u8>
83        + TryFrom<u64>
84        + TryFrom<u32>
85        + TryFrom<u16>
86        + TryFrom<u8>
87        + TryFrom<i32>
88        + TryInto<usize>
89        + TryInto<u64>
90        + TryInto<u32>
91        + TryInto<u16>
92        + TryInto<u8>
93        + TryInto<i32>
94        + TryFrom<usize>
95        + Add<Self::Offset>
96        + Sum<Self::Offset>
97        + AddAssign<Self::Offset>
98        + SubAssign<Self::Offset>
99        + 'static;
100
101    /// Type used to pass this value as an argument or return value for a Wasm function.
102    type Native: super::NativeWasmType;
103
104    /// Zero value used for `WasmPtr::is_null`.
105    const ZERO: Self::Offset;
106
107    /// One value used for counting.
108    const ONE: Self::Offset;
109
110    /// Convert an `Offset` to a `Native`.
111    fn offset_to_native(offset: Self::Offset) -> Self::Native;
112
113    /// Convert a `Native` to an `Offset`.
114    fn native_to_offset(native: Self::Native) -> Self::Offset;
115
116    /// True if the memory is 64-bit
117    fn is_64bit() -> bool;
118}
119
120/// Marker trait for 32-bit memories.
121#[derive(Clone, Copy)]
122pub struct Memory32;
123unsafe impl MemorySize for Memory32 {
124    type Offset = u32;
125    type Native = i32;
126    const ZERO: Self::Offset = 0;
127    const ONE: Self::Offset = 1;
128    fn offset_to_native(offset: Self::Offset) -> Self::Native {
129        offset as Self::Native
130    }
131    fn native_to_offset(native: Self::Native) -> Self::Offset {
132        native as Self::Offset
133    }
134    fn is_64bit() -> bool {
135        false
136    }
137}
138
139/// Marker trait for 64-bit memories.
140#[derive(Clone, Copy)]
141pub struct Memory64;
142unsafe impl MemorySize for Memory64 {
143    type Offset = u64;
144    type Native = i64;
145    const ZERO: Self::Offset = 0;
146    const ONE: Self::Offset = 1;
147    fn offset_to_native(offset: Self::Offset) -> Self::Native {
148        offset as Self::Native
149    }
150    fn native_to_offset(native: Self::Native) -> Self::Offset {
151        native as Self::Offset
152    }
153    fn is_64bit() -> bool {
154        true
155    }
156}