Skip to main content

wasmedge_sdk/
io.rs

1use crate::{types::ExternRef, ValType, WasmValue};
2
3/// Describes the mapping of Rust type to Wasm type.
4///
5/// ```rust
6/// use wasmedge_sdk::{WasmValType, ValType};
7///
8/// assert_eq!(i32::WASM_TYPE, ValType::I32);
9/// ```
10///
11pub trait WasmValType {
12    /// The Wasm type.
13    const WASM_TYPE: ValType;
14}
15
16/// The `impl_wasm_val_type` macro is used to generate the following struct
17///
18/// ```ignore
19/// impl WasmValType for i32 {
20///     const WASM_TYPE: ValType = ValType::I32;
21/// }
22/// ```
23macro_rules! impl_wasm_val_type {
24    ($t:ty, $w:expr) => {
25        impl WasmValType for $t {
26            const WASM_TYPE: ValType = $w;
27        }
28    };
29}
30
31impl_wasm_val_type!(i8, ValType::I32);
32impl_wasm_val_type!(u8, ValType::I32);
33impl_wasm_val_type!(i16, ValType::I32);
34impl_wasm_val_type!(u16, ValType::I32);
35impl_wasm_val_type!(i32, ValType::I32);
36impl_wasm_val_type!(u32, ValType::I64);
37impl_wasm_val_type!(i64, ValType::I64);
38impl_wasm_val_type!(f32, ValType::F32);
39impl_wasm_val_type!(f64, ValType::F64);
40impl_wasm_val_type!(i128, ValType::V128);
41// impl_wasm_val_type!(FuncRef, ValType::FuncRef);
42impl_wasm_val_type!(ExternRef, ValType::ExternRef);
43
44#[cfg(test)]
45mod test_wasm_val_type {
46    use super::*;
47
48    #[test]
49    fn test_wasm_types() {
50        assert_eq!(i8::WASM_TYPE, ValType::I32);
51        assert_eq!(u8::WASM_TYPE, ValType::I32);
52        assert_eq!(i16::WASM_TYPE, ValType::I32);
53        assert_eq!(u16::WASM_TYPE, ValType::I32);
54        assert_eq!(i32::WASM_TYPE, ValType::I32);
55        assert_eq!(u32::WASM_TYPE, ValType::I64);
56        assert_eq!(i64::WASM_TYPE, ValType::I64);
57        assert_eq!(f32::WASM_TYPE, ValType::F32);
58        assert_eq!(f64::WASM_TYPE, ValType::F64);
59        assert_eq!(i128::WASM_TYPE, ValType::V128);
60        // assert_eq!(FuncRef::WASM_TYPE, ValType::FuncRef);
61        assert_eq!(ExternRef::WASM_TYPE, ValType::ExternRef);
62    }
63}
64
65/// Describes the mapping of a tuple of Rust types to Wasm types.
66///
67/// ```rust
68/// use wasmedge_sdk::{types::ExternRef, ValType, WasmValTypeList};
69///
70/// assert_eq!(
71///      <(i32, i64, f32, f64, ExternRef)>::wasm_types(),
72///      [ValType::I32, ValType::I64, ValType::F32, ValType::F64, ValType::ExternRef]
73/// );
74/// ```
75pub trait WasmValTypeList
76where
77    Self: Sized,
78{
79    /// The array type that can hold all the represented values.
80    ///
81    /// Note that all values are stored in their binary form.
82    type Array: AsMut<[i128]>;
83
84    /// Get the Wasm types for the tuple (list) of currently
85    /// represented values.
86    fn wasm_types() -> &'static [ValType];
87}
88
89macro_rules! impl_wasm_val_type_list {
90    ( $($o:ident),* ) => {
91        #[allow(unused_parens, dead_code)]
92        impl< $( $o ),* >
93            WasmValTypeList
94        for ( $( $o ),* )
95        where
96            $( $o: WasmValType ),*
97        {
98            type Array = [i128; count_idents!( $( $o ),* )];
99
100            fn wasm_types() -> &'static [ValType] {
101                &[
102                    $(
103                        $o::WASM_TYPE
104                    ),*
105                ]
106            }
107        }
108    };
109}
110
111// Count the number of identifiers at compile-time.
112macro_rules! count_idents {
113    ( $($idents:ident),* ) => {
114        {
115            #[allow(dead_code, non_camel_case_types)]
116            enum Idents { $( $idents, )* __CountIdentsLast }
117            const COUNT: usize = Idents::__CountIdentsLast as usize;
118            COUNT
119        }
120    };
121}
122
123impl_wasm_val_type_list!();
124impl_wasm_val_type_list!(A1);
125impl_wasm_val_type_list!(A1, A2);
126impl_wasm_val_type_list!(A1, A2, A3);
127impl_wasm_val_type_list!(A1, A2, A3, A4);
128impl_wasm_val_type_list!(A1, A2, A3, A4, A5);
129impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6);
130impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7);
131impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8);
132impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9);
133impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
134impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11);
135impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12);
136impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13);
137impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14);
138impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15);
139impl_wasm_val_type_list!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16);
140impl_wasm_val_type_list!(
141    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17
142);
143impl_wasm_val_type_list!(
144    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18
145);
146impl_wasm_val_type_list!(
147    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19
148);
149impl_wasm_val_type_list!(
150    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20
151);
152impl_wasm_val_type_list!(
153    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21
154);
155impl_wasm_val_type_list!(
156    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
157    A22
158);
159impl_wasm_val_type_list!(
160    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
161    A22, A23
162);
163impl_wasm_val_type_list!(
164    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
165    A22, A23, A24
166);
167impl_wasm_val_type_list!(
168    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
169    A22, A23, A24, A25
170);
171impl_wasm_val_type_list!(
172    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
173    A22, A23, A24, A25, A26
174);
175impl_wasm_val_type_list!(
176    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
177    A22, A23, A24, A25, A26, A27
178);
179impl_wasm_val_type_list!(
180    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
181    A22, A23, A24, A25, A26, A27, A28
182);
183impl_wasm_val_type_list!(
184    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
185    A22, A23, A24, A25, A26, A27, A28, A29
186);
187impl_wasm_val_type_list!(
188    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
189    A22, A23, A24, A25, A26, A27, A28, A29, A30
190);
191impl_wasm_val_type_list!(
192    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
193    A22, A23, A24, A25, A26, A27, A28, A29, A30, A31
194);
195impl_wasm_val_type_list!(
196    A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,
197    A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32
198);
199
200#[cfg(test)]
201mod test_wasm_val_type_list {
202    use super::*;
203
204    #[test]
205    fn test_wasm_types_for_multi_values() {
206        assert_eq!(<()>::wasm_types(), []);
207        assert_eq!(<(i32, i32)>::wasm_types(), [ValType::I32, ValType::I32]);
208        assert_eq!(<(i64, i64)>::wasm_types(), [ValType::I64, ValType::I64]);
209        assert_eq!(<(f32, f32)>::wasm_types(), [ValType::F32, ValType::F32]);
210        assert_eq!(<(f64, f64)>::wasm_types(), [ValType::F64, ValType::F64]);
211        // assert_eq!(
212        //     <(i32, i64, f32, f64, FuncRef, ExternRef)>::wasm_types(),
213        //     [
214        //         ValType::I32,
215        //         ValType::I64,
216        //         ValType::F32,
217        //         ValType::F64,
218        //         ValType::FuncRef,
219        //         ValType::ExternRef,
220        //     ]
221        // );
222        // assert_eq!(
223        //     <(FuncRef, ExternRef)>::wasm_types(),
224        //     [ValType::FuncRef, ValType::ExternRef]
225        // );
226    }
227}
228
229/// Defines the function converting a value of Rust type to the one of Wasm type.
230pub trait WasmVal {
231    fn to_wasm_value(self) -> WasmValue;
232}
233impl WasmVal for i8 {
234    fn to_wasm_value(self) -> WasmValue {
235        WasmValue::from_i32(self as i32)
236    }
237}
238impl WasmVal for u8 {
239    fn to_wasm_value(self) -> WasmValue {
240        WasmValue::from_i32(self as i32)
241    }
242}
243impl WasmVal for i16 {
244    fn to_wasm_value(self) -> WasmValue {
245        WasmValue::from_i32(self as i32)
246    }
247}
248impl WasmVal for u16 {
249    fn to_wasm_value(self) -> WasmValue {
250        WasmValue::from_i32(self as i32)
251    }
252}
253impl WasmVal for i32 {
254    fn to_wasm_value(self) -> WasmValue {
255        WasmValue::from_i32(self)
256    }
257}
258impl WasmVal for u32 {
259    fn to_wasm_value(self) -> WasmValue {
260        WasmValue::from_i64(self as i64)
261    }
262}
263impl WasmVal for i64 {
264    fn to_wasm_value(self) -> WasmValue {
265        WasmValue::from_i64(self)
266    }
267}
268impl WasmVal for f32 {
269    fn to_wasm_value(self) -> WasmValue {
270        WasmValue::from_f32(self)
271    }
272}
273impl WasmVal for f64 {
274    fn to_wasm_value(self) -> WasmValue {
275        WasmValue::from_f64(self)
276    }
277}
278impl WasmVal for i128 {
279    fn to_wasm_value(self) -> WasmValue {
280        WasmValue::from_v128(self)
281    }
282}
283// impl WasmVal for FuncRef {
284//     fn to_wasm_value(self) -> WasmValue {
285//         WasmValue::from_func_ref(self.inner)
286//     }
287// }
288impl WasmVal for ExternRef {
289    fn to_wasm_value(self) -> WasmValue {
290        self.inner
291    }
292}
293
294/// Generates arguments of [WasmValue](crate::WasmValue) types.
295///
296/// Notice that to use the macro, it is required to use `WasmVal` trait.
297#[macro_export]
298macro_rules! params {
299    ( $( $x:expr ),* ) => {
300        #[allow(unused_mut)]
301        {
302            let mut temp_vec = vec![];
303            $(
304                temp_vec.push($x.to_wasm_value());
305
306            )*
307            temp_vec
308        }
309    };
310}