wamr_rust_sdk/
value.rs

1/*
2 * Copyright (C) 2019 Intel Corporation. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4 */
5
6//! a wasm value. Always used as function parameters and results
7
8#[derive(Debug, PartialEq)]
9pub enum WasmValue {
10    Void,
11    I32(i32),
12    I64(i64),
13    F32(f32),
14    F64(f64),
15    V128(i128),
16}
17
18impl WasmValue {
19    pub fn encode(&self) -> Vec<u32> {
20        match *self {
21            WasmValue::Void => {
22                vec![]
23            }
24            WasmValue::I32(value) => {
25                let in_u32_array = unsafe { std::mem::transmute::<i32, [u32; 1]>(value) };
26                vec![in_u32_array[0]]
27            }
28            WasmValue::I64(value) => {
29                let in_u32_array = unsafe { std::mem::transmute::<i64, [u32; 2]>(value) };
30                vec![in_u32_array[0], in_u32_array[1]]
31            }
32            WasmValue::F32(value) => {
33                let in_u32_array = unsafe { std::mem::transmute::<f32, [u32; 1]>(value) };
34                vec![in_u32_array[0]]
35            }
36            WasmValue::F64(value) => {
37                let in_u32_array = unsafe { std::mem::transmute::<f64, [u32; 2]>(value) };
38                vec![in_u32_array[0], in_u32_array[1]]
39            }
40            WasmValue::V128(value) => {
41                let in_u32_array = unsafe { std::mem::transmute::<i128, [u32; 4]>(value) };
42                vec![
43                    in_u32_array[0],
44                    in_u32_array[1],
45                    in_u32_array[2],
46                    in_u32_array[3],
47                ]
48            }
49        }
50    }
51
52    pub fn decode_to_i32(binary: &[u32]) -> WasmValue {
53        let binary: [u32; 1] = [binary[0]];
54        WasmValue::I32(unsafe { std::mem::transmute::<[u32; 1], i32>(binary) })
55    }
56
57    pub fn decode_to_f32(binary: &[u32]) -> WasmValue {
58        let binary: [u32; 1] = [binary[0]];
59        WasmValue::F32(unsafe { std::mem::transmute::<[u32; 1], f32>(binary) })
60    }
61
62    pub fn decode_to_i64(binary: &[u32]) -> WasmValue {
63        let binary: [u32; 2] = [binary[0], binary[1]];
64        WasmValue::I64(unsafe { std::mem::transmute::<[u32; 2], i64>(binary) })
65    }
66
67    pub fn decode_to_f64(binary: &[u32]) -> WasmValue {
68        let binary: [u32; 2] = [binary[0], binary[1]];
69        WasmValue::F64(unsafe { std::mem::transmute::<[u32; 2], f64>(binary) })
70    }
71
72    pub fn decode_to_v128(binary: &[u32]) -> WasmValue {
73        let binary: [u32; 4] = [binary[0], binary[1], binary[2], binary[3]];
74        WasmValue::V128(unsafe { std::mem::transmute::<[u32; 4], i128>(binary) })
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn test_encode() {
84        let params = vec![WasmValue::I32(1), WasmValue::I64(2)];
85
86        let mut ret: Vec<u32> = Vec::new();
87        for p in params {
88            ret.append(&mut p.encode());
89        }
90
91        assert_eq!(ret.len(), 3);
92        assert_eq!(ret, vec![1, 2, 0]);
93    }
94
95    #[test]
96    fn test_encode_decode() {
97        let values = vec![
98            WasmValue::I32(1),
99            WasmValue::I64(2),
100            WasmValue::F32(3.0),
101            WasmValue::F64(4.0),
102            WasmValue::V128(5),
103        ];
104
105        let mut binary: Vec<u32> = Vec::new();
106        for v in &values {
107            binary.append(&mut v.encode());
108        }
109
110        let decoded_values: Vec<WasmValue> = vec![
111            WasmValue::decode_to_i32(&binary[0..1]),
112            WasmValue::decode_to_i64(&binary[1..3]),
113            WasmValue::decode_to_f32(&binary[3..4]),
114            WasmValue::decode_to_f64(&binary[4..6]),
115            WasmValue::decode_to_v128(&binary[6..10]),
116        ];
117
118        assert_eq!(values, decoded_values);
119    }
120}