1use crate::extern_ref::VMExternRef;
5use crate::lib::std::fmt;
6use crate::types::Type;
7use crate::values::{Value, WasmValueType};
8
9pub trait NativeWasmType: Sized {
25 type Abi: Copy + fmt::Debug;
27
28 const WASM_TYPE: Type;
30
31 #[doc(hidden)]
32 fn from_abi(abi: Self::Abi) -> Self;
33
34 #[doc(hidden)]
35 fn into_abi(self) -> Self::Abi;
36
37 fn to_binary(self) -> i128;
39
40 fn to_value<T: WasmValueType>(self) -> Value<T> {
42 let binary = self.to_binary();
43 let hack = 3;
46
47 unsafe { Value::read_value_from(&hack, &binary, Self::WASM_TYPE) }
48 }
49
50 fn from_binary(binary: i128) -> Self;
52}
53
54impl NativeWasmType for i32 {
55 const WASM_TYPE: Type = Type::I32;
56 type Abi = Self;
57
58 #[inline]
59 fn from_abi(abi: Self::Abi) -> Self {
60 abi
61 }
62
63 #[inline]
64 fn into_abi(self) -> Self::Abi {
65 self
66 }
67
68 #[inline]
69 fn to_binary(self) -> i128 {
70 self as _
71 }
72
73 #[inline]
74 fn from_binary(bits: i128) -> Self {
75 bits as _
76 }
77}
78
79impl NativeWasmType for i64 {
80 const WASM_TYPE: Type = Type::I64;
81 type Abi = Self;
82
83 #[inline]
84 fn from_abi(abi: Self::Abi) -> Self {
85 abi
86 }
87
88 #[inline]
89 fn into_abi(self) -> Self::Abi {
90 self
91 }
92
93 #[inline]
94 fn to_binary(self) -> i128 {
95 self as _
96 }
97
98 #[inline]
99 fn from_binary(bits: i128) -> Self {
100 bits as _
101 }
102}
103
104impl NativeWasmType for f32 {
105 const WASM_TYPE: Type = Type::F32;
106 type Abi = Self;
107
108 #[inline]
109 fn from_abi(abi: Self::Abi) -> Self {
110 abi
111 }
112
113 #[inline]
114 fn into_abi(self) -> Self::Abi {
115 self
116 }
117
118 #[inline]
119 fn to_binary(self) -> i128 {
120 self.to_bits() as _
121 }
122
123 #[inline]
124 fn from_binary(bits: i128) -> Self {
125 Self::from_bits(bits as _)
126 }
127}
128
129impl NativeWasmType for f64 {
130 const WASM_TYPE: Type = Type::F64;
131 type Abi = Self;
132
133 #[inline]
134 fn from_abi(abi: Self::Abi) -> Self {
135 abi
136 }
137
138 #[inline]
139 fn into_abi(self) -> Self::Abi {
140 self
141 }
142
143 #[inline]
144 fn to_binary(self) -> i128 {
145 self.to_bits() as _
146 }
147
148 #[inline]
149 fn from_binary(bits: i128) -> Self {
150 Self::from_bits(bits as _)
151 }
152}
153
154impl NativeWasmType for u128 {
155 const WASM_TYPE: Type = Type::V128;
156 type Abi = Self;
157
158 #[inline]
159 fn from_abi(abi: Self::Abi) -> Self {
160 abi
161 }
162
163 #[inline]
164 fn into_abi(self) -> Self::Abi {
165 self
166 }
167
168 #[inline]
169 fn to_binary(self) -> i128 {
170 self as _
171 }
172
173 #[inline]
174 fn from_binary(bits: i128) -> Self {
175 bits as _
176 }
177}
178
179impl NativeWasmType for VMExternRef {
180 const WASM_TYPE: Type = Type::ExternRef;
181 type Abi = Self;
182
183 #[inline]
184 fn from_abi(abi: Self::Abi) -> Self {
185 abi
186 }
187
188 #[inline]
189 fn into_abi(self) -> Self::Abi {
190 self
191 }
192
193 #[inline]
194 fn to_binary(self) -> i128 {
195 self.to_binary()
196 }
197
198 #[inline]
199 fn from_binary(bits: i128) -> Self {
200 unsafe { Self::from_binary(bits) }
202 }
203}
204
205#[cfg(test)]
206mod test_native_type {
207 use super::*;
208 use crate::types::Type;
209
210 #[test]
211 fn test_wasm_types() {
212 assert_eq!(i32::WASM_TYPE, Type::I32);
213 assert_eq!(i64::WASM_TYPE, Type::I64);
214 assert_eq!(f32::WASM_TYPE, Type::F32);
215 assert_eq!(f64::WASM_TYPE, Type::F64);
216 assert_eq!(u128::WASM_TYPE, Type::V128);
217 }
218
219 #[test]
220 fn test_roundtrip() {
221 assert_eq!(i32::from_binary(42i32.to_binary()), 42i32);
222 assert_eq!(i64::from_binary(42i64.to_binary()), 42i64);
223 assert_eq!(f32::from_binary(42f32.to_binary()), 42f32);
224 assert_eq!(f64::from_binary(42f64.to_binary()), 42f64);
225 assert_eq!(u128::from_binary(42u128.to_binary()), 42u128);
226 }
227}
228
229pub unsafe trait ValueType: Copy
257where
258 Self: Sized,
259{
260}
261
262macro_rules! impl_value_type_for {
263 ( $($type:ty),* ) => {
264 $(
265 unsafe impl ValueType for $type {}
266 )*
267 };
268}
269
270impl_value_type_for!(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64);