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         })
219     }
220 
221     /// Deserialize a value of this type from the heap.
222     pub(crate) fn load(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Val> {
223         Ok(match ty {
224             InterfaceType::Bool => Val::Bool(bool::linear_lift_from_memory(cx, ty, bytes)?),
225             InterfaceType::S8 => Val::S8(i8::linear_lift_from_memory(cx, ty, bytes)?),
226             InterfaceType::U8 => Val::U8(u8::linear_lift_from_memory(cx, ty, bytes)?),
227             InterfaceType::S16 => Val::S16(i16::linear_lift_from_memory(cx, ty, bytes)?),
228             InterfaceType::U16 => Val::U16(u16::linear_lift_from_memory(cx, ty, bytes)?),
229             InterfaceType::S32 => Val::S32(i32::linear_lift_from_memory(cx, ty, bytes)?),
230             InterfaceType::U32 => Val::U32(u32::linear_lift_from_memory(cx, ty, bytes)?),
231             InterfaceType::S64 => Val::S64(i64::linear_lift_from_memory(cx, ty, bytes)?),
232             InterfaceType::U64 => Val::U64(u64::linear_lift_from_memory(cx, ty, bytes)?),
233             InterfaceType::Float32 => Val::Float32(f32::linear_lift_from_memory(cx, ty, bytes)?),
234             InterfaceType::Float64 => Val::Float64(f64::linear_lift_from_memory(cx, ty, bytes)?),
235             InterfaceType::Char => Val::Char(char::linear_lift_from_memory(cx, ty, bytes)?),
236             InterfaceType::String => Val::String(<_>::linear_lift_from_memory(cx, ty, bytes)?),
237             InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
238                 Val::Resource(ResourceAny::linear_lift_from_memory(cx, ty, bytes)?)
239             }
240             InterfaceType::List(i) => {
241                 // FIXME(#4311): needs memory64 treatment
242                 let ptr = u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize;
243                 let len = u32::from_le_bytes(bytes[4..].try_into().unwrap()) as usize;
244                 load_list(cx, i, ptr, len)?
245             }
246 
247             InterfaceType::Record(i) => {
248                 let mut offset = 0;
249                 let fields = cx.types[i].fields.iter();
250                 Val::Record(
251                     fields
252                         .map(|field| -> Result<(String, Val)> {
253                             let abi = cx.types.canonical_abi(&field.ty);
254                             let offset = abi.next_field32(&mut offset);
255                             let offset = usize::try_from(offset).unwrap();
256                             let size = usize::try_from(abi.size32).unwrap();
257                             Ok((
258                                 field.name.to_string(),
259                                 Val::load(cx, field.ty, &bytes[offset..][..size])?,
260                             ))
261                         })
262                         .collect::<Result<_>>()?,
263                 )
264             }
265             InterfaceType::Tuple(i) => {
266                 let types = cx.types[i].types.iter().copied();
267                 let mut offset = 0;
268                 Val::Tuple(
269                     types
270                         .map(|ty| {
271                             let abi = cx.types.canonical_abi(&ty);
272                             let offset = abi.next_field32(&mut offset);
273                             let offset = usize::try_from(offset).unwrap();
274                             let size = usize::try_from(abi.size32).unwrap();
275                             Val::load(cx, ty, &bytes[offset..][..size])
276                         })
277                         .collect::<Result<_>>()?,
278                 )
279             }
280             InterfaceType::Variant(i) => {
281                 let ty = &cx.types[i];
282                 let (discriminant, value) =
283                     load_variant(cx, &ty.info, ty.cases.values().copied(), bytes)?;
284 
285                 let (k, _) = ty.cases.get_index(discriminant as usize).unwrap();
286                 Val::Variant(k.clone(), value)
287             }
288             InterfaceType::Enum(i) => {
289                 let ty = &cx.types[i];
290                 let (discriminant, _) =
291                     load_variant(cx, &ty.info, ty.names.iter().map(|_| None), bytes)?;
292 
293                 Val::Enum(ty.names[discriminant as usize].clone())
294             }
295             InterfaceType::Option(i) => {
296                 let ty = &cx.types[i];
297                 let (_discriminant, value) =
298                     load_variant(cx, &ty.info, [None, Some(ty.ty)].into_iter(), bytes)?;
299 
300                 Val::Option(value)
301             }
302             InterfaceType::Result(i) => {
303                 let ty = &cx.types[i];
304                 let (discriminant, value) =
305                     load_variant(cx, &ty.info, [ty.ok, ty.err].into_iter(), bytes)?;
306 
307                 Val::Result(if discriminant == 0 {
308                     Ok(value)
309                 } else {
310                     Err(value)
311                 })
312             }
313             InterfaceType::Flags(i) => {
314                 let ty = &cx.types[i];
315                 let mut flags = Vec::new();
316                 match FlagsSize::from_count(ty.names.len()) {
317                     FlagsSize::Size0 => {}
318                     FlagsSize::Size1 => {
319                         let bits = u8::linear_lift_from_memory(cx, InterfaceType::U8, bytes)?;
320                         push_flags(ty, &mut flags, 0, u32::from(bits));
321                     }
322                     FlagsSize::Size2 => {
323                         let bits = u16::linear_lift_from_memory(cx, InterfaceType::U16, bytes)?;
324                         push_flags(ty, &mut flags, 0, u32::from(bits));
325                     }
326                     FlagsSize::Size4Plus(n) => {
327                         for i in 0..n {
328                             let bits = u32::linear_lift_from_memory(
329                                 cx,
330                                 InterfaceType::U32,
331                                 &bytes[usize::from(i) * 4..][..4],
332                             )?;
333                             push_flags(ty, &mut flags, u32::from(i) * 32, bits);
334                         }
335                     }
336                 }
337                 Val::Flags(flags)
338             }
339             InterfaceType::Future(_) => FutureAny::linear_lift_from_memory(cx, ty, bytes)?.into(),
340             InterfaceType::Stream(_) => StreamAny::linear_lift_from_memory(cx, ty, bytes)?.into(),
341             InterfaceType::ErrorContext(_) => {
342                 ErrorContext::linear_lift_from_memory(cx, ty, bytes)?.into_val()
343             }
344         })
345     }
346 
347     /// Serialize this value as core Wasm stack values.
348     pub(crate) fn lower<T>(
349         &self,
350         cx: &mut LowerContext<'_, T>,
351         ty: InterfaceType,
352         dst: &mut IterMut<'_, MaybeUninit<ValRaw>>,
353     ) -> Result<()> {
354         match (ty, self) {
355             (InterfaceType::Bool, Val::Bool(value)) => {
356                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
357             }
358             (InterfaceType::Bool, _) => unexpected(ty, self),
359             (InterfaceType::S8, Val::S8(value)) => {
360                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
361             }
362             (InterfaceType::S8, _) => unexpected(ty, self),
363             (InterfaceType::U8, Val::U8(value)) => {
364                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
365             }
366             (InterfaceType::U8, _) => unexpected(ty, self),
367             (InterfaceType::S16, Val::S16(value)) => {
368                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
369             }
370             (InterfaceType::S16, _) => unexpected(ty, self),
371             (InterfaceType::U16, Val::U16(value)) => {
372                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
373             }
374             (InterfaceType::U16, _) => unexpected(ty, self),
375             (InterfaceType::S32, Val::S32(value)) => {
376                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
377             }
378             (InterfaceType::S32, _) => unexpected(ty, self),
379             (InterfaceType::U32, Val::U32(value)) => {
380                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
381             }
382             (InterfaceType::U32, _) => unexpected(ty, self),
383             (InterfaceType::S64, Val::S64(value)) => {
384                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
385             }
386             (InterfaceType::S64, _) => unexpected(ty, self),
387             (InterfaceType::U64, Val::U64(value)) => {
388                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
389             }
390             (InterfaceType::U64, _) => unexpected(ty, self),
391             (InterfaceType::Float32, Val::Float32(value)) => {
392                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
393             }
394             (InterfaceType::Float32, _) => unexpected(ty, self),
395             (InterfaceType::Float64, Val::Float64(value)) => {
396                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
397             }
398             (InterfaceType::Float64, _) => unexpected(ty, self),
399             (InterfaceType::Char, Val::Char(value)) => {
400                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
401             }
402             (InterfaceType::Char, _) => unexpected(ty, self),
403             // NB: `lower` on `ResourceAny` does its own type-checking, so skip
404             // looking at it here.
405             (InterfaceType::Borrow(_) | InterfaceType::Own(_), Val::Resource(value)) => {
406                 value.linear_lower_to_flat(cx, ty, next_mut(dst))
407             }
408             (InterfaceType::Borrow(_) | InterfaceType::Own(_), _) => unexpected(ty, self),
409             (InterfaceType::String, Val::String(value)) => {
410                 let my_dst = &mut MaybeUninit::<[ValRaw; 2]>::uninit();
411                 value.linear_lower_to_flat(cx, ty, my_dst)?;
412                 let my_dst = unsafe { my_dst.assume_init() };
413                 next_mut(dst).write(my_dst[0]);
414                 next_mut(dst).write(my_dst[1]);
415                 Ok(())
416             }
417             (InterfaceType::String, _) => unexpected(ty, self),
418             (InterfaceType::List(ty), Val::List(values)) => {
419                 let ty = &cx.types[ty];
420                 let (ptr, len) = lower_list(cx, ty.element, values)?;
421                 next_mut(dst).write(ValRaw::i64(ptr as i64));
422                 next_mut(dst).write(ValRaw::i64(len as i64));
423                 Ok(())
424             }
425             (InterfaceType::List(_), _) => unexpected(ty, self),
426             (InterfaceType::Record(ty), Val::Record(values)) => {
427                 let ty = &cx.types[ty];
428                 if ty.fields.len() != values.len() {
429                     bail!("expected {} fields, got {}", ty.fields.len(), values.len());
430                 }
431                 for ((name, value), field) in values.iter().zip(ty.fields.iter()) {
432                     if *name != field.name {
433                         bail!("expected field `{}`, got `{name}`", field.name);
434                     }
435                     value.lower(cx, field.ty, dst)?;
436                 }
437                 Ok(())
438             }
439             (InterfaceType::Record(_), _) => unexpected(ty, self),
440             (InterfaceType::Tuple(ty), Val::Tuple(values)) => {
441                 let ty = &cx.types[ty];
442                 if ty.types.len() != values.len() {
443                     bail!("expected {} types, got {}", ty.types.len(), values.len());
444                 }
445                 for (value, ty) in values.iter().zip(ty.types.iter()) {
446                     value.lower(cx, *ty, dst)?;
447                 }
448                 Ok(())
449             }
450             (InterfaceType::Tuple(_), _) => unexpected(ty, self),
451             (InterfaceType::Variant(ty), Val::Variant(n, v)) => {
452                 GenericVariant::variant(&cx.types[ty], n, v)?.lower(cx, dst)
453             }
454             (InterfaceType::Variant(_), _) => unexpected(ty, self),
455             (InterfaceType::Option(ty), Val::Option(v)) => {
456                 GenericVariant::option(&cx.types[ty], v).lower(cx, dst)
457             }
458             (InterfaceType::Option(_), _) => unexpected(ty, self),
459             (InterfaceType::Result(ty), Val::Result(v)) => {
460                 GenericVariant::result(&cx.types[ty], v)?.lower(cx, dst)
461             }
462             (InterfaceType::Result(_), _) => unexpected(ty, self),
463             (InterfaceType::Enum(ty), Val::Enum(discriminant)) => {
464                 let discriminant = get_enum_discriminant(&cx.types[ty], discriminant)?;
465                 next_mut(dst).write(ValRaw::u32(discriminant));
466                 Ok(())
467             }
468             (InterfaceType::Enum(_), _) => unexpected(ty, self),
469             (InterfaceType::Flags(ty), Val::Flags(value)) => {
470                 let ty = &cx.types[ty];
471                 let storage = flags_to_storage(ty, value)?;
472                 for value in storage {
473                     next_mut(dst).write(ValRaw::u32(value));
474                 }
475                 Ok(())
476             }
477             (InterfaceType::Flags(_), _) => unexpected(ty, self),
478             (InterfaceType::Future(_), Val::Future(f)) => {
479                 f.linear_lower_to_flat(cx, ty, next_mut(dst))
480             }
481             (InterfaceType::Future(_), _) => unexpected(ty, self),
482             (InterfaceType::Stream(_), Val::Stream(s)) => {
483                 s.linear_lower_to_flat(cx, ty, next_mut(dst))
484             }
485             (InterfaceType::Stream(_), _) => unexpected(ty, self),
486             (InterfaceType::ErrorContext(_), Val::ErrorContext(ErrorContextAny(rep))) => {
487                 concurrent::lower_error_context_to_index(*rep, cx, ty)?.linear_lower_to_flat(
488                     cx,
489                     InterfaceType::U32,
490                     next_mut(dst),
491                 )
492             }
493             (InterfaceType::ErrorContext(_), _) => unexpected(ty, self),
494         }
495     }
496 
497     /// Serialize this value to the heap at the specified memory location.
498     pub(crate) fn store<T>(
499         &self,
500         cx: &mut LowerContext<'_, T>,
501         ty: InterfaceType,
502         offset: usize,
503     ) -> Result<()> {
504         debug_assert!(offset % usize::try_from(cx.types.canonical_abi(&ty).align32)? == 0);
505 
506         match (ty, self) {
507             (InterfaceType::Bool, Val::Bool(value)) => value.linear_lower_to_memory(cx, ty, offset),
508             (InterfaceType::Bool, _) => unexpected(ty, self),
509             (InterfaceType::U8, Val::U8(value)) => value.linear_lower_to_memory(cx, ty, offset),
510             (InterfaceType::U8, _) => unexpected(ty, self),
511             (InterfaceType::S8, Val::S8(value)) => value.linear_lower_to_memory(cx, ty, offset),
512             (InterfaceType::S8, _) => unexpected(ty, self),
513             (InterfaceType::U16, Val::U16(value)) => value.linear_lower_to_memory(cx, ty, offset),
514             (InterfaceType::U16, _) => unexpected(ty, self),
515             (InterfaceType::S16, Val::S16(value)) => value.linear_lower_to_memory(cx, ty, offset),
516             (InterfaceType::S16, _) => unexpected(ty, self),
517             (InterfaceType::U32, Val::U32(value)) => value.linear_lower_to_memory(cx, ty, offset),
518             (InterfaceType::U32, _) => unexpected(ty, self),
519             (InterfaceType::S32, Val::S32(value)) => value.linear_lower_to_memory(cx, ty, offset),
520             (InterfaceType::S32, _) => unexpected(ty, self),
521             (InterfaceType::U64, Val::U64(value)) => value.linear_lower_to_memory(cx, ty, offset),
522             (InterfaceType::U64, _) => unexpected(ty, self),
523             (InterfaceType::S64, Val::S64(value)) => value.linear_lower_to_memory(cx, ty, offset),
524             (InterfaceType::S64, _) => unexpected(ty, self),
525             (InterfaceType::Float32, Val::Float32(value)) => {
526                 value.linear_lower_to_memory(cx, ty, offset)
527             }
528             (InterfaceType::Float32, _) => unexpected(ty, self),
529             (InterfaceType::Float64, Val::Float64(value)) => {
530                 value.linear_lower_to_memory(cx, ty, offset)
531             }
532             (InterfaceType::Float64, _) => unexpected(ty, self),
533             (InterfaceType::Char, Val::Char(value)) => value.linear_lower_to_memory(cx, ty, offset),
534             (InterfaceType::Char, _) => unexpected(ty, self),
535             (InterfaceType::String, Val::String(value)) => {
536                 value.linear_lower_to_memory(cx, ty, offset)
537             }
538             (InterfaceType::String, _) => unexpected(ty, self),
539 
540             // NB: resources do type-checking when they lower.
541             (InterfaceType::Borrow(_) | InterfaceType::Own(_), Val::Resource(value)) => {
542                 value.linear_lower_to_memory(cx, ty, offset)
543             }
544             (InterfaceType::Borrow(_) | InterfaceType::Own(_), _) => unexpected(ty, self),
545             (InterfaceType::List(ty), Val::List(values)) => {
546                 let ty = &cx.types[ty];
547                 let (ptr, len) = lower_list(cx, ty.element, values)?;
548                 // FIXME(#4311): needs memory64 handling
549                 *cx.get(offset + 0) = u32::try_from(ptr).unwrap().to_le_bytes();
550                 *cx.get(offset + 4) = u32::try_from(len).unwrap().to_le_bytes();
551                 Ok(())
552             }
553             (InterfaceType::List(_), _) => unexpected(ty, self),
554             (InterfaceType::Record(ty), Val::Record(values)) => {
555                 let ty = &cx.types[ty];
556                 if ty.fields.len() != values.len() {
557                     bail!("expected {} fields, got {}", ty.fields.len(), values.len());
558                 }
559                 let mut offset = offset;
560                 for ((name, value), field) in values.iter().zip(ty.fields.iter()) {
561                     if *name != field.name {
562                         bail!("expected field `{}`, got `{name}`", field.name);
563                     }
564                     value.store(
565                         cx,
566                         field.ty,
567                         cx.types
568                             .canonical_abi(&field.ty)
569                             .next_field32_size(&mut offset),
570                     )?;
571                 }
572                 Ok(())
573             }
574             (InterfaceType::Record(_), _) => unexpected(ty, self),
575             (InterfaceType::Tuple(ty), Val::Tuple(values)) => {
576                 let ty = &cx.types[ty];
577                 if ty.types.len() != values.len() {
578                     bail!("expected {} types, got {}", ty.types.len(), values.len());
579                 }
580                 let mut offset = offset;
581                 for (value, ty) in values.iter().zip(ty.types.iter()) {
582                     value.store(
583                         cx,
584                         *ty,
585                         cx.types.canonical_abi(ty).next_field32_size(&mut offset),
586                     )?;
587                 }
588                 Ok(())
589             }
590             (InterfaceType::Tuple(_), _) => unexpected(ty, self),
591 
592             (InterfaceType::Variant(ty), Val::Variant(n, v)) => {
593                 GenericVariant::variant(&cx.types[ty], n, v)?.store(cx, offset)
594             }
595             (InterfaceType::Variant(_), _) => unexpected(ty, self),
596             (InterfaceType::Enum(ty), Val::Enum(v)) => {
597                 GenericVariant::enum_(&cx.types[ty], v)?.store(cx, offset)
598             }
599             (InterfaceType::Enum(_), _) => unexpected(ty, self),
600             (InterfaceType::Option(ty), Val::Option(v)) => {
601                 GenericVariant::option(&cx.types[ty], v).store(cx, offset)
602             }
603             (InterfaceType::Option(_), _) => unexpected(ty, self),
604             (InterfaceType::Result(ty), Val::Result(v)) => {
605                 GenericVariant::result(&cx.types[ty], v)?.store(cx, offset)
606             }
607             (InterfaceType::Result(_), _) => unexpected(ty, self),
608 
609             (InterfaceType::Flags(ty), Val::Flags(flags)) => {
610                 let ty = &cx.types[ty];
611                 let storage = flags_to_storage(ty, flags)?;
612                 match FlagsSize::from_count(ty.names.len()) {
613                     FlagsSize::Size0 => {}
614                     FlagsSize::Size1 => u8::try_from(storage[0]).unwrap().linear_lower_to_memory(
615                         cx,
616                         InterfaceType::U8,
617                         offset,
618                     )?,
619                     FlagsSize::Size2 => u16::try_from(storage[0]).unwrap().linear_lower_to_memory(
620                         cx,
621                         InterfaceType::U16,
622                         offset,
623                     )?,
624                     FlagsSize::Size4Plus(_) => {
625                         let mut offset = offset;
626                         for value in storage {
627                             value.linear_lower_to_memory(cx, InterfaceType::U32, offset)?;
628                             offset += 4;
629                         }
630                     }
631                 }
632                 Ok(())
633             }
634             (InterfaceType::Flags(_), _) => unexpected(ty, self),
635             (InterfaceType::Future(_), Val::Future(f)) => f.linear_lower_to_memory(cx, ty, offset),
636             (InterfaceType::Future(_), _) => unexpected(ty, self),
637             (InterfaceType::Stream(_), Val::Stream(s)) => s.linear_lower_to_memory(cx, ty, offset),
638             (InterfaceType::Stream(_), _) => unexpected(ty, self),
639             (InterfaceType::ErrorContext(_), Val::ErrorContext(ErrorContextAny(rep))) => {
640                 concurrent::lower_error_context_to_index(*rep, cx, ty)?.linear_lower_to_memory(
641                     cx,
642                     InterfaceType::U32,
643                     offset,
644                 )
645             }
646             (InterfaceType::ErrorContext(_), _) => unexpected(ty, self),
647         }
648     }
649 
650     pub(crate) fn desc(&self) -> &'static str {
651         match self {
652             Val::Bool(_) => "bool",
653             Val::U8(_) => "u8",
654             Val::S8(_) => "s8",
655             Val::U16(_) => "u16",
656             Val::S16(_) => "s16",
657             Val::U32(_) => "u32",
658             Val::S32(_) => "s32",
659             Val::U64(_) => "u64",
660             Val::S64(_) => "s64",
661             Val::Float32(_) => "f32",
662             Val::Float64(_) => "f64",
663             Val::Char(_) => "char",
664             Val::List(_) => "list",
665             Val::String(_) => "string",
666             Val::Record(_) => "record",
667             Val::Enum(_) => "enum",
668             Val::Variant(..) => "variant",
669             Val::Tuple(_) => "tuple",
670             Val::Option(_) => "option",
671             Val::Result(_) => "result",
672             Val::Resource(_) => "resource",
673             Val::Flags(_) => "flags",
674             Val::Future(_) => "future",
675             Val::Stream(_) => "stream",
676             Val::ErrorContext(_) => "error-context",
677         }
678     }
679 
680     /// Deserialize a [`Val`] from its [`crate::component::wasm_wave`] encoding. Deserialization
681     /// requires a target [`crate::component::Type`].
682     #[cfg(feature = "wave")]
683     pub fn from_wave(ty: &crate::component::Type, s: &str) -> Result<Self> {
684         Ok(wasm_wave::from_str(ty, s)?)
685     }
686 
687     /// Serialize a [`Val`] to its [`crate::component::wasm_wave`] encoding.
688     #[cfg(feature = "wave")]
689     pub fn to_wave(&self) -> Result<String> {
690         Ok(wasm_wave::to_string(self)?)
691     }
692 }
693 
694 impl PartialEq for Val {
695     fn eq(&self, other: &Self) -> bool {
696         match (self, other) {
697             // IEEE 754 equality considers NaN inequal to NaN and negative zero
698             // equal to positive zero, however we do the opposite here, because
699             // this logic is used by testing and fuzzing, which want to know
700             // whether two values are semantically the same, rather than
701             // numerically equal.
702             (Self::Float32(l), Self::Float32(r)) => {
703                 (*l != 0.0 && l == r)
704                     || (*l == 0.0 && l.to_bits() == r.to_bits())
705                     || (l.is_nan() && r.is_nan())
706             }
707             (Self::Float32(_), _) => false,
708             (Self::Float64(l), Self::Float64(r)) => {
709                 (*l != 0.0 && l == r)
710                     || (*l == 0.0 && l.to_bits() == r.to_bits())
711                     || (l.is_nan() && r.is_nan())
712             }
713             (Self::Float64(_), _) => false,
714 
715             (Self::Bool(l), Self::Bool(r)) => l == r,
716             (Self::Bool(_), _) => false,
717             (Self::S8(l), Self::S8(r)) => l == r,
718             (Self::S8(_), _) => false,
719             (Self::U8(l), Self::U8(r)) => l == r,
720             (Self::U8(_), _) => false,
721             (Self::S16(l), Self::S16(r)) => l == r,
722             (Self::S16(_), _) => false,
723             (Self::U16(l), Self::U16(r)) => l == r,
724             (Self::U16(_), _) => false,
725             (Self::S32(l), Self::S32(r)) => l == r,
726             (Self::S32(_), _) => false,
727             (Self::U32(l), Self::U32(r)) => l == r,
728             (Self::U32(_), _) => false,
729             (Self::S64(l), Self::S64(r)) => l == r,
730             (Self::S64(_), _) => false,
731             (Self::U64(l), Self::U64(r)) => l == r,
732             (Self::U64(_), _) => false,
733             (Self::Char(l), Self::Char(r)) => l == r,
734             (Self::Char(_), _) => false,
735             (Self::String(l), Self::String(r)) => l == r,
736             (Self::String(_), _) => false,
737             (Self::List(l), Self::List(r)) => l == r,
738             (Self::List(_), _) => false,
739             (Self::Record(l), Self::Record(r)) => l == r,
740             (Self::Record(_), _) => false,
741             (Self::Tuple(l), Self::Tuple(r)) => l == r,
742             (Self::Tuple(_), _) => false,
743             (Self::Variant(ln, lv), Self::Variant(rn, rv)) => ln == rn && lv == rv,
744             (Self::Variant(..), _) => false,
745             (Self::Enum(l), Self::Enum(r)) => l == r,
746             (Self::Enum(_), _) => false,
747             (Self::Option(l), Self::Option(r)) => l == r,
748             (Self::Option(_), _) => false,
749             (Self::Result(l), Self::Result(r)) => l == r,
750             (Self::Result(_), _) => false,
751             (Self::Flags(l), Self::Flags(r)) => l == r,
752             (Self::Flags(_), _) => false,
753             (Self::Resource(l), Self::Resource(r)) => l == r,
754             (Self::Resource(_), _) => false,
755             (Self::Future(l), Self::Future(r)) => l == r,
756             (Self::Future(_), _) => false,
757             (Self::Stream(l), Self::Stream(r)) => l == r,
758             (Self::Stream(_), _) => false,
759             (Self::ErrorContext(l), Self::ErrorContext(r)) => l == r,
760             (Self::ErrorContext(_), _) => false,
761         }
762     }
763 }
764 
765 impl Eq for Val {}
766 
767 struct GenericVariant<'a> {
768     discriminant: u32,
769     payload: Option<(&'a Val, InterfaceType)>,
770     abi: &'a CanonicalAbiInfo,
771     info: &'a VariantInfo,
772 }
773 
774 impl GenericVariant<'_> {
775     fn result<'a>(
776         ty: &'a TypeResult,
777         r: &'a Result<Option<Box<Val>>, Option<Box<Val>>>,
778     ) -> Result<GenericVariant<'a>> {
779         let (discriminant, payload) = match r {
780             Ok(val) => {
781                 let payload = match (val, ty.ok) {
782                     (Some(val), Some(ty)) => Some((&**val, ty)),
783                     (None, None) => None,
784                     (Some(_), None) => {
785                         bail!("payload provided to `ok` but not expected");
786                     }
787                     (None, Some(_)) => {
788                         bail!("payload expected to `ok` but not provided");
789                     }
790                 };
791                 (0, payload)
792             }
793             Err(val) => {
794                 let payload = match (val, ty.err) {
795                     (Some(val), Some(ty)) => Some((&**val, ty)),
796                     (None, None) => None,
797                     (Some(_), None) => {
798                         bail!("payload provided to `err` but not expected");
799                     }
800                     (None, Some(_)) => {
801                         bail!("payload expected to `err` but not provided");
802                     }
803                 };
804                 (1, payload)
805             }
806         };
807         Ok(GenericVariant {
808             discriminant,
809             payload,
810             abi: &ty.abi,
811             info: &ty.info,
812         })
813     }
814 
815     fn option<'a>(ty: &'a TypeOption, r: &'a Option<Box<Val>>) -> GenericVariant<'a> {
816         let (discriminant, payload) = match r {
817             None => (0, None),
818             Some(val) => (1, Some((&**val, ty.ty))),
819         };
820         GenericVariant {
821             discriminant,
822             payload,
823             abi: &ty.abi,
824             info: &ty.info,
825         }
826     }
827 
828     fn enum_<'a>(ty: &'a TypeEnum, discriminant: &str) -> Result<GenericVariant<'a>> {
829         let discriminant = get_enum_discriminant(ty, discriminant)?;
830 
831         Ok(GenericVariant {
832             discriminant,
833             payload: None,
834             abi: &ty.abi,
835             info: &ty.info,
836         })
837     }
838 
839     fn variant<'a>(
840         ty: &'a TypeVariant,
841         discriminant_name: &str,
842         payload: &'a Option<Box<Val>>,
843     ) -> Result<GenericVariant<'a>> {
844         let (discriminant, payload_ty) = get_variant_discriminant(ty, discriminant_name)?;
845 
846         let payload = match (payload, payload_ty) {
847             (Some(val), Some(ty)) => Some((&**val, *ty)),
848             (None, None) => None,
849             (Some(_), None) => bail!("did not expect a payload for case `{discriminant_name}`"),
850             (None, Some(_)) => bail!("expected a payload for case `{discriminant_name}`"),
851         };
852 
853         Ok(GenericVariant {
854             discriminant,
855             payload,
856             abi: &ty.abi,
857             info: &ty.info,
858         })
859     }
860 
861     fn lower<T>(
862         &self,
863         cx: &mut LowerContext<'_, T>,
864         dst: &mut IterMut<'_, MaybeUninit<ValRaw>>,
865     ) -> Result<()> {
866         next_mut(dst).write(ValRaw::u32(self.discriminant));
867 
868         // For the remaining lowered representation of this variant that
869         // the payload didn't write we write out zeros here to ensure
870         // the entire variant is written.
871         let value_flat = match self.payload {
872             Some((value, ty)) => {
873                 value.lower(cx, ty, dst)?;
874                 cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap()
875             }
876             None => 0,
877         };
878         let variant_flat = self.abi.flat_count(usize::MAX).unwrap();
879         for _ in (1 + value_flat)..variant_flat {
880             next_mut(dst).write(ValRaw::u64(0));
881         }
882         Ok(())
883     }
884 
885     fn store<T>(&self, cx: &mut LowerContext<'_, T>, offset: usize) -> Result<()> {
886         match self.info.size {
887             DiscriminantSize::Size1 => u8::try_from(self.discriminant)
888                 .unwrap()
889                 .linear_lower_to_memory(cx, InterfaceType::U8, offset)?,
890             DiscriminantSize::Size2 => u16::try_from(self.discriminant)
891                 .unwrap()
892                 .linear_lower_to_memory(cx, InterfaceType::U16, offset)?,
893             DiscriminantSize::Size4 => {
894                 self.discriminant
895                     .linear_lower_to_memory(cx, InterfaceType::U32, offset)?
896             }
897         }
898 
899         if let Some((value, ty)) = self.payload {
900             let offset = offset + usize::try_from(self.info.payload_offset32).unwrap();
901             value.store(cx, ty, offset)?;
902         }
903 
904         Ok(())
905     }
906 }
907 
908 fn load_list(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize) -> Result<Val> {
909     let elem = cx.types[ty].element;
910     let abi = cx.types.canonical_abi(&elem);
911     let element_size = usize::try_from(abi.size32).unwrap();
912     let element_alignment = abi.align32;
913 
914     match len
915         .checked_mul(element_size)
916         .and_then(|len| ptr.checked_add(len))
917     {
918         Some(n) if n <= cx.memory().len() => {}
919         _ => bail!("list pointer/length out of bounds of memory"),
920     }
921     if ptr % usize::try_from(element_alignment)? != 0 {
922         bail!("list pointer is not aligned")
923     }
924 
925     Ok(Val::List(
926         (0..len)
927             .map(|index| {
928                 Val::load(
929                     cx,
930                     elem,
931                     &cx.memory()[ptr + (index * element_size)..][..element_size],
932                 )
933             })
934             .collect::<Result<_>>()?,
935     ))
936 }
937 
938 fn load_variant(
939     cx: &mut LiftContext<'_>,
940     info: &VariantInfo,
941     mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
942     bytes: &[u8],
943 ) -> Result<(u32, Option<Box<Val>>)> {
944     let discriminant = match info.size {
945         DiscriminantSize::Size1 => u32::from(u8::linear_lift_from_memory(
946             cx,
947             InterfaceType::U8,
948             &bytes[..1],
949         )?),
950         DiscriminantSize::Size2 => u32::from(u16::linear_lift_from_memory(
951             cx,
952             InterfaceType::U16,
953             &bytes[..2],
954         )?),
955         DiscriminantSize::Size4 => {
956             u32::linear_lift_from_memory(cx, InterfaceType::U32, &bytes[..4])?
957         }
958     };
959     let case_ty = types.nth(discriminant as usize).ok_or_else(|| {
960         anyhow!(
961             "discriminant {} out of range [0..{})",
962             discriminant,
963             types.len()
964         )
965     })?;
966     let value = match case_ty {
967         Some(case_ty) => {
968             let payload_offset = usize::try_from(info.payload_offset32).unwrap();
969             let case_abi = cx.types.canonical_abi(&case_ty);
970             let case_size = usize::try_from(case_abi.size32).unwrap();
971             Some(Box::new(Val::load(
972                 cx,
973                 case_ty,
974                 &bytes[payload_offset..][..case_size],
975             )?))
976         }
977         None => None,
978     };
979     Ok((discriminant, value))
980 }
981 
982 fn lift_variant(
983     cx: &mut LiftContext<'_>,
984     flatten_count: usize,
985     mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
986     src: &mut Iter<'_, ValRaw>,
987 ) -> Result<(u32, Option<Box<Val>>)> {
988     let len = types.len();
989     let discriminant = next(src).get_u32();
990     let ty = types
991         .nth(discriminant as usize)
992         .ok_or_else(|| anyhow!("discriminant {discriminant} out of range [0..{len})"))?;
993     let (value, value_flat) = match ty {
994         Some(ty) => (
995             Some(Box::new(Val::lift(cx, ty, src)?)),
996             cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
997         ),
998         None => (None, 0),
999     };
1000     for _ in (1 + value_flat)..flatten_count {
1001         next(src);
1002     }
1003     Ok((discriminant, value))
1004 }
1005 
1006 /// Lower a list with the specified element type and values.
1007 fn lower_list<T>(
1008     cx: &mut LowerContext<'_, T>,
1009     element_type: InterfaceType,
1010     items: &[Val],
1011 ) -> Result<(usize, usize)> {
1012     let abi = cx.types.canonical_abi(&element_type);
1013     let elt_size = usize::try_from(abi.size32)?;
1014     let elt_align = abi.align32;
1015     let size = items
1016         .len()
1017         .checked_mul(elt_size)
1018         .ok_or_else(|| anyhow::anyhow!("size overflow copying a list"))?;
1019     let ptr = cx.realloc(0, 0, elt_align, size)?;
1020     let mut element_ptr = ptr;
1021     for item in items {
1022         item.store(cx, element_type, element_ptr)?;
1023         element_ptr += elt_size;
1024     }
1025     Ok((ptr, items.len()))
1026 }
1027 
1028 fn push_flags(ty: &TypeFlags, flags: &mut Vec<String>, mut offset: u32, mut bits: u32) {
1029     while bits > 0 {
1030         if bits & 1 != 0 {
1031             flags.push(ty.names[offset as usize].clone());
1032         }
1033         bits >>= 1;
1034         offset += 1;
1035     }
1036 }
1037 
1038 fn flags_to_storage(ty: &TypeFlags, flags: &[String]) -> Result<Vec<u32>> {
1039     let mut storage = match FlagsSize::from_count(ty.names.len()) {
1040         FlagsSize::Size0 => Vec::new(),
1041         FlagsSize::Size1 | FlagsSize::Size2 => vec![0],
1042         FlagsSize::Size4Plus(n) => vec![0; n.into()],
1043     };
1044 
1045     for flag in flags {
1046         let bit = ty
1047             .names
1048             .get_index_of(flag)
1049             .ok_or_else(|| anyhow::anyhow!("unknown flag: `{flag}`"))?;
1050         storage[bit / 32] |= 1 << (bit % 32);
1051     }
1052     Ok(storage)
1053 }
1054 
1055 fn get_enum_discriminant(ty: &TypeEnum, n: &str) -> Result<u32> {
1056     ty.names
1057         .get_index_of(n)
1058         .ok_or_else(|| anyhow::anyhow!("enum variant name `{n}` is not valid"))
1059         .map(|i| i.try_into().unwrap())
1060 }
1061 
1062 fn get_variant_discriminant<'a>(
1063     ty: &'a TypeVariant,
1064     name: &str,
1065 ) -> Result<(u32, &'a Option<InterfaceType>)> {
1066     let (i, _, ty) = ty
1067         .cases
1068         .get_full(name)
1069         .ok_or_else(|| anyhow::anyhow!("unknown variant case: `{name}`"))?;
1070     Ok((i.try_into().unwrap(), ty))
1071 }
1072 
1073 fn next<'a>(src: &mut Iter<'a, ValRaw>) -> &'a ValRaw {
1074     src.next().unwrap()
1075 }
1076 
1077 fn next_mut<'a>(dst: &mut IterMut<'a, MaybeUninit<ValRaw>>) -> &'a mut MaybeUninit<ValRaw> {
1078     dst.next().unwrap()
1079 }
1080 
1081 #[cold]
1082 fn unexpected<T>(ty: InterfaceType, val: &Val) -> Result<T> {
1083     bail!(
1084         "type mismatch: expected {}, found {}",
1085         desc(&ty),
1086         val.desc()
1087     )
1088 }
1089 
1090 /// Represents a component model `error-context`.
1091 ///
1092 /// Note that this type is not usable at this time as its implementation has not
1093 /// been filled out. There are no operations on this and there's additionally no
1094 /// ability to "drop" or deallocate this index.
1095 //
1096 // FIXME(#11161) this needs to be filled out implementation-wise
1097 #[derive(Debug, Clone, PartialEq, Eq)]
1098 pub struct ErrorContextAny(pub(crate) u32);
1099 
1100 impl From<bool> for Val {
1101     fn from(b: bool) -> Self {
1102         Val::Bool(b)
1103     }
1104 }
1105 
1106 impl From<u8> for Val {
1107     fn from(u: u8) -> Self {
1108         Val::U8(u)
1109     }
1110 }
1111 
1112 impl From<i8> for Val {
1113     fn from(i: i8) -> Self {
1114         Val::S8(i)
1115     }
1116 }
1117 
1118 impl From<u16> for Val {
1119     fn from(u: u16) -> Self {
1120         Val::U16(u)
1121     }
1122 }
1123 
1124 impl From<i16> for Val {
1125     fn from(i: i16) -> Self {
1126         Val::S16(i)
1127     }
1128 }
1129 
1130 impl From<u32> for Val {
1131     fn from(u: u32) -> Self {
1132         Val::U32(u)
1133     }
1134 }
1135 
1136 impl From<i32> for Val {
1137     fn from(i: i32) -> Self {
1138         Val::S32(i)
1139     }
1140 }
1141 
1142 impl From<u64> for Val {
1143     fn from(u: u64) -> Self {
1144         Val::U64(u)
1145     }
1146 }
1147 
1148 impl From<i64> for Val {
1149     fn from(i: i64) -> Self {
1150         Val::S64(i)
1151     }
1152 }
1153 
1154 impl From<char> for Val {
1155     fn from(i: char) -> Self {
1156         Val::Char(i)
1157     }
1158 }
1159 
1160 impl From<String> for Val {
1161     fn from(i: String) -> Self {
1162         Val::String(i)
1163     }
1164 }
1165 
1166 impl From<ResourceAny> for Val {
1167     fn from(i: ResourceAny) -> Self {
1168         Val::Resource(i)
1169     }
1170 }
1171 
1172 impl From<FutureAny> for Val {
1173     fn from(i: FutureAny) -> Self {
1174         Val::Future(i)
1175     }
1176 }
1177 
1178 impl From<StreamAny> for Val {
1179     fn from(i: StreamAny) -> Self {
1180         Val::Stream(i)
1181     }
1182 }
1183