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