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#[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 {
27 bound: Pages,
29 offset_guard_size: u64,
34 },
35}
36
37impl MemoryStyle {
38 pub fn offset_guard_size(&self) -> u64 {
40 match self {
41 Self::Dynamic { offset_guard_size } => *offset_guard_size,
42 Self::Static {
43 offset_guard_size, ..
44 } => *offset_guard_size,
45 }
46 }
47}
48
49pub unsafe trait MemorySize: Copy {
55 type Offset: Default
57 + std::fmt::Debug
58 + std::fmt::Display
59 + Eq
60 + Ord
61 + PartialEq<Self::Offset>
62 + PartialOrd<Self::Offset>
63 + Clone
64 + Copy
65 + Sync
66 + Send
67 + ValueType
68 + Into<u64>
69 + From<u32>
70 + From<u16>
71 + From<u8>
72 + TryFrom<u64>
73 + TryFrom<u32>
74 + TryFrom<u16>
75 + TryFrom<u8>
76 + TryFrom<i32>
77 + TryInto<usize>
78 + TryInto<u64>
79 + TryInto<u32>
80 + TryInto<u16>
81 + TryInto<u8>
82 + TryInto<i32>
83 + TryFrom<usize>
84 + Add<Self::Offset>
85 + Sum<Self::Offset>
86 + AddAssign<Self::Offset>
87 + SubAssign<Self::Offset>
88 + 'static;
89
90 type Native: super::NativeWasmType;
92
93 const ZERO: Self::Offset;
95
96 const ONE: Self::Offset;
98
99 fn offset_to_native(offset: Self::Offset) -> Self::Native;
101
102 fn native_to_offset(native: Self::Native) -> Self::Offset;
104
105 fn is_64bit() -> bool;
107}
108
109#[derive(Clone, Copy)]
111pub struct Memory32;
112unsafe impl MemorySize for Memory32 {
113 type Offset = u32;
114 type Native = i32;
115 const ZERO: Self::Offset = 0;
116 const ONE: Self::Offset = 1;
117 fn offset_to_native(offset: Self::Offset) -> Self::Native {
118 offset as Self::Native
119 }
120 fn native_to_offset(native: Self::Native) -> Self::Offset {
121 native as Self::Offset
122 }
123 fn is_64bit() -> bool {
124 false
125 }
126}
127
128#[derive(Clone, Copy)]
130pub struct Memory64;
131unsafe impl MemorySize for Memory64 {
132 type Offset = u64;
133 type Native = i64;
134 const ZERO: Self::Offset = 0;
135 const ONE: Self::Offset = 1;
136 fn offset_to_native(offset: Self::Offset) -> Self::Native {
137 offset as Self::Native
138 }
139 fn native_to_offset(native: Self::Native) -> Self::Offset {
140 native as Self::Offset
141 }
142 fn is_64bit() -> bool {
143 true
144 }
145}