1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use core::{fmt, marker::PhantomData, mem::MaybeUninit};
#[allow(missing_docs)]
#[repr(C)]
#[derive(Copy, Clone)]
pub union RawValue {
pub i32: i32,
pub i64: i64,
pub u32: u32,
pub u64: u64,
pub f32: f32,
pub f64: f64,
pub i128: i128,
pub u128: u128,
pub funcref: usize,
pub externref: usize,
pub bytes: [u8; 16],
}
impl From<i32> for RawValue {
fn from(value: i32) -> Self {
Self { i32: value }
}
}
impl From<i64> for RawValue {
fn from(value: i64) -> Self {
Self { i64: value }
}
}
impl From<f32> for RawValue {
fn from(value: f32) -> Self {
Self { f32: value }
}
}
impl From<f64> for RawValue {
fn from(value: f64) -> Self {
Self { f64: value }
}
}
impl Default for RawValue {
fn default() -> Self {
Self { bytes: [0; 16] }
}
}
impl fmt::Debug for RawValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawValue")
.field("bytes", unsafe { &self.bytes })
.finish()
}
}
macro_rules! partial_eq {
($($t:ty => $f:tt),*) => ($(
impl PartialEq<$t> for RawValue {
fn eq(&self, o: &$t) -> bool {
unsafe { self.$f == *o }
}
}
)*)
}
partial_eq! {
i32 => i32,
u32 => u32,
i64 => i64,
u64 => u64,
f32 => f32,
f64 => f64,
i128 => i128,
u128 => u128
}
impl PartialEq for RawValue {
fn eq(&self, o: &Self) -> bool {
unsafe { self.u128 == o.u128 }
}
}
pub unsafe trait ValueType: Copy {
fn zero_padding_bytes(&self, bytes: &mut [MaybeUninit<u8>]);
}
macro_rules! primitives {
($($t:ident)*) => ($(
unsafe impl ValueType for $t {
#[inline]
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {}
}
unsafe impl<const N: usize> ValueType for [$t; N] {
#[inline]
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {}
}
)*)
}
primitives! {
bool
i8 u8
i16 u16
i32 u32
i64 u64
i128 u128
isize usize
f32 f64
}
unsafe impl<T: ?Sized> ValueType for PhantomData<T> {
#[inline]
fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit<u8>]) {}
}