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}