1 use crate::ValRaw;
2 use crate::component::ResourceAny;
3 use crate::component::concurrent::{self, ErrorContext, FutureAny, StreamAny};
4 use crate::component::func::{Lift, LiftContext, Lower, LowerContext, desc};
5 use crate::prelude::*;
6 use core::mem::MaybeUninit;
7 use core::slice::{Iter, IterMut};
8 use wasmtime_component_util::{DiscriminantSize, FlagsSize};
9 use wasmtime_environ::component::{
10     CanonicalAbiInfo, InterfaceType, TypeEnum, TypeFlags, TypeListIndex, TypeOption, TypeResult,
11     TypeVariant, VariantInfo,
12 };
13 
14 /// Represents possible runtime values which a component function can either
15 /// consume or produce
16 ///
17 /// This is a dynamic representation of possible values in the component model.
18 /// Note that this is not an efficient representation but is instead intended to
19 /// be a flexible and somewhat convenient representation. The most efficient
20 /// representation of component model types is to use the `bindgen!` macro to
21 /// generate native Rust types with specialized liftings and lowerings.
22 ///
23 /// This type is used in conjunction with [`Func::call`] for example if the
24 /// signature of a component is not statically known ahead of time.
25 ///
26 /// # Equality and `Val`
27 ///
28 /// This type implements both the Rust `PartialEq` and `Eq` traits. This type
29 /// additionally contains values which are not necessarily easily equated,
30 /// however, such as floats (`Float32` and `Float64`) and resources. Equality
31 /// does require that two values have the same type, and then these cases are
32 /// handled as:
33 ///
34 /// * Floats are tested if they are "semantically the same" meaning all NaN
35 ///   values are equal to all other NaN values. Additionally zero values must be
36 ///   exactly the same, so positive zero is not equal to negative zero. The
37 ///   primary use case at this time is fuzzing-related equality which this is
38 ///   sufficient for.
39 ///
40 /// * Resources are tested if their types and indices into the host table are
41 ///   equal. This does not compare the underlying representation so borrows of
42 ///   the same guest resource are not considered equal. This additionally
43 ///   doesn't go further and test for equality in the guest itself (for example
44 ///   two different heap allocations of `Box<u32>` can be equal in normal Rust
45 ///   if they contain the same value, but will never be considered equal when
46 ///   compared as `Val::Resource`s).
47 ///
48 /// In general if a strict guarantee about equality is required here it's
49 /// recommended to "build your own" as this equality intended for fuzzing
50 /// Wasmtime may not be suitable for you.
51 ///
52 /// # Component model types and `Val`
53 ///
54 /// The `Val` type here does not contain enough information to say what the
55 /// component model type of a `Val` is. This is instead more of an AST of sorts.
56 /// For example the `Val::Enum` only carries information about a single
57 /// discriminant, not the entire enumeration or what it's a discriminant of.
58 ///
59 /// This means that when a `Val` is passed to Wasmtime, for example as a
60 /// function parameter when calling a function or as a return value from an
61 /// host-defined imported function, then it must pass a type-check. Instances of
62 /// `Val` are type-checked against what's required by the component itself.
63 ///
64 /// [`Func::call`]: crate::component::Func::call
65 #[derive(Debug, Clone)]
66 #[expect(missing_docs, reason = "self-describing variants")]
67 pub enum Val {
68     Bool(bool),
69     S8(i8),
70     U8(u8),
71     S16(i16),
72     U16(u16),
73     S32(i32),
74     U32(u32),
75     S64(i64),
76     U64(u64),
77     Float32(f32),
78     Float64(f64),
79     Char(char),
80     String(String),
81     List(Vec<Val>),
82     Record(Vec<(String, Val)>),
83     Tuple(Vec<Val>),
84     Variant(String, Option<Box<Val>>),
85     Enum(String),
86     Option(Option<Box<Val>>),
87     Result(Result<Option<Box<Val>>, Option<Box<Val>>>),
88     Flags(Vec<String>),
89     Resource(ResourceAny),
90     Future(FutureAny),
91     Stream(StreamAny),
92     ErrorContext(ErrorContextAny),
93 }
94 
95 impl Val {
96     /// Deserialize a value of this type from core Wasm stack values.
97     pub(crate) fn lift(
98         cx: &mut LiftContext<'_>,
99         ty: InterfaceType,
100         src: &mut Iter<'_, ValRaw>,
101     ) -> Result<Val> {
102         Ok(match ty {
103             InterfaceType::Bool => Val::Bool(bool::linear_lift_from_flat(cx, ty, next(src))?),
104             InterfaceType::S8 => Val::S8(i8::linear_lift_from_flat(cx, ty, next(src))?),
105             InterfaceType::U8 => Val::U8(u8::linear_lift_from_flat(cx, ty, next(src))?),
106             InterfaceType::S16 => Val::S16(i16::linear_lift_from_flat(cx, ty, next(src))?),
107             InterfaceType::U16 => Val::U16(u16::linear_lift_from_flat(cx, ty, next(src))?),
108             InterfaceType::S32 => Val::S32(i32::linear_lift_from_flat(cx, ty, next(src))?),
109             InterfaceType::U32 => Val::U32(u32::linear_lift_from_flat(cx, ty, next(src))?),
110             InterfaceType::S64 => Val::S64(i64::linear_lift_from_flat(cx, ty, next(src))?),
111             InterfaceType::U64 => Val::U64(u64::linear_lift_from_flat(cx, ty, next(src))?),
112             InterfaceType::Float32 => Val::Float32(f32::linear_lift_from_flat(cx, ty, next(src))?),
113             InterfaceType::Float64 => Val::Float64(f64::linear_lift_from_flat(cx, ty, next(src))?),
114             InterfaceType::Char => Val::Char(char::linear_lift_from_flat(cx, ty, next(src))?),
115             InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
116                 Val::Resource(ResourceAny::linear_lift_from_flat(cx, ty, next(src))?)
117             }
118             InterfaceType::String => Val::String(<_>::linear_lift_from_flat(
119                 cx,
120                 ty,
121                 &[*next(src), *next(src)],
122             )?),
123             InterfaceType::List(i) => {
124                 // FIXME(#4311): needs memory64 treatment
125                 let ptr = u32::linear_lift_from_flat(cx, InterfaceType::U32, next(src))? as usize;
126                 let len = u32::linear_lift_from_flat(cx, InterfaceType::U32, next(src))? as usize;
127                 load_list(cx, i, ptr, len)?
128             }
129             InterfaceType::Record(i) => Val::Record(
130                 cx.types[i]
131                     .fields
132                     .iter()
133                     .map(|field| {
134                         let val = Self::lift(cx, field.ty, src)?;
135                         Ok((field.name.to_string(), val))
136                     })
137                     .collect::<Result<_>>()?,
138             ),
139             InterfaceType::Tuple(i) => Val::Tuple(
140                 cx.types[i]
141                     .types
142                     .iter()
143                     .map(|ty| Self::lift(cx, *ty, src))
144                     .collect::<Result<_>>()?,
145             ),
146             InterfaceType::Variant(i) => {
147                 let vty = &cx.types[i];
148                 let (discriminant, value) = lift_variant(
149                     cx,
150                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
151                     vty.cases.values().copied(),
152                     src,
153                 )?;
154 
155                 let (k, _) = vty.cases.get_index(discriminant as usize).unwrap();
156                 Val::Variant(k.clone(), value)
157             }
158             InterfaceType::Enum(i) => {
159                 let ety = &cx.types[i];
160                 let (discriminant, _) = lift_variant(
161                     cx,
162                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
163                     ety.names.iter().map(|_| None),
164                     src,
165                 )?;
166 
167                 Val::Enum(ety.names[discriminant as usize].clone())
168             }
169             InterfaceType::Option(i) => {
170                 let (_discriminant, value) = lift_variant(
171                     cx,
172                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
173                     [None, Some(cx.types[i].ty)].into_iter(),
174                     src,
175                 )?;
176 
177                 Val::Option(value)
178             }
179             InterfaceType::Result(i) => {
180                 let result_ty = &cx.types[i];
181                 let (discriminant, value) = lift_variant(
182                     cx,
183                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
184                     [result_ty.ok, result_ty.err].into_iter(),
185                     src,
186                 )?;
187 
188                 Val::Result(if discriminant == 0 {
189                     Ok(value)
190                 } else {
191                     Err(value)
192                 })
193             }
194             InterfaceType::Flags(i) => {
195                 let u32_count = cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap();
196                 let ty = &cx.types[i];
197                 let mut flags = Vec::new();
198                 for i in 0..u32::try_from(u32_count).unwrap() {
199                     push_flags(
200                         ty,
201                         &mut flags,
202                         i * 32,
203                         u32::linear_lift_from_flat(cx, InterfaceType::U32, next(src))?,
204                     );
205                 }
206 
207                 Val::Flags(flags)
208             }
209             InterfaceType::Future(_) => {
210                 Val::Future(FutureAny::linear_lift_from_flat(cx, ty, next(src))?)
211             }
212             InterfaceType::Stream(_) => {
213                 Val::Stream(StreamAny::linear_lift_from_flat(cx, ty, next(src))?)
214             }
215             InterfaceType::ErrorContext(_) => {
216                 ErrorContext::linear_lift_from_flat(cx, ty, next(src))?.into_val()
217             }
218             InterfaceType::FixedLengthList(_) => todo!(), // FIXME(#12279)
219         })
220     }
221 
222     /// Deserialize a value of this type from the heap.
223     pub(crate) fn load(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Val> {
224         Ok(match ty {
225             InterfaceType::Bool => Val::Bool(bool::linear_lift_from_memory(cx, ty, bytes)?),
226             InterfaceType::S8 => Val::S8(i8::linear_lift_from_memory(cx, ty, bytes)?),
227             InterfaceType::U8 => Val::U8(u8::linear_lift_from_memory(cx, ty, bytes)?),
228             InterfaceType::S16 => Val::S16(i16::linear_lift_from_memory(cx, ty, bytes)?),
229             InterfaceType::U16 => Val::U16(u16::linear_lift_from_memory(cx, ty, bytes)?),
230             InterfaceType::S32 => Val::S32(i32::linear_lift_from_memory(cx, ty, bytes)?),
231             InterfaceType::U32 => Val::U32(u32::linear_lift_from_memory(cx, ty, bytes)?),
232             InterfaceType::S64 => Val::S64(i64::linear_lift_from_memory(cx, ty, bytes)?),
233             InterfaceType::U64 => Val::U64(u64::linear_lift_from_memory(cx, ty, bytes)?),
234             InterfaceType::Float32 => Val::Float32(f32::linear_lift_from_memory(cx, ty, bytes)?),
235             InterfaceType::Float64 => Val::Float64(f64::linear_lift_from_memory(cx, ty, bytes)?),
236             InterfaceType::Char => Val::Char(char::linear_lift_from_memory(cx, ty, bytes)?),
237             InterfaceType::String => Val::String(<_>::linear_lift_from_memory(cx, ty, bytes)?),
238             InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
239                 Val::Resource(ResourceAny::linear_lift_from_memory(cx, ty, bytes)?)
240             }
241             InterfaceType::List(i) => {
242                 // FIXME(#4311): needs memory64 treatment
243                 let ptr = u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize;
244                 let len = u32::from_le_bytes(bytes[4..].try_into().unwrap()) as usize;
245                 load_list(cx, i, ptr, len)?
246             }
247 
248             InterfaceType::Record(i) => {
249                 let mut offset = 0;
250                 let fields = cx.types[i].fields.iter();
251                 Val::Record(
252                     fields
253                         .map(|field| -> Result<(String, Val)> {
254                             let abi = cx.types.canonical_abi(&field.ty);
255                             let offset = abi.next_field32(&mut offset);
256                             let offset = usize::try_from(offset).unwrap();
257                             let size = usize::try_from(abi.size32).unwrap();
258                             Ok((
259                                 field.name.to_string(),
260                                 Val::load(cx, field.ty, &bytes[offset..][..size])?,
261                             ))
262                         })
263                         .collect::<Result<_>>()?,
264                 )
265             }
266             InterfaceType::Tuple(i) => {
267                 let types = cx.types[i].types.iter().copied();
268                 let mut offset = 0;
269                 Val::Tuple(
270                     types
271                         .map(|ty| {
272                             let abi = cx.types.canonical_abi(&ty);
273                             let offset = abi.next_field32(&mut offset);
274                             let offset = usize::try_from(offset).unwrap();
275                             let size = usize::try_from(abi.size32).unwrap();
276                             Val::load(cx, ty, &bytes[offset..][..size])
277                         })
278                         .collect::<Result<_>>()?,
279                 )
280             }
281             InterfaceType::Variant(i) => {
282                 let ty = &cx.types[i];
283                 let (discriminant, value) =
284                     load_variant(cx, &ty.info, ty.cases.values().copied(), bytes)?;
285 
286                 let (k, _) = ty.cases.get_index(discriminant as usize).unwrap();
287                 Val::Variant(k.clone(), value)
288             }
289             InterfaceType::Enum(i) => {
290                 let ty = &cx.types[i];
291                 let (discriminant, _) =
292                     load_variant(cx, &ty.info, ty.names.iter().map(|_| None), bytes)?;
293 
294                 Val::Enum(ty.names[discriminant as usize].clone())
295             }
296             InterfaceType::Option(i) => {
297                 let ty = &cx.types[i];
298                 let (_discriminant, value) =
299                     load_variant(cx, &ty.info, [None, Some(ty.ty)].into_iter(), bytes)?;
300 
301                 Val::Option(value)
302             }
303             InterfaceType::Result(i) => {
304                 let ty = &cx.types[i];
305                 let (discriminant, value) =
306                     load_variant(cx, &ty.info, [ty.ok, ty.err].into_iter(), bytes)?;
307 
308                 Val::Result(if discriminant == 0 {
309                     Ok(value)
310                 } else {
311                     Err(value)
312                 })
313             }
314             InterfaceType::Flags(i) => {
315                 let ty = &cx.types[i];
316                 let mut flags = Vec::new();
317                 match FlagsSize::from_count(ty.names.len()) {
318                     FlagsSize::Size0 => {}
319                     FlagsSize::Size1 => {
320                         let bits = u8::linear_lift_from_memory(cx, InterfaceType::U8, bytes)?;
321                         push_flags(ty, &mut flags, 0, u32::from(bits));
322                     }
323                     FlagsSize::Size2 => {
324                         let bits = u16::linear_lift_from_memory(cx, InterfaceType::U16, bytes)?;
325                         push_flags(ty, &mut flags, 0, u32::from(bits));
326                     }
327                     FlagsSize::Size4Plus(n) => {
328                         for i in 0..n {
329                             let bits = u32::linear_lift_from_memory(
330                                 cx,
331                                 InterfaceType::U32,
332                                 &bytes[usize::from(i) * 4..][..4],
333                             )?;
334                             push_flags(ty, &mut flags, u32::from(i) * 32, bits);
335                         }
336                     }
337                 }
338                 Val::Flags(flags)
339             }
340             InterfaceType::Future(_) => FutureAny::linear_lift_from_memory(cx, ty, bytes)?.into(),
341             InterfaceType::Stream(_) => StreamAny::linear_lift_from_memory(cx, ty, bytes)?.into(),
342             InterfaceType::ErrorContext(_) => {
343                 ErrorContext::linear_lift_from_memory(cx, ty, bytes)?.into_val()
344             }
345             InterfaceType::FixedLengthList(_) => todo!(), // FIXME(#12279)
346         })
347     }
348 
349     /// Serialize this value as core Wasm stack values.
350     pub(crate) fn lower<T>(
351         &self,
352         cx: &mut LowerContext<'_, T>,
353         ty: InterfaceType,
354         dst: &mut IterMut<'_, MaybeUninit<ValRaw>>,
355     ) -> Result<()> {
356         match (ty, self) {
357             (InterfaceType::Bool, Val::Bool(value)) => {
358                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
359             }
360             (InterfaceType::Bool, _) => unexpected(ty, self),
361             (InterfaceType::S8, Val::S8(value)) => {
362                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
363             }
364             (InterfaceType::S8, _) => unexpected(ty, self),
365             (InterfaceType::U8, Val::U8(value)) => {
366                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
367             }
368             (InterfaceType::U8, _) => unexpected(ty, self),
369             (InterfaceType::S16, Val::S16(value)) => {
370                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
371             }
372             (InterfaceType::S16, _) => unexpected(ty, self),
373             (InterfaceType::U16, Val::U16(value)) => {
374                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
375             }
376             (InterfaceType::U16, _) => unexpected(ty, self),
377             (InterfaceType::S32, Val::S32(value)) => {
378                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
379             }
380             (InterfaceType::S32, _) => unexpected(ty, self),
381             (InterfaceType::U32, Val::U32(value)) => {
382                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
383             }
384             (InterfaceType::U32, _) => unexpected(ty, self),
385             (InterfaceType::S64, Val::S64(value)) => {
386                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
387             }
388             (InterfaceType::S64, _) => unexpected(ty, self),
389             (InterfaceType::U64, Val::U64(value)) => {
390                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
391             }
392             (InterfaceType::U64, _) => unexpected(ty, self),
393             (InterfaceType::Float32, Val::Float32(value)) => {
394                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
395             }
396             (InterfaceType::Float32, _) => unexpected(ty, self),
397             (InterfaceType::Float64, Val::Float64(value)) => {
398                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
399             }
400             (InterfaceType::Float64, _) => unexpected(ty, self),
401             (InterfaceType::Char, Val::Char(value)) => {
402                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
403             }
404             (InterfaceType::Char, _) => unexpected(ty, self),
405             // NB: `lower` on `ResourceAny` does its own type-checking, so skip
406             // looking at it here.
407             (InterfaceType::Borrow(_) | InterfaceType::Own(_), Val::Resource(value)) => {
408                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
409             }
410             (InterfaceType::Borrow(_) | InterfaceType::Own(_), _) => unexpected(ty, self),
411             (InterfaceType::String, Val::String(value)) => {
412                 let my_dst = &mut MaybeUninit::<[ValRaw; 2]>::uninit();
413                 value.linear_lower_to_flat(cx, ty, my_dst)?;
414                 let my_dst = unsafe { my_dst.assume_init() };
415                 next_mut(dst).write(my_dst[0]);
416                 next_mut(dst).write(my_dst[1]);
417                 Ok(())
418             }
419             (InterfaceType::String, _) => unexpected(ty, self),
420             (InterfaceType::List(ty), Val::List(values)) => {
421                 let ty = &cx.types[ty];
422                 let (ptr, len) = lower_list(cx, ty.element, values)?;
423                 next_mut(dst).write(ValRaw::i64(ptr as i64));
424                 next_mut(dst).write(ValRaw::i64(len as i64));
425                 Ok(())
426             }
427             (InterfaceType::List(_), _) => unexpected(ty, self),
428             (InterfaceType::Record(ty), Val::Record(values)) => {
429                 let ty = &cx.types[ty];
430                 if ty.fields.len() != values.len() {
431                     bail!("expected {} fields, got {}", ty.fields.len(), values.len());
432                 }
433                 for ((name, value), field) in values.iter().zip(ty.fields.iter()) {
434                     if *name != field.name {
435                         bail!("expected field `{}`, got `{name}`", field.name);
436                     }
437                     value.lower(cx, field.ty, dst)?;
438                 }
439                 Ok(())
440             }
441             (InterfaceType::Record(_), _) => unexpected(ty, self),
442             (InterfaceType::Tuple(ty), Val::Tuple(values)) => {
443                 let ty = &cx.types[ty];
444                 if ty.types.len() != values.len() {
445                     bail!("expected {} types, got {}", ty.types.len(), values.len());
446                 }
447                 for (value, ty) in values.iter().zip(ty.types.iter()) {
448                     value.lower(cx, *ty, dst)?;
449                 }
450                 Ok(())
451             }
452             (InterfaceType::Tuple(_), _) => unexpected(ty, self),
453             (InterfaceType::Variant(ty), Val::Variant(n, v)) => {
454                 GenericVariant::variant(&cx.types[ty], n, v)?.lower(cx, dst)
455             }
456             (InterfaceType::Variant(_), _) => unexpected(ty, self),
457             (InterfaceType::Option(ty), Val::Option(v)) => {
458                 GenericVariant::option(&cx.types[ty], v).lower(cx, dst)
459             }
460             (InterfaceType::Option(_), _) => unexpected(ty, self),
461             (InterfaceType::Result(ty), Val::Result(v)) => {
462                 GenericVariant::result(&cx.types[ty], v)?.lower(cx, dst)
463             }
464             (InterfaceType::Result(_), _) => unexpected(ty, self),
465             (InterfaceType::Enum(ty), Val::Enum(discriminant)) => {
466                 let discriminant = get_enum_discriminant(&cx.types[ty], discriminant)?;
467                 next_mut(dst).write(ValRaw::u32(discriminant));
468                 Ok(())
469             }
470             (InterfaceType::Enum(_), _) => unexpected(ty, self),
471             (InterfaceType::Flags(ty), Val::Flags(value)) => {
472                 let ty = &cx.types[ty];
473                 let storage = flags_to_storage(ty, value)?;
474                 for value in storage {
475                     next_mut(dst).write(ValRaw::u32(value));
476                 }
477                 Ok(())
478             }
479             (InterfaceType::Flags(_), _) => unexpected(ty, self),
480             (InterfaceType::Future(_), Val::Future(f)) => {
481                 f.linear_lower_to_flat(cx, ty, next_mut(dst))
482             }
483             (InterfaceType::Future(_), _) => unexpected(ty, self),
484             (InterfaceType::Stream(_), Val::Stream(s)) => {
485                 s.linear_lower_to_flat(cx, ty, next_mut(dst))
486             }
487             (InterfaceType::Stream(_), _) => unexpected(ty, self),
488             (InterfaceType::ErrorContext(_), Val::ErrorContext(ErrorContextAny(rep))) => {
489                 concurrent::lower_error_context_to_index(*rep, cx, ty)?.linear_lower_to_flat(
490                     cx,
491                     InterfaceType::U32,
492                     next_mut(dst),
493                 )
494             }
495             (InterfaceType::ErrorContext(_), _) => unexpected(ty, self),
496             (InterfaceType::FixedLengthList(_), _) => todo!(), // FIXME(#12279)
497         }
498     }
499 
500     /// Serialize this value to the heap at the specified memory location.
501     pub(crate) fn store<T>(
502         &self,
503         cx: &mut LowerContext<'_, T>,
504         ty: InterfaceType,
505         offset: usize,
506     ) -> Result<()> {
507         debug_assert!(offset % usize::try_from(cx.types.canonical_abi(&ty).align32)? == 0);
508 
509         match (ty, self) {
510             (InterfaceType::Bool, Val::Bool(value)) => value.linear_lower_to_memory(cx, ty, offset),
511             (InterfaceType::Bool, _) => unexpected(ty, self),
512             (InterfaceType::U8, Val::U8(value)) => value.linear_lower_to_memory(cx, ty, offset),
513             (InterfaceType::U8, _) => unexpected(ty, self),
514             (InterfaceType::S8, Val::S8(value)) => value.linear_lower_to_memory(cx, ty, offset),
515             (InterfaceType::S8, _) => unexpected(ty, self),
516             (InterfaceType::U16, Val::U16(value)) => value.linear_lower_to_memory(cx, ty, offset),
517             (InterfaceType::U16, _) => unexpected(ty, self),
518             (InterfaceType::S16, Val::S16(value)) => value.linear_lower_to_memory(cx, ty, offset),
519             (InterfaceType::S16, _) => unexpected(ty, self),
520             (InterfaceType::U32, Val::U32(value)) => value.linear_lower_to_memory(cx, ty, offset),
521             (InterfaceType::U32, _) => unexpected(ty, self),
522             (InterfaceType::S32, Val::S32(value)) => value.linear_lower_to_memory(cx, ty, offset),
523             (InterfaceType::S32, _) => unexpected(ty, self),
524             (InterfaceType::U64, Val::U64(value)) => value.linear_lower_to_memory(cx, ty, offset),
525             (InterfaceType::U64, _) => unexpected(ty, self),
526             (InterfaceType::S64, Val::S64(value)) => value.linear_lower_to_memory(cx, ty, offset),
527             (InterfaceType::S64, _) => unexpected(ty, self),
528             (InterfaceType::Float32, Val::Float32(value)) => {
529                 value.linear_lower_to_memory(cx, ty, offset)
530             }
531             (InterfaceType::Float32, _) => unexpected(ty, self),
532             (InterfaceType::Float64, Val::Float64(value)) => {
533                 value.linear_lower_to_memory(cx, ty, offset)
534             }
535             (InterfaceType::Float64, _) => unexpected(ty, self),
536             (InterfaceType::Char, Val::Char(value)) => value.linear_lower_to_memory(cx, ty, offset),
537             (InterfaceType::Char, _) => unexpected(ty, self),
538             (InterfaceType::String, Val::String(value)) => {
539                 value.linear_lower_to_memory(cx, ty, offset)
540             }
541             (InterfaceType::String, _) => unexpected(ty, self),
542 
543             // NB: resources do type-checking when they lower.
544             (InterfaceType::Borrow(_) | InterfaceType::Own(_), Val::Resource(value)) => {
545                 value.linear_lower_to_memory(cx, ty, offset)
546             }
547             (InterfaceType::Borrow(_) | InterfaceType::Own(_), _) => unexpected(ty, self),
548             (InterfaceType::List(ty), Val::List(values)) => {
549                 let ty = &cx.types[ty];
550                 let (ptr, len) = lower_list(cx, ty.element, values)?;
551                 // FIXME(#4311): needs memory64 handling
552                 *cx.get(offset + 0) = u32::try_from(ptr).unwrap().to_le_bytes();
553                 *cx.get(offset + 4) = u32::try_from(len).unwrap().to_le_bytes();
554                 Ok(())
555             }
556             (InterfaceType::List(_), _) => unexpected(ty, self),
557             (InterfaceType::Record(ty), Val::Record(values)) => {
558                 let ty = &cx.types[ty];
559                 if ty.fields.len() != values.len() {
560                     bail!("expected {} fields, got {}", ty.fields.len(), values.len());
561                 }
562                 let mut offset = offset;
563                 for ((name, value), field) in values.iter().zip(ty.fields.iter()) {
564                     if *name != field.name {
565                         bail!("expected field `{}`, got `{name}`", field.name);
566                     }
567                     value.store(
568                         cx,
569                         field.ty,
570                         cx.types
571                             .canonical_abi(&field.ty)
572                             .next_field32_size(&mut offset),
573                     )?;
574                 }
575                 Ok(())
576             }
577             (InterfaceType::Record(_), _) => unexpected(ty, self),
578             (InterfaceType::Tuple(ty), Val::Tuple(values)) => {
579                 let ty = &cx.types[ty];
580                 if ty.types.len() != values.len() {
581                     bail!("expected {} types, got {}", ty.types.len(), values.len());
582                 }
583                 let mut offset = offset;
584                 for (value, ty) in values.iter().zip(ty.types.iter()) {
585                     value.store(
586                         cx,
587                         *ty,
588                         cx.types.canonical_abi(ty).next_field32_size(&mut offset),
589                     )?;
590                 }
591                 Ok(())
592             }
593             (InterfaceType::Tuple(_), _) => unexpected(ty, self),
594 
595             (InterfaceType::Variant(ty), Val::Variant(n, v)) => {
596                 GenericVariant::variant(&cx.types[ty], n, v)?.store(cx, offset)
597             }
598             (InterfaceType::Variant(_), _) => unexpected(ty, self),
599             (InterfaceType::Enum(ty), Val::Enum(v)) => {
600                 GenericVariant::enum_(&cx.types[ty], v)?.store(cx, offset)
601             }
602             (InterfaceType::Enum(_), _) => unexpected(ty, self),
603             (InterfaceType::Option(ty), Val::Option(v)) => {
604                 GenericVariant::option(&cx.types[ty], v).store(cx, offset)
605             }
606             (InterfaceType::Option(_), _) => unexpected(ty, self),
607             (InterfaceType::Result(ty), Val::Result(v)) => {
608                 GenericVariant::result(&cx.types[ty], v)?.store(cx, offset)
609             }
610             (InterfaceType::Result(_), _) => unexpected(ty, self),
611 
612             (InterfaceType::Flags(ty), Val::Flags(flags)) => {
613                 let ty = &cx.types[ty];
614                 let storage = flags_to_storage(ty, flags)?;
615                 match FlagsSize::from_count(ty.names.len()) {
616                     FlagsSize::Size0 => {}
617                     FlagsSize::Size1 => u8::try_from(storage[0]).unwrap().linear_lower_to_memory(
618                         cx,
619                         InterfaceType::U8,
620                         offset,
621                     )?,
622                     FlagsSize::Size2 => u16::try_from(storage[0]).unwrap().linear_lower_to_memory(
623                         cx,
624                         InterfaceType::U16,
625                         offset,
626                     )?,
627                     FlagsSize::Size4Plus(_) => {
628                         let mut offset = offset;
629                         for value in storage {
630                             value.linear_lower_to_memory(cx, InterfaceType::U32, offset)?;
631                             offset += 4;
632                         }
633                     }
634                 }
635                 Ok(())
636             }
637             (InterfaceType::Flags(_), _) => unexpected(ty, self),
638             (InterfaceType::Future(_), Val::Future(f)) => f.linear_lower_to_memory(cx, ty, offset),
639             (InterfaceType::Future(_), _) => unexpected(ty, self),
640             (InterfaceType::Stream(_), Val::Stream(s)) => s.linear_lower_to_memory(cx, ty, offset),
641             (InterfaceType::Stream(_), _) => unexpected(ty, self),
642             (InterfaceType::ErrorContext(_), Val::ErrorContext(ErrorContextAny(rep))) => {
643                 concurrent::lower_error_context_to_index(*rep, cx, ty)?.linear_lower_to_memory(
644                     cx,
645                     InterfaceType::U32,
646                     offset,
647                 )
648             }
649             (InterfaceType::ErrorContext(_), _) => unexpected(ty, self),
650             (InterfaceType::FixedLengthList(_), _) => todo!(), // FIXME(#12279)
651         }
652     }
653 
654     pub(crate) fn desc(&self) -> &'static str {
655         match self {
656             Val::Bool(_) => "bool",
657             Val::U8(_) => "u8",
658             Val::S8(_) => "s8",
659             Val::U16(_) => "u16",
660             Val::S16(_) => "s16",
661             Val::U32(_) => "u32",
662             Val::S32(_) => "s32",
663             Val::U64(_) => "u64",
664             Val::S64(_) => "s64",
665             Val::Float32(_) => "f32",
666             Val::Float64(_) => "f64",
667             Val::Char(_) => "char",
668             Val::List(_) => "list",
669             Val::String(_) => "string",
670             Val::Record(_) => "record",
671             Val::Enum(_) => "enum",
672             Val::Variant(..) => "variant",
673             Val::Tuple(_) => "tuple",
674             Val::Option(_) => "option",
675             Val::Result(_) => "result",
676             Val::Resource(_) => "resource",
677             Val::Flags(_) => "flags",
678             Val::Future(_) => "future",
679             Val::Stream(_) => "stream",
680             Val::ErrorContext(_) => "error-context",
681         }
682     }
683 
684     /// Deserialize a [`Val`] from its [`crate::component::wasm_wave`] encoding. Deserialization
685     /// requires a target [`crate::component::Type`].
686     #[cfg(feature = "wave")]
687     pub fn from_wave(ty: &crate::component::Type, s: &str) -> Result<Self> {
688         Ok(wasm_wave::from_str(ty, s)?)
689     }
690 
691     /// Serialize a [`Val`] to its [`crate::component::wasm_wave`] encoding.
692     #[cfg(feature = "wave")]
693     pub fn to_wave(&self) -> Result<String> {
694         Ok(wasm_wave::to_string(self)?)
695     }
696 }
697 
698 impl PartialEq for Val {
699     fn eq(&self, other: &Self) -> bool {
700         match (self, other) {
701             // IEEE 754 equality considers NaN inequal to NaN and negative zero
702             // equal to positive zero, however we do the opposite here, because
703             // this logic is used by testing and fuzzing, which want to know
704             // whether two values are semantically the same, rather than
705             // numerically equal.
706             (Self::Float32(l), Self::Float32(r)) => {
707                 (*l != 0.0 && l == r)
708                     || (*l == 0.0 && l.to_bits() == r.to_bits())
709                     || (l.is_nan() && r.is_nan())
710             }
711             (Self::Float32(_), _) => false,
712             (Self::Float64(l), Self::Float64(r)) => {
713                 (*l != 0.0 && l == r)
714                     || (*l == 0.0 && l.to_bits() == r.to_bits())
715                     || (l.is_nan() && r.is_nan())
716             }
717             (Self::Float64(_), _) => false,
718 
719             (Self::Bool(l), Self::Bool(r)) => l == r,
720             (Self::Bool(_), _) => false,
721             (Self::S8(l), Self::S8(r)) => l == r,
722             (Self::S8(_), _) => false,
723             (Self::U8(l), Self::U8(r)) => l == r,
724             (Self::U8(_), _) => false,
725             (Self::S16(l), Self::S16(r)) => l == r,
726             (Self::S16(_), _) => false,
727             (Self::U16(l), Self::U16(r)) => l == r,
728             (Self::U16(_), _) => false,
729             (Self::S32(l), Self::S32(r)) => l == r,
730             (Self::S32(_), _) => false,
731             (Self::U32(l), Self::U32(r)) => l == r,
732             (Self::U32(_), _) => false,
733             (Self::S64(l), Self::S64(r)) => l == r,
734             (Self::S64(_), _) => false,
735             (Self::U64(l), Self::U64(r)) => l == r,
736             (Self::U64(_), _) => false,
737             (Self::Char(l), Self::Char(r)) => l == r,
738             (Self::Char(_), _) => false,
739             (Self::String(l), Self::String(r)) => l == r,
740             (Self::String(_), _) => false,
741             (Self::List(l), Self::List(r)) => l == r,
742             (Self::List(_), _) => false,
743             (Self::Record(l), Self::Record(r)) => l == r,
744             (Self::Record(_), _) => false,
745             (Self::Tuple(l), Self::Tuple(r)) => l == r,
746             (Self::Tuple(_), _) => false,
747             (Self::Variant(ln, lv), Self::Variant(rn, rv)) => ln == rn && lv == rv,
748             (Self::Variant(..), _) => false,
749             (Self::Enum(l), Self::Enum(r)) => l == r,
750             (Self::Enum(_), _) => false,
751             (Self::Option(l), Self::Option(r)) => l == r,
752             (Self::Option(_), _) => false,
753             (Self::Result(l), Self::Result(r)) => l == r,
754             (Self::Result(_), _) => false,
755             (Self::Flags(l), Self::Flags(r)) => l == r,
756             (Self::Flags(_), _) => false,
757             (Self::Resource(l), Self::Resource(r)) => l == r,
758             (Self::Resource(_), _) => false,
759             (Self::Future(l), Self::Future(r)) => l == r,
760             (Self::Future(_), _) => false,
761             (Self::Stream(l), Self::Stream(r)) => l == r,
762             (Self::Stream(_), _) => false,
763             (Self::ErrorContext(l), Self::ErrorContext(r)) => l == r,
764             (Self::ErrorContext(_), _) => false,
765         }
766     }
767 }
768 
769 impl Eq for Val {}
770 
771 struct GenericVariant<'a> {
772     discriminant: u32,
773     payload: Option<(&'a Val, InterfaceType)>,
774     abi: &'a CanonicalAbiInfo,
775     info: &'a VariantInfo,
776 }
777 
778 impl GenericVariant<'_> {
779     fn result<'a>(
780         ty: &'a TypeResult,
781         r: &'a Result<Option<Box<Val>>, Option<Box<Val>>>,
782     ) -> Result<GenericVariant<'a>> {
783         let (discriminant, payload) = match r {
784             Ok(val) => {
785                 let payload = match (val, ty.ok) {
786                     (Some(val), Some(ty)) => Some((&**val, ty)),
787                     (None, None) => None,
788                     (Some(_), None) => {
789                         bail!("payload provided to `ok` but not expected");
790                     }
791                     (None, Some(_)) => {
792                         bail!("payload expected to `ok` but not provided");
793                     }
794                 };
795                 (0, payload)
796             }
797             Err(val) => {
798                 let payload = match (val, ty.err) {
799                     (Some(val), Some(ty)) => Some((&**val, ty)),
800                     (None, None) => None,
801                     (Some(_), None) => {
802                         bail!("payload provided to `err` but not expected");
803                     }
804                     (None, Some(_)) => {
805                         bail!("payload expected to `err` but not provided");
806                     }
807                 };
808                 (1, payload)
809             }
810         };
811         Ok(GenericVariant {
812             discriminant,
813             payload,
814             abi: &ty.abi,
815             info: &ty.info,
816         })
817     }
818 
819     fn option<'a>(ty: &'a TypeOption, r: &'a Option<Box<Val>>) -> GenericVariant<'a> {
820         let (discriminant, payload) = match r {
821             None => (0, None),
822             Some(val) => (1, Some((&**val, ty.ty))),
823         };
824         GenericVariant {
825             discriminant,
826             payload,
827             abi: &ty.abi,
828             info: &ty.info,
829         }
830     }
831 
832     fn enum_<'a>(ty: &'a TypeEnum, discriminant: &str) -> Result<GenericVariant<'a>> {
833         let discriminant = get_enum_discriminant(ty, discriminant)?;
834 
835         Ok(GenericVariant {
836             discriminant,
837             payload: None,
838             abi: &ty.abi,
839             info: &ty.info,
840         })
841     }
842 
843     fn variant<'a>(
844         ty: &'a TypeVariant,
845         discriminant_name: &str,
846         payload: &'a Option<Box<Val>>,
847     ) -> Result<GenericVariant<'a>> {
848         let (discriminant, payload_ty) = get_variant_discriminant(ty, discriminant_name)?;
849 
850         let payload = match (payload, payload_ty) {
851             (Some(val), Some(ty)) => Some((&**val, *ty)),
852             (None, None) => None,
853             (Some(_), None) => bail!("did not expect a payload for case `{discriminant_name}`"),
854             (None, Some(_)) => bail!("expected a payload for case `{discriminant_name}`"),
855         };
856 
857         Ok(GenericVariant {
858             discriminant,
859             payload,
860             abi: &ty.abi,
861             info: &ty.info,
862         })
863     }
864 
865     fn lower<T>(
866         &self,
867         cx: &mut LowerContext<'_, T>,
868         dst: &mut IterMut<'_, MaybeUninit<ValRaw>>,
869     ) -> Result<()> {
870         next_mut(dst).write(ValRaw::u32(self.discriminant));
871 
872         // For the remaining lowered representation of this variant that
873         // the payload didn't write we write out zeros here to ensure
874         // the entire variant is written.
875         let value_flat = match self.payload {
876             Some((value, ty)) => {
877                 value.lower(cx, ty, dst)?;
878                 cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap()
879             }
880             None => 0,
881         };
882         let variant_flat = self.abi.flat_count(usize::MAX).unwrap();
883         for _ in (1 + value_flat)..variant_flat {
884             next_mut(dst).write(ValRaw::u64(0));
885         }
886         Ok(())
887     }
888 
889     fn store<T>(&self, cx: &mut LowerContext<'_, T>, offset: usize) -> Result<()> {
890         match self.info.size {
891             DiscriminantSize::Size1 => u8::try_from(self.discriminant)
892                 .unwrap()
893                 .linear_lower_to_memory(cx, InterfaceType::U8, offset)?,
894             DiscriminantSize::Size2 => u16::try_from(self.discriminant)
895                 .unwrap()
896                 .linear_lower_to_memory(cx, InterfaceType::U16, offset)?,
897             DiscriminantSize::Size4 => {
898                 self.discriminant
899                     .linear_lower_to_memory(cx, InterfaceType::U32, offset)?
900             }
901         }
902 
903         if let Some((value, ty)) = self.payload {
904             let offset = offset + usize::try_from(self.info.payload_offset32).unwrap();
905             value.store(cx, ty, offset)?;
906         }
907 
908         Ok(())
909     }
910 }
911 
912 fn load_list(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize) -> Result<Val> {
913     let elem = cx.types[ty].element;
914     let abi = cx.types.canonical_abi(&elem);
915     let element_size = usize::try_from(abi.size32).unwrap();
916     let element_alignment = abi.align32;
917 
918     match len
919         .checked_mul(element_size)
920         .and_then(|len| ptr.checked_add(len))
921     {
922         Some(n) if n <= cx.memory().len() => {}
923         _ => bail!("list pointer/length out of bounds of memory"),
924     }
925     if ptr % usize::try_from(element_alignment)? != 0 {
926         bail!("list pointer is not aligned")
927     }
928 
929     Ok(Val::List(
930         (0..len)
931             .map(|index| {
932                 Val::load(
933                     cx,
934                     elem,
935                     &cx.memory()[ptr + (index * element_size)..][..element_size],
936                 )
937             })
938             .collect::<Result<_>>()?,
939     ))
940 }
941 
942 fn load_variant(
943     cx: &mut LiftContext<'_>,
944     info: &VariantInfo,
945     mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
946     bytes: &[u8],
947 ) -> Result<(u32, Option<Box<Val>>)> {
948     let discriminant = match info.size {
949         DiscriminantSize::Size1 => u32::from(u8::linear_lift_from_memory(
950             cx,
951             InterfaceType::U8,
952             &bytes[..1],
953         )?),
954         DiscriminantSize::Size2 => u32::from(u16::linear_lift_from_memory(
955             cx,
956             InterfaceType::U16,
957             &bytes[..2],
958         )?),
959         DiscriminantSize::Size4 => {
960             u32::linear_lift_from_memory(cx, InterfaceType::U32, &bytes[..4])?
961         }
962     };
963     let case_ty = types.nth(discriminant as usize).ok_or_else(|| {
964         format_err!(
965             "discriminant {} out of range [0..{})",
966             discriminant,
967             types.len()
968         )
969     })?;
970     let value = match case_ty {
971         Some(case_ty) => {
972             let payload_offset = usize::try_from(info.payload_offset32).unwrap();
973             let case_abi = cx.types.canonical_abi(&case_ty);
974             let case_size = usize::try_from(case_abi.size32).unwrap();
975             Some(Box::new(Val::load(
976                 cx,
977                 case_ty,
978                 &bytes[payload_offset..][..case_size],
979             )?))
980         }
981         None => None,
982     };
983     Ok((discriminant, value))
984 }
985 
986 fn lift_variant(
987     cx: &mut LiftContext<'_>,
988     flatten_count: usize,
989     mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
990     src: &mut Iter<'_, ValRaw>,
991 ) -> Result<(u32, Option<Box<Val>>)> {
992     let len = types.len();
993     let discriminant = next(src).get_u32();
994     let ty = types
995         .nth(discriminant as usize)
996         .ok_or_else(|| format_err!("discriminant {discriminant} out of range [0..{len})"))?;
997     let (value, value_flat) = match ty {
998         Some(ty) => (
999             Some(Box::new(Val::lift(cx, ty, src)?)),
1000             cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
1001         ),
1002         None => (None, 0),
1003     };
1004     for _ in (1 + value_flat)..flatten_count {
1005         next(src);
1006     }
1007     Ok((discriminant, value))
1008 }
1009 
1010 /// Lower a list with the specified element type and values.
1011 fn lower_list<T>(
1012     cx: &mut LowerContext<'_, T>,
1013     element_type: InterfaceType,
1014     items: &[Val],
1015 ) -> Result<(usize, usize)> {
1016     let abi = cx.types.canonical_abi(&element_type);
1017     let elt_size = usize::try_from(abi.size32)?;
1018     let elt_align = abi.align32;
1019     let size = items
1020         .len()
1021         .checked_mul(elt_size)
1022         .ok_or_else(|| crate::format_err!("size overflow copying a list"))?;
1023     let ptr = cx.realloc(0, 0, elt_align, size)?;
1024     let mut element_ptr = ptr;
1025     for item in items {
1026         item.store(cx, element_type, element_ptr)?;
1027         element_ptr += elt_size;
1028     }
1029     Ok((ptr, items.len()))
1030 }
1031 
1032 fn push_flags(ty: &TypeFlags, flags: &mut Vec<String>, mut offset: u32, mut bits: u32) {
1033     while bits > 0 {
1034         if bits & 1 != 0 {
1035             flags.push(ty.names[offset as usize].clone());
1036         }
1037         bits >>= 1;
1038         offset += 1;
1039     }
1040 }
1041 
1042 fn flags_to_storage(ty: &TypeFlags, flags: &[String]) -> Result<Vec<u32>> {
1043     let mut storage = match FlagsSize::from_count(ty.names.len()) {
1044         FlagsSize::Size0 => Vec::new(),
1045         FlagsSize::Size1 | FlagsSize::Size2 => vec![0],
1046         FlagsSize::Size4Plus(n) => vec![0; n.into()],
1047     };
1048 
1049     for flag in flags {
1050         let bit = ty
1051             .names
1052             .get_index_of(flag)
1053             .ok_or_else(|| crate::format_err!("unknown flag: `{flag}`"))?;
1054         storage[bit / 32] |= 1 << (bit % 32);
1055     }
1056     Ok(storage)
1057 }
1058 
1059 fn get_enum_discriminant(ty: &TypeEnum, n: &str) -> Result<u32> {
1060     ty.names
1061         .get_index_of(n)
1062         .ok_or_else(|| crate::format_err!("enum variant name `{n}` is not valid"))
1063         .map(|i| i.try_into().unwrap())
1064 }
1065 
1066 fn get_variant_discriminant<'a>(
1067     ty: &'a TypeVariant,
1068     name: &str,
1069 ) -> Result<(u32, &'a Option<InterfaceType>)> {
1070     let (i, _, ty) = ty
1071         .cases
1072         .get_full(name)
1073         .ok_or_else(|| crate::format_err!("unknown variant case: `{name}`"))?;
1074     Ok((i.try_into().unwrap(), ty))
1075 }
1076 
1077 fn next<'a>(src: &mut Iter<'a, ValRaw>) -> &'a ValRaw {
1078     src.next().unwrap()
1079 }
1080 
1081 fn next_mut<'a>(dst: &mut IterMut<'a, MaybeUninit<ValRaw>>) -> &'a mut MaybeUninit<ValRaw> {
1082     dst.next().unwrap()
1083 }
1084 
1085 #[cold]
1086 fn unexpected<T>(ty: InterfaceType, val: &Val) -> Result<T> {
1087     bail!(
1088         "type mismatch: expected {}, found {}",
1089         desc(&ty),
1090         val.desc()
1091     )
1092 }
1093 
1094 /// Represents a component model `error-context`.
1095 ///
1096 /// Note that this type is not usable at this time as its implementation has not
1097 /// been filled out. There are no operations on this and there's additionally no
1098 /// ability to "drop" or deallocate this index.
1099 //
1100 // FIXME(#11161) this needs to be filled out implementation-wise
1101 #[derive(Debug, Clone, PartialEq, Eq)]
1102 pub struct ErrorContextAny(pub(crate) u32);
1103 
1104 impl From<bool> for Val {
1105     fn from(b: bool) -> Self {
1106         Val::Bool(b)
1107     }
1108 }
1109 
1110 impl From<u8> for Val {
1111     fn from(u: u8) -> Self {
1112         Val::U8(u)
1113     }
1114 }
1115 
1116 impl From<i8> for Val {
1117     fn from(i: i8) -> Self {
1118         Val::S8(i)
1119     }
1120 }
1121 
1122 impl From<u16> for Val {
1123     fn from(u: u16) -> Self {
1124         Val::U16(u)
1125     }
1126 }
1127 
1128 impl From<i16> for Val {
1129     fn from(i: i16) -> Self {
1130         Val::S16(i)
1131     }
1132 }
1133 
1134 impl From<u32> for Val {
1135     fn from(u: u32) -> Self {
1136         Val::U32(u)
1137     }
1138 }
1139 
1140 impl From<i32> for Val {
1141     fn from(i: i32) -> Self {
1142         Val::S32(i)
1143     }
1144 }
1145 
1146 impl From<u64> for Val {
1147     fn from(u: u64) -> Self {
1148         Val::U64(u)
1149     }
1150 }
1151 
1152 impl From<i64> for Val {
1153     fn from(i: i64) -> Self {
1154         Val::S64(i)
1155     }
1156 }
1157 
1158 impl From<char> for Val {
1159     fn from(i: char) -> Self {
1160         Val::Char(i)
1161     }
1162 }
1163 
1164 impl From<String> for Val {
1165     fn from(i: String) -> Self {
1166         Val::String(i)
1167     }
1168 }
1169 
1170 impl From<ResourceAny> for Val {
1171     fn from(i: ResourceAny) -> Self {
1172         Val::Resource(i)
1173     }
1174 }
1175 
1176 impl From<FutureAny> for Val {
1177     fn from(i: FutureAny) -> Self {
1178         Val::Future(i)
1179     }
1180 }
1181 
1182 impl From<StreamAny> for Val {
1183     fn from(i: StreamAny) -> Self {
1184         Val::Stream(i)
1185     }
1186 }
1187