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
use super::super::value::wasm_valkind_t;
use std::convert::TryInto;
use wasmer_api::Type;

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum wasm_valkind_enum {
    WASM_I32 = 0,
    WASM_I64 = 1,
    WASM_F32 = 2,
    WASM_F64 = 3,
    WASM_ANYREF = 128,
    WASM_FUNCREF = 129,
}

impl From<Type> for wasm_valkind_enum {
    fn from(other: Type) -> Self {
        match other {
            Type::I32 => Self::WASM_I32,
            Type::I64 => Self::WASM_I64,
            Type::F32 => Self::WASM_F32,
            Type::F64 => Self::WASM_F64,
            Type::V128 => todo!("no v128 type in Wasm C API yet!"),
            Type::ExternRef => Self::WASM_ANYREF,
            Type::FuncRef => Self::WASM_FUNCREF,
        }
    }
}

impl From<wasm_valkind_enum> for Type {
    fn from(other: wasm_valkind_enum) -> Self {
        use wasm_valkind_enum::*;
        match other {
            WASM_I32 => Type::I32,
            WASM_I64 => Type::I64,
            WASM_F32 => Type::F32,
            WASM_F64 => Type::F64,
            WASM_ANYREF => Type::ExternRef,
            WASM_FUNCREF => Type::FuncRef,
        }
    }
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
pub struct wasm_valtype_t {
    valkind: wasm_valkind_enum,
}

impl Default for wasm_valtype_t {
    fn default() -> Self {
        Self {
            valkind: wasm_valkind_enum::WASM_I32,
        }
    }
}

wasm_declare_boxed_vec!(valtype);

impl From<wasm_valtype_t> for Type {
    fn from(other: wasm_valtype_t) -> Self {
        (&other).into()
    }
}

impl From<&wasm_valtype_t> for Type {
    fn from(other: &wasm_valtype_t) -> Self {
        other.valkind.into()
    }
}

impl From<Type> for wasm_valtype_t {
    fn from(other: Type) -> Self {
        Self {
            valkind: other.into(),
        }
    }
}

#[no_mangle]
pub extern "C" fn wasm_valtype_new(kind: wasm_valkind_t) -> Option<Box<wasm_valtype_t>> {
    let kind_enum = kind.try_into().ok()?;
    let valtype = wasm_valtype_t { valkind: kind_enum };

    Some(Box::new(valtype))
}

#[no_mangle]
pub unsafe extern "C" fn wasm_valtype_delete(_valtype: Option<Box<wasm_valtype_t>>) {}

#[no_mangle]
pub unsafe extern "C" fn wasm_valtype_kind(valtype: Option<&wasm_valtype_t>) -> wasm_valkind_t {
    valtype
        .expect("`wasm_valtype_kind: argument is a null pointer")
        .valkind as wasm_valkind_t
}