mycelium_kernel/wasm/
convert.rs

1use core::fmt;
2
3#[derive(Debug, Copy, Clone)]
4pub struct ConvertError;
5impl fmt::Display for ConvertError {
6    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7        write!(f, "conversion error")
8    }
9}
10impl From<ConvertError> for wasmi::Trap {
11    fn from(_: ConvertError) -> wasmi::Trap {
12        wasmi::TrapKind::UnexpectedSignature.into()
13    }
14}
15
16/// Trait describing a type which can be used in wasm method signatures.
17// XXX: Should this require `wasmi::FromRuntimeValue` and
18// `Into<wasmi::RuntimeValue>`?
19pub trait WasmPrimitive: Sized {
20    const TYPE: wasmi::ValueType;
21
22    fn from_wasm_value(value: wasmi::RuntimeValue) -> Result<Self, ConvertError>;
23    fn into_wasm_value(self) -> wasmi::RuntimeValue;
24}
25
26macro_rules! impl_wasm_primitive {
27    ($($rust:ty = $wasm:ident;)*) => {
28        $(
29            impl WasmPrimitive for $rust {
30                const TYPE: wasmi::ValueType = wasmi::ValueType::$wasm;
31
32                fn from_wasm_value(value: wasmi::RuntimeValue) -> Result<Self, ConvertError> {
33                    value.try_into().ok_or(ConvertError)
34                }
35
36                fn into_wasm_value(self) -> wasmi::RuntimeValue {
37                    self.into()
38                }
39            }
40        )*
41    }
42}
43
44impl_wasm_primitive! {
45    i8 = I32;
46    i16 = I32;
47    i32 = I32;
48    i64 = I64;
49    u8 = I32;
50    u16 = I32;
51    u32 = I32;
52    u64 = I64;
53    wasmi::nan_preserving_float::F32 = F32;
54    wasmi::nan_preserving_float::F64 = F64;
55}