1use crate::{
2 core::{TypedVal, UntypedVal},
3 ExternRef,
4 Func,
5 Ref,
6 ValType,
7 F32,
8 F64,
9 V128,
10};
11
12pub trait WithType {
14 type Output;
16
17 fn with_type(self, ty: ValType) -> Self::Output;
19}
20
21impl WithType for UntypedVal {
22 type Output = Val;
23
24 fn with_type(self, ty: ValType) -> Self::Output {
25 match ty {
26 ValType::I32 => Val::I32(self.into()),
27 ValType::I64 => Val::I64(self.into()),
28 ValType::F32 => Val::F32(self.into()),
29 ValType::F64 => Val::F64(self.into()),
30 #[cfg(feature = "simd")]
31 ValType::V128 => Val::V128(self.into()),
32 ValType::FuncRef => Val::FuncRef(self.into()),
33 ValType::ExternRef => Val::ExternRef(self.into()),
34 #[cfg(not(feature = "simd"))]
35 unsupported => unimplemented!("encountered unsupported `ValType`: {unsupported:?}"),
36 }
37 }
38}
39
40impl From<Val> for UntypedVal {
41 fn from(value: Val) -> Self {
42 match value {
43 Val::I32(value) => value.into(),
44 Val::I64(value) => value.into(),
45 Val::F32(value) => value.into(),
46 Val::F64(value) => value.into(),
47 #[cfg(feature = "simd")]
48 Val::V128(value) => value.into(),
49 Val::FuncRef(value) => value.into(),
50 Val::ExternRef(value) => value.into(),
51 #[cfg(not(feature = "simd"))]
52 unsupported => unimplemented!("encountered unsupported `Val`: {unsupported:?}"),
53 }
54 }
55}
56
57#[derive(Clone, Debug)]
65pub enum Val {
66 I32(i32),
68 I64(i64),
70 F32(F32),
72 F64(F64),
74 V128(V128),
76 FuncRef(Ref<Func>),
78 ExternRef(Ref<ExternRef>),
80}
81
82impl Val {
83 #[inline]
85 pub fn default(value_type: ValType) -> Self {
86 match value_type {
87 ValType::I32 => Self::I32(0),
88 ValType::I64 => Self::I64(0),
89 ValType::F32 => Self::F32(0f32.into()),
90 ValType::F64 => Self::F64(0f64.into()),
91 ValType::V128 => Self::V128(V128::from(0_u128)),
92 ValType::FuncRef => Self::from(<Ref<Func>>::Null),
93 ValType::ExternRef => Self::from(<Ref<ExternRef>>::Null),
94 }
95 }
96
97 #[inline]
99 pub fn ty(&self) -> ValType {
100 match *self {
101 Self::I32(_) => ValType::I32,
102 Self::I64(_) => ValType::I64,
103 Self::F32(_) => ValType::F32,
104 Self::F64(_) => ValType::F64,
105 Self::V128(_) => ValType::V128,
106 Self::FuncRef(_) => ValType::FuncRef,
107 Self::ExternRef(_) => ValType::ExternRef,
108 }
109 }
110
111 pub fn i32(&self) -> Option<i32> {
113 match self {
114 Self::I32(value) => Some(*value),
115 _ => None,
116 }
117 }
118
119 pub fn i64(&self) -> Option<i64> {
121 match self {
122 Self::I64(value) => Some(*value),
123 _ => None,
124 }
125 }
126
127 pub fn f32(&self) -> Option<F32> {
129 match self {
130 Self::F32(value) => Some(*value),
131 _ => None,
132 }
133 }
134
135 pub fn f64(&self) -> Option<F64> {
137 match self {
138 Self::F64(value) => Some(*value),
139 _ => None,
140 }
141 }
142
143 pub fn funcref(&self) -> Option<Ref<&Func>> {
145 match self {
146 Self::FuncRef(value) => Some(value.as_ref()),
147 _ => None,
148 }
149 }
150
151 pub fn externref(&self) -> Option<Ref<&ExternRef>> {
153 match self {
154 Self::ExternRef(value) => Some(value.as_ref()),
155 _ => None,
156 }
157 }
158}
159
160impl From<i32> for Val {
161 #[inline]
162 fn from(val: i32) -> Self {
163 Self::I32(val)
164 }
165}
166
167impl From<i64> for Val {
168 #[inline]
169 fn from(val: i64) -> Self {
170 Self::I64(val)
171 }
172}
173
174impl From<F32> for Val {
175 #[inline]
176 fn from(val: F32) -> Self {
177 Self::F32(val)
178 }
179}
180
181impl From<F64> for Val {
182 #[inline]
183 fn from(val: F64) -> Self {
184 Self::F64(val)
185 }
186}
187
188impl From<Func> for Val {
189 #[inline]
190 fn from(func: Func) -> Self {
191 Self::FuncRef(Ref::Val(func))
192 }
193}
194
195impl From<ExternRef> for Val {
196 #[inline]
197 fn from(externref: ExternRef) -> Self {
198 Self::ExternRef(Ref::Val(externref))
199 }
200}
201
202impl From<Ref<Func>> for Val {
203 #[inline]
204 fn from(funcref: Ref<Func>) -> Self {
205 Self::FuncRef(funcref)
206 }
207}
208
209impl From<Ref<ExternRef>> for Val {
210 #[inline]
211 fn from(externref: Ref<ExternRef>) -> Self {
212 Self::ExternRef(externref)
213 }
214}
215
216impl From<V128> for Val {
217 #[inline]
218 fn from(value: V128) -> Self {
219 Self::V128(value)
220 }
221}
222
223impl From<TypedVal> for Val {
224 fn from(value: TypedVal) -> Self {
225 let untyped = value.untyped();
226 match value.ty() {
227 ValType::I32 => Self::I32(untyped.into()),
228 ValType::I64 => Self::I64(untyped.into()),
229 ValType::F32 => Self::F32(untyped.into()),
230 ValType::F64 => Self::F64(untyped.into()),
231 ValType::V128 => {
232 #[cfg(feature = "simd")]
233 {
234 Self::V128(untyped.into())
235 }
236 #[cfg(not(feature = "simd"))]
237 {
238 panic!("`simd` crate feature is disabled")
239 }
240 }
241 ValType::FuncRef => Self::FuncRef(untyped.into()),
242 ValType::ExternRef => Self::ExternRef(untyped.into()),
243 }
244 }
245}
246
247impl From<Val> for TypedVal {
248 fn from(value: Val) -> Self {
249 Self::new(value.ty(), value.into())
250 }
251}