1use crate::{Pages, ValueType, WASM_PAGE_SIZE};
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#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, RkyvSerialize, RkyvDeserialize, Archive)]
12#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
13#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
14#[rkyv(derive(Debug), compare(PartialEq))]
15#[repr(u8)]
16pub enum MemoryStyle {
17 Dynamic {
19 offset_guard_size: u64,
24 },
25 Static,
32}
33
34impl MemoryStyle {
35 pub const fn static_bound() -> Pages {
37 Pages::max_value()
38 }
39
40 pub const fn static_offset_guard_size() -> u64 {
43 0x1_0000_0000 + WASM_PAGE_SIZE as u64
44 }
45
46 pub fn offset_guard_size(&self) -> u64 {
48 match self {
49 Self::Dynamic { offset_guard_size } => *offset_guard_size,
50 Self::Static => Self::static_offset_guard_size(),
51 }
52 }
53}
54
55pub unsafe trait MemorySize: Copy {
61 type Offset: Default
63 + std::fmt::Debug
64 + std::fmt::Display
65 + Eq
66 + Ord
67 + PartialEq<Self::Offset>
68 + PartialOrd<Self::Offset>
69 + Clone
70 + Copy
71 + Sync
72 + Send
73 + ValueType
74 + Into<u64>
75 + From<u32>
76 + From<u16>
77 + From<u8>
78 + TryFrom<u64>
79 + TryFrom<u32>
80 + TryFrom<u16>
81 + TryFrom<u8>
82 + TryFrom<i32>
83 + TryInto<usize>
84 + TryInto<u64>
85 + TryInto<u32>
86 + TryInto<u16>
87 + TryInto<u8>
88 + TryInto<i32>
89 + TryFrom<usize>
90 + Add<Self::Offset>
91 + Sum<Self::Offset>
92 + AddAssign<Self::Offset>
93 + SubAssign<Self::Offset>
94 + 'static;
95
96 type Native: super::NativeWasmType;
98
99 const ZERO: Self::Offset;
101
102 const ONE: Self::Offset;
104
105 fn offset_to_native(offset: Self::Offset) -> Self::Native;
107
108 fn native_to_offset(native: Self::Native) -> Self::Offset;
110
111 fn is_64bit() -> bool;
113}
114
115#[derive(Clone, Copy)]
117pub struct Memory32;
118unsafe impl MemorySize for Memory32 {
119 type Offset = u32;
120 type Native = i32;
121 const ZERO: Self::Offset = 0;
122 const ONE: Self::Offset = 1;
123 fn offset_to_native(offset: Self::Offset) -> Self::Native {
124 offset as Self::Native
125 }
126 fn native_to_offset(native: Self::Native) -> Self::Offset {
127 native as Self::Offset
128 }
129 fn is_64bit() -> bool {
130 false
131 }
132}
133
134#[derive(Clone, Copy)]
136pub struct Memory64;
137unsafe impl MemorySize for Memory64 {
138 type Offset = u64;
139 type Native = i64;
140 const ZERO: Self::Offset = 0;
141 const ONE: Self::Offset = 1;
142 fn offset_to_native(offset: Self::Offset) -> Self::Native {
143 offset as Self::Native
144 }
145 fn native_to_offset(native: Self::Native) -> Self::Offset {
146 native as Self::Offset
147 }
148 fn is_64bit() -> bool {
149 true
150 }
151}