1 use crate::prelude::*;
2 use std::borrow::Cow;
3 
4 use super::{canonicalize_nan32, canonicalize_nan64, unwrap_val};
5 use wasm_wave::wasm::{WasmFunc, WasmType, WasmTypeKind, WasmValue, WasmValueError};
6 
7 impl WasmType for crate::ValType {
kind(&self) -> WasmTypeKind8     fn kind(&self) -> WasmTypeKind {
9         match self {
10             Self::I32 => WasmTypeKind::S32,
11             Self::I64 => WasmTypeKind::S64,
12             Self::F32 => WasmTypeKind::F32,
13             Self::F64 => WasmTypeKind::F64,
14             Self::V128 => WasmTypeKind::Tuple,
15 
16             Self::Ref(_) => WasmTypeKind::Unsupported,
17         }
18     }
19 
tuple_element_types(&self) -> Box<dyn Iterator<Item = Self> + '_>20     fn tuple_element_types(&self) -> Box<dyn Iterator<Item = Self> + '_> {
21         match *self {
22             Self::V128 => {}
23             _ => panic!("tuple_element_types called on non-tuple type"),
24         }
25         Box::new([Self::I64, Self::I64].into_iter())
26     }
27 }
28 
29 impl WasmValue for crate::Val {
30     type Type = crate::ValType;
31 
kind(&self) -> WasmTypeKind32     fn kind(&self) -> WasmTypeKind {
33         match self {
34             Self::I32(_) => WasmTypeKind::S32,
35             Self::I64(_) => WasmTypeKind::S64,
36             Self::F32(_) => WasmTypeKind::F32,
37             Self::F64(_) => WasmTypeKind::F64,
38             Self::V128(_) => WasmTypeKind::Tuple,
39             Self::FuncRef(_) => WasmTypeKind::Unsupported,
40             Self::ExternRef(_) => WasmTypeKind::Unsupported,
41             Self::AnyRef(_) => WasmTypeKind::Unsupported,
42             Self::ExnRef(_) => WasmTypeKind::Unsupported,
43             Self::ContRef(_) => WasmTypeKind::Unsupported,
44         }
45     }
46 
make_s32(val: i32) -> Self47     fn make_s32(val: i32) -> Self {
48         Self::I32(val)
49     }
make_s64(val: i64) -> Self50     fn make_s64(val: i64) -> Self {
51         Self::I64(val)
52     }
make_f32(val: f32) -> Self53     fn make_f32(val: f32) -> Self {
54         let val = canonicalize_nan32(val);
55         Self::F32(val.to_bits())
56     }
make_f64(val: f64) -> Self57     fn make_f64(val: f64) -> Self {
58         let val = canonicalize_nan64(val);
59         Self::F64(val.to_bits())
60     }
make_tuple( ty: &Self::Type, vals: impl IntoIterator<Item = Self>, ) -> Result<Self, WasmValueError>61     fn make_tuple(
62         ty: &Self::Type,
63         vals: impl IntoIterator<Item = Self>,
64     ) -> Result<Self, WasmValueError> {
65         match *ty {
66             Self::Type::V128 => {}
67             _ => {
68                 return Err(WasmValueError::Other(
69                     "tuples only used for v128 (v64x2)".to_string(),
70                 ));
71             }
72         }
73         let mut iter = vals.into_iter();
74         let Some(l_val) = iter.next() else {
75             return Err(WasmValueError::Other("expected 2 values".to_string()));
76         };
77         let Some(h_val) = iter.next() else {
78             return Err(WasmValueError::Other("expected 2 values".to_string()));
79         };
80         if iter.next().is_some() {
81             return Err(WasmValueError::Other("expected 2 values".to_string()));
82         }
83 
84         let (Some(l), Some(h)) = (l_val.i64(), h_val.i64()) else {
85             return Err(WasmValueError::Other("expected 2 i64s (v64x2)".to_string()));
86         };
87         Ok(Self::V128(((h as u128) << 64 | (l as u128)).into()))
88     }
89 
unwrap_s32(&self) -> i3290     fn unwrap_s32(&self) -> i32 {
91         *unwrap_val!(self, Self::I32, "s32")
92     }
93 
unwrap_s64(&self) -> i6494     fn unwrap_s64(&self) -> i64 {
95         *unwrap_val!(self, Self::I64, "s64")
96     }
97 
unwrap_f32(&self) -> f3298     fn unwrap_f32(&self) -> f32 {
99         let val = f32::from_bits(*unwrap_val!(self, Self::F32, "f32"));
100         canonicalize_nan32(val)
101     }
102 
unwrap_f64(&self) -> f64103     fn unwrap_f64(&self) -> f64 {
104         let val = f64::from_bits(*unwrap_val!(self, Self::F64, "f64"));
105         canonicalize_nan64(val)
106     }
107     #[expect(clippy::cast_possible_truncation, reason = "handled losslessly here")]
unwrap_tuple(&self) -> Box<dyn Iterator<Item = Cow<'_, Self>> + '_>108     fn unwrap_tuple(&self) -> Box<dyn Iterator<Item = Cow<'_, Self>> + '_> {
109         let v = unwrap_val!(self, Self::V128, "tuple").as_u128();
110         let low = v as i64;
111         let high = (v >> 64) as i64;
112         Box::new(
113             [Self::I64(low), Self::I64(high)]
114                 .into_iter()
115                 .map(Cow::Owned),
116         )
117     }
118 }
119 
120 impl WasmFunc for crate::FuncType {
121     type Type = crate::ValType;
122 
params(&self) -> Box<dyn Iterator<Item = Self::Type> + '_>123     fn params(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
124         Box::new(self.params())
125     }
126 
results(&self) -> Box<dyn Iterator<Item = Self::Type> + '_>127     fn results(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
128         Box::new(self.results())
129     }
130 }
131 
132 #[cfg(test)]
133 mod tests {
134     #[test]
core_vals_smoke_test()135     fn core_vals_smoke_test() {
136         use crate::Val;
137         for (val, want) in [
138             (Val::I32(10), "10"),
139             (Val::I64(-10), "-10"),
140             (1.5f32.into(), "1.5"),
141             (f32::NAN.into(), "nan"),
142             (f32::INFINITY.into(), "inf"),
143             (f32::NEG_INFINITY.into(), "-inf"),
144             ((-1.5f64).into(), "-1.5"),
145             (f32::NAN.into(), "nan"),
146             (f32::INFINITY.into(), "inf"),
147             (f32::NEG_INFINITY.into(), "-inf"),
148             (
149                 Val::V128(0x1234567890abcdef1122334455667788.into()),
150                 "(1234605616436508552, 1311768467294899695)",
151             ),
152         ] {
153             let got = wasm_wave::to_string(&val)
154                 .unwrap_or_else(|err| panic!("failed to serialize {val:?}: {err}"));
155             assert_eq!(got, want, "for {val:?}");
156         }
157     }
158 }
159