1 use crate::component::func::{bad_type_info, Lift, LiftContext, Lower, LowerContext};
2 use crate::component::types::{self, Type};
3 use crate::component::ResourceAny;
4 use crate::ValRaw;
5 use anyhow::{anyhow, bail, Context, Error, Result};
6 use std::collections::HashMap;
7 use std::fmt;
8 use std::iter;
9 use std::mem::MaybeUninit;
10 use std::ops::Deref;
11 use wasmtime_component_util::{DiscriminantSize, FlagsSize};
12 use wasmtime_environ::component::{
13     CanonicalAbiInfo, ComponentTypes, InterfaceType, TypeListIndex, VariantInfo,
14 };
15 
16 /// Dynamic representation of `list<T>` in the component model.
17 ///
18 /// This structure is part of the dynamically-typed [`Val`] which represents
19 /// all possible values in the component model. This is often used in
20 /// conjunction with [`Func::call`](crate::component::Func::call).
21 ///
22 /// Note that `Vec<T>` is also supported for component model lists when
23 /// using [`TypedFunc`](crate::component::TypedFunc).
24 #[derive(PartialEq, Eq, Clone)]
25 pub struct List {
26     ty: types::List,
27     values: Box<[Val]>,
28 }
29 
30 impl List {
31     /// Creates a new list with the specified type with the specified `values`.
32     ///
33     /// # Errors
34     ///
35     /// Returns an error if any value in `values` does not have the element
36     /// type of `ty` specified.
37     pub fn new(ty: &types::List, values: Box<[Val]>) -> Result<Self> {
38         let element_type = ty.ty();
39         for (index, value) in values.iter().enumerate() {
40             element_type
41                 .is_supertype_of(value)
42                 .with_context(|| format!("type mismatch for element {index} of list"))?;
43         }
44 
45         Ok(Self {
46             ty: ty.clone(),
47             values,
48         })
49     }
50 
51     /// Returns the corresponding type of this list
52     pub fn ty(&self) -> &types::List {
53         &self.ty
54     }
55 }
56 
57 impl Deref for List {
58     type Target = [Val];
59 
60     fn deref(&self) -> &[Val] {
61         &self.values
62     }
63 }
64 
65 impl fmt::Debug for List {
66     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67         let mut f = f.debug_list();
68         for val in self.iter() {
69             f.entry(val);
70         }
71         f.finish()
72     }
73 }
74 
75 /// Dynamic representation of `record` in the component model.
76 ///
77 /// This structure is part of the dynamically-typed [`Val`] which represents
78 /// all possible values in the component model. This is often used in
79 /// conjunction with [`Func::call`](crate::component::Func::call).
80 ///
81 /// Note that records can also be mapped to Rust `struct`s through the
82 /// [`#[derive(ComponentType)]`](macro@crate::component::ComponentType) macro
83 /// and using [`TypedFunc`](crate::component::TypedFunc).
84 #[derive(PartialEq, Eq, Clone)]
85 pub struct Record {
86     ty: types::Record,
87     values: Box<[Val]>,
88 }
89 
90 impl Record {
91     /// Creates a new record with the specified `ty` and the `values` for fields.
92     ///
93     /// Note that the `values` specified for fields must list fields in the
94     /// same order that the `ty` lists them in.
95     ///
96     /// # Errors
97     ///
98     /// Returns an error if any of the `values` specified are in the wrong order
99     /// field-wise or have the wrong type relative to what's specified in `ty`.
100     pub fn new<'a>(
101         ty: &types::Record,
102         values: impl IntoIterator<Item = (&'a str, Val)>,
103     ) -> Result<Self> {
104         let mut fields = ty.fields();
105         let expected_len = fields.len();
106         let mut iter = values.into_iter();
107         let mut values = Vec::with_capacity(expected_len);
108         loop {
109             match (fields.next(), iter.next()) {
110                 (Some(field), Some((name, value))) => {
111                     if name == field.name {
112                         field
113                             .ty
114                             .is_supertype_of(&value)
115                             .with_context(|| format!("type mismatch for field {name} of record"))?;
116 
117                         values.push(value);
118                     } else {
119                         bail!("field name mismatch: expected {}; got {name}", field.name)
120                     }
121                 }
122                 (None, Some((_, value))) => values.push(value),
123                 _ => break,
124             }
125         }
126 
127         if values.len() != expected_len {
128             bail!("expected {} value(s); got {}", expected_len, values.len());
129         }
130 
131         Ok(Self {
132             ty: ty.clone(),
133             values: values.into(),
134         })
135     }
136 
137     /// Returns the corresponding type of this record.
138     pub fn ty(&self) -> &types::Record {
139         &self.ty
140     }
141 
142     /// Returns the list of fields that this struct contains with their name
143     /// and value.
144     pub fn fields(&self) -> impl ExactSizeIterator<Item = (&str, &Val)> {
145         assert_eq!(self.values.len(), self.ty.fields().len());
146         self.ty
147             .fields()
148             .zip(self.values.iter())
149             .map(|(ty, val)| (ty.name, val))
150     }
151 }
152 
153 impl fmt::Debug for Record {
154     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155         let mut f = f.debug_struct("Record");
156         for (name, val) in self.fields() {
157             f.field(name, val);
158         }
159         f.finish()
160     }
161 }
162 
163 /// Dynamic representation of `tuple<...>` in the component model.
164 ///
165 /// This structure is part of the dynamically-typed [`Val`] which represents
166 /// all possible values in the component model. This is often used in
167 /// conjunction with [`Func::call`](crate::component::Func::call).
168 ///
169 /// Note that tuples are also mapped to Rust tuples when using
170 /// [`TypedFunc`](crate::component::TypedFunc).
171 #[derive(PartialEq, Eq, Clone)]
172 pub struct Tuple {
173     ty: types::Tuple,
174     values: Box<[Val]>,
175 }
176 
177 impl Tuple {
178     /// Creates a new tuple with the `ty` specified and `values` for each
179     /// entry.
180     ///
181     /// # Errors
182     ///
183     /// Returns an error if `values` does not match the `ty` specified, such as
184     /// if it has the wrong length or if any field has the wrong type.
185     pub fn new(ty: &types::Tuple, values: Box<[Val]>) -> Result<Self> {
186         if values.len() != ty.types().len() {
187             bail!(
188                 "expected {} value(s); got {}",
189                 ty.types().len(),
190                 values.len()
191             );
192         }
193 
194         for (index, (value, ty)) in values.iter().zip(ty.types()).enumerate() {
195             ty.is_supertype_of(value)
196                 .with_context(|| format!("type mismatch for field {index} of tuple"))?;
197         }
198 
199         Ok(Self {
200             ty: ty.clone(),
201             values,
202         })
203     }
204 
205     /// Returns the type of this tuple.
206     pub fn ty(&self) -> &types::Tuple {
207         &self.ty
208     }
209 
210     /// Returns the list of values that this tuple contains.
211     pub fn values(&self) -> &[Val] {
212         &self.values
213     }
214 }
215 
216 impl fmt::Debug for Tuple {
217     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218         let mut tuple = f.debug_tuple("");
219         for val in self.values() {
220             tuple.field(val);
221         }
222         tuple.finish()
223     }
224 }
225 
226 /// Dynamic representation of `variant` in the component model.
227 ///
228 /// This structure is part of the dynamically-typed [`Val`] which represents
229 /// all possible values in the component model. This is often used in
230 /// conjunction with [`Func::call`](crate::component::Func::call).
231 ///
232 /// Note that variants can also be mapped to Rust `enum`s through the
233 /// [`#[derive(ComponentType)]`](macro@crate::component::ComponentType) macro
234 /// and using [`TypedFunc`](crate::component::TypedFunc).
235 #[derive(PartialEq, Eq, Clone)]
236 pub struct Variant {
237     ty: types::Variant,
238     discriminant: u32,
239     value: Option<Box<Val>>,
240 }
241 
242 impl Variant {
243     /// Creates a new variant with the specified `ty` and the case `name` and
244     /// `value` provided.
245     ///
246     /// This will create a instance of a variant with the case `name` which has
247     /// the optional payload of `value`.
248     ///
249     /// # Errors
250     ///
251     /// Returns an error if `name` doesn't match any case of `ty` or if
252     /// `value` is of the wrong type. Note that `ty` must match the payload
253     /// type exactly, in that if the case for `name` doesn't have a type then
254     /// `value` must be `None`.
255     pub fn new(ty: &types::Variant, name: &str, value: Option<Val>) -> Result<Self> {
256         let (discriminant, case_type) = ty
257             .cases()
258             .enumerate()
259             .find_map(|(index, case)| {
260                 if case.name == name {
261                     Some((index, case.ty))
262                 } else {
263                     None
264                 }
265             })
266             .ok_or_else(|| anyhow!("unknown variant case: {name}"))?;
267 
268         typecheck_payload(name, case_type.as_ref(), value.as_ref())?;
269 
270         Ok(Self {
271             ty: ty.clone(),
272             discriminant: u32::try_from(discriminant)?,
273             value: value.map(Box::new),
274         })
275     }
276 
277     /// Returns the type of this variant.
278     pub fn ty(&self) -> &types::Variant {
279         &self.ty
280     }
281 
282     /// Returns name of the discriminant of this value within the variant type.
283     pub fn discriminant(&self) -> &str {
284         self.ty
285             .cases()
286             .nth(self.discriminant as usize)
287             .unwrap()
288             .name
289     }
290 
291     /// Returns the payload value for this variant.
292     pub fn payload(&self) -> Option<&Val> {
293         self.value.as_deref()
294     }
295 
296     fn as_generic<'a>(
297         &'a self,
298         types: &'a ComponentTypes,
299         ty: InterfaceType,
300     ) -> GenericVariant<'a> {
301         let ty = match ty {
302             InterfaceType::Variant(i) => &types[i],
303             _ => bad_type_info(),
304         };
305         GenericVariant {
306             discriminant: self.discriminant,
307             abi: &ty.abi,
308             info: &ty.info,
309             payload: self
310                 .value
311                 .as_deref()
312                 .zip(ty.cases[self.discriminant as usize].ty),
313         }
314     }
315 }
316 
317 fn typecheck_payload(name: &str, case_type: Option<&Type>, value: Option<&Val>) -> Result<()> {
318     match (case_type, value) {
319         (Some(expected), Some(actual)) => expected
320             .is_supertype_of(&actual)
321             .with_context(|| format!("type mismatch for case {name} of variant")),
322         (None, None) => Ok(()),
323         (Some(_), None) => bail!("expected a payload for case `{name}`"),
324         (None, Some(_)) => bail!("did not expect payload for case `{name}`"),
325     }
326 }
327 
328 impl fmt::Debug for Variant {
329     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330         f.debug_tuple(self.discriminant())
331             .field(&self.payload())
332             .finish()
333     }
334 }
335 
336 /// Dynamic representation of `enum` in the component model.
337 ///
338 /// This structure is part of the dynamically-typed [`Val`] which represents
339 /// all possible values in the component model. This is often used in
340 /// conjunction with [`Func::call`](crate::component::Func::call).
341 ///
342 /// Note that enums can also be mapped to Rust `enum`s through the
343 /// [`#[derive(ComponentType)]`](macro@crate::component::ComponentType) macro
344 /// and using [`TypedFunc`](crate::component::TypedFunc).
345 #[derive(PartialEq, Eq, Clone)]
346 pub struct Enum {
347     ty: types::Enum,
348     discriminant: u32,
349 }
350 
351 impl Enum {
352     /// Creates a new enum value with the `ty` specified selecting the
353     /// specified variant called `name`.
354     ///
355     /// # Errors
356     ///
357     /// Returns an error if `name` isn't listed within `ty`.
358     pub fn new(ty: &types::Enum, name: &str) -> Result<Self> {
359         let discriminant = u32::try_from(
360             ty.names()
361                 .position(|n| n == name)
362                 .ok_or_else(|| anyhow!("unknown enum case: {name}"))?,
363         )?;
364 
365         Ok(Self {
366             ty: ty.clone(),
367             discriminant,
368         })
369     }
370 
371     /// Returns the type of this value.
372     pub fn ty(&self) -> &types::Enum {
373         &self.ty
374     }
375 
376     /// Returns name of this enum value.
377     pub fn discriminant(&self) -> &str {
378         self.ty.names().nth(self.discriminant as usize).unwrap()
379     }
380 
381     fn as_generic<'a>(
382         &'a self,
383         types: &'a ComponentTypes,
384         ty: InterfaceType,
385     ) -> GenericVariant<'a> {
386         let ty = match ty {
387             InterfaceType::Enum(i) => &types[i],
388             _ => bad_type_info(),
389         };
390         GenericVariant {
391             discriminant: self.discriminant,
392             abi: &ty.abi,
393             info: &ty.info,
394             payload: None,
395         }
396     }
397 }
398 
399 impl fmt::Debug for Enum {
400     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401         fmt::Display::fmt(&self.discriminant(), f)
402     }
403 }
404 
405 /// Dynamic representation of `option<T>` in the component model.
406 ///
407 /// This structure is part of the dynamically-typed [`Val`] which represents
408 /// all possible values in the component model. This is often used in
409 /// conjunction with [`Func::call`](crate::component::Func::call).
410 ///
411 /// Note that options are also mapped to Rust `Option<T>` when using
412 /// [`TypedFunc`](crate::component::TypedFunc).
413 #[derive(PartialEq, Eq, Clone)]
414 pub struct OptionVal {
415     ty: types::OptionType,
416     discriminant: u32,
417     value: Option<Box<Val>>,
418 }
419 
420 impl OptionVal {
421     /// Creates a new value with the `ty` specified holding the payload `value`.
422     ///
423     /// # Errors
424     ///
425     /// Returns an error if `value` is `Some` and the payload has the wrong
426     /// type for `ty`.
427     pub fn new(ty: &types::OptionType, value: Option<Val>) -> Result<Self> {
428         let value = value
429             .map(|value| {
430                 ty.ty()
431                     .is_supertype_of(&value)
432                     .context("type mismatch for option")?;
433 
434                 Ok::<_, Error>(value)
435             })
436             .transpose()?;
437 
438         Ok(Self {
439             ty: ty.clone(),
440             discriminant: if value.is_none() { 0 } else { 1 },
441             value: value.map(Box::new),
442         })
443     }
444 
445     /// Returns the type of this value.
446     pub fn ty(&self) -> &types::OptionType {
447         &self.ty
448     }
449 
450     /// Returns the optional value contained within.
451     pub fn value(&self) -> Option<&Val> {
452         self.value.as_deref()
453     }
454 
455     fn as_generic<'a>(
456         &'a self,
457         types: &'a ComponentTypes,
458         ty: InterfaceType,
459     ) -> GenericVariant<'a> {
460         let ty = match ty {
461             InterfaceType::Option(i) => &types[i],
462             _ => bad_type_info(),
463         };
464         GenericVariant {
465             discriminant: self.discriminant,
466             abi: &ty.abi,
467             info: &ty.info,
468             payload: self.value.as_deref().zip(Some(ty.ty)),
469         }
470     }
471 }
472 
473 impl fmt::Debug for OptionVal {
474     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
475         self.value().fmt(f)
476     }
477 }
478 
479 /// Dynamic representation of `result<T, E>` in the component model.
480 ///
481 /// This structure is part of the dynamically-typed [`Val`] which represents
482 /// all possible values in the component model. This is often used in
483 /// conjunction with [`Func::call`](crate::component::Func::call).
484 ///
485 /// Note that tuples are also mapped to Rust's `Result<T, E>` when using
486 /// [`TypedFunc`](crate::component::TypedFunc).
487 #[derive(PartialEq, Eq, Clone)]
488 pub struct ResultVal {
489     ty: types::ResultType,
490     discriminant: u32,
491     value: Option<Box<Val>>,
492 }
493 
494 impl ResultVal {
495     /// Creates a new `Result` from the specified `ty` and `value`.
496     ///
497     /// Note that the `value` uses `Option<Val>` for payloads to map to the
498     /// optional payload value of the component model within each variant.
499     ///
500     /// # Errors
501     ///
502     /// Returns an error if the `value` payload has the wrong type for `ty`.
503     pub fn new(ty: &types::ResultType, value: Result<Option<Val>, Option<Val>>) -> Result<Self> {
504         Ok(Self {
505             ty: ty.clone(),
506             discriminant: if value.is_ok() { 0 } else { 1 },
507             value: match value {
508                 Ok(value) => {
509                     typecheck_payload("ok", ty.ok().as_ref(), value.as_ref())?;
510                     value.map(Box::new)
511                 }
512                 Err(value) => {
513                     typecheck_payload("err", ty.err().as_ref(), value.as_ref())?;
514                     value.map(Box::new)
515                 }
516             },
517         })
518     }
519 
520     /// Returns the type of this value.
521     pub fn ty(&self) -> &types::ResultType {
522         &self.ty
523     }
524 
525     /// Returns the result value contained within.
526     pub fn value(&self) -> Result<Option<&Val>, Option<&Val>> {
527         if self.discriminant == 0 {
528             Ok(self.value.as_deref())
529         } else {
530             Err(self.value.as_deref())
531         }
532     }
533 
534     fn as_generic<'a>(
535         &'a self,
536         types: &'a ComponentTypes,
537         ty: InterfaceType,
538     ) -> GenericVariant<'a> {
539         let ty = match ty {
540             InterfaceType::Result(i) => &types[i],
541             _ => bad_type_info(),
542         };
543         GenericVariant {
544             discriminant: self.discriminant,
545             abi: &ty.abi,
546             info: &ty.info,
547             payload: self.value.as_deref().zip(if self.discriminant == 0 {
548                 ty.ok
549             } else {
550                 ty.err
551             }),
552         }
553     }
554 }
555 
556 impl fmt::Debug for ResultVal {
557     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
558         self.value().fmt(f)
559     }
560 }
561 
562 /// Dynamic representation of `flags` in the component model.
563 ///
564 /// This structure is part of the dynamically-typed [`Val`] which represents
565 /// all possible values in the component model. This is often used in
566 /// conjunction with [`Func::call`](crate::component::Func::call).
567 ///
568 /// Note that flags can also be mapped to Rust structures through the
569 /// [`flags!`](crate::component::flags) macro and using
570 /// [`TypedFunc`](crate::component::TypedFunc).
571 #[derive(PartialEq, Eq, Clone)]
572 pub struct Flags {
573     ty: types::Flags,
574     count: u32,
575     value: Box<[u32]>,
576 }
577 
578 impl Flags {
579     /// Creates a new set of flags with the `ty` specified and the `names` as
580     /// members of the flags.
581     ///
582     /// # Errors
583     ///
584     /// An error is returned if any of `names` aren't present within the `ty`
585     /// specified.
586     pub fn new(ty: &types::Flags, names: &[&str]) -> Result<Self> {
587         let map = ty
588             .names()
589             .enumerate()
590             .map(|(index, name)| (name, index))
591             .collect::<HashMap<_, _>>();
592 
593         let count = usize::from(ty.canonical_abi().flat_count.unwrap());
594         let mut values = vec![0_u32; count];
595 
596         for name in names {
597             let index = map
598                 .get(name)
599                 .ok_or_else(|| anyhow!("unknown flag: {name}"))?;
600             values[index / 32] |= 1 << (index % 32);
601         }
602 
603         Ok(Self {
604             ty: ty.clone(),
605             count: u32::try_from(map.len())?,
606             value: values.into(),
607         })
608     }
609 
610     /// Returns the type of this value.
611     pub fn ty(&self) -> &types::Flags {
612         &self.ty
613     }
614 
615     /// Returns an iterator over the set of names that this flags set contains.
616     pub fn flags(&self) -> impl Iterator<Item = &str> {
617         (0..self.count).filter_map(|i| {
618             let (idx, bit) = ((i / 32) as usize, i % 32);
619             if self.value[idx] & (1 << bit) != 0 {
620                 Some(self.ty.names().nth(i as usize).unwrap())
621             } else {
622                 None
623             }
624         })
625     }
626 }
627 
628 impl fmt::Debug for Flags {
629     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630         let mut set = f.debug_set();
631         for flag in self.flags() {
632             set.entry(&flag);
633         }
634         set.finish()
635     }
636 }
637 
638 /// Represents possible runtime values which a component function can either
639 /// consume or produce
640 ///
641 /// This is a dynamic representation of possible values in the component model.
642 /// Note that this is not an efficient representation but is instead intended to
643 /// be a flexible and somewhat convenient representation. The most efficient
644 /// representation of component model types is to use the `bindgen!` macro to
645 /// generate native Rust types with specialized liftings and lowerings.
646 ///
647 /// This type is used in conjunction with [`Func::call`] for example if the
648 /// signature of a component is not statically known ahead of time.
649 ///
650 /// # Notes on Equality
651 ///
652 /// This type implements both the Rust `PartialEq` and `Eq` traits. This type
653 /// additionally contains values which are not necessarily easily equated,
654 /// however, such as floats (`Float32` and `Float64`) and resources. Equality
655 /// does require that two values have the same type, and then these cases are
656 /// handled as:
657 ///
658 /// * Floats are tested if they are "semantically the same" meaning all NaN
659 ///   values are equal to all other NaN values. Additionally zero values must be
660 ///   exactly the same, so positive zero is not equal to negative zero. The
661 ///   primary use case at this time is fuzzing-related equality which this is
662 ///   sufficient for.
663 ///
664 /// * Resources are tested if their types and indices into the host table are
665 ///   equal. This does not compare the underlying representation so borrows of
666 ///   the same guest resource are not considered equal. This additionally
667 ///   doesn't go further and test for equality in the guest itself (for example
668 ///   two different heap allocations of `Box<u32>` can be equal in normal Rust
669 ///   if they contain the same value, but will never be considered equal when
670 ///   compared as `Val::Resource`s).
671 ///
672 /// In general if a strict guarantee about equality is required here it's
673 /// recommended to "build your own" as this equality intended for fuzzing
674 /// Wasmtime may not be suitable for you.
675 ///
676 /// [`Func::call`]: crate::component::Func::call
677 #[derive(Debug, Clone)]
678 #[allow(missing_docs)]
679 pub enum Val {
680     Bool(bool),
681     S8(i8),
682     U8(u8),
683     S16(i16),
684     U16(u16),
685     S32(i32),
686     U32(u32),
687     S64(i64),
688     U64(u64),
689     Float32(f32),
690     Float64(f64),
691     Char(char),
692     String(Box<str>),
693     List(List),
694     Record(Record),
695     Tuple(Tuple),
696     Variant(Variant),
697     Enum(Enum),
698     Option(OptionVal),
699     Result(ResultVal),
700     Flags(Flags),
701     Resource(ResourceAny),
702 }
703 
704 impl Val {
705     /// Retrieve the [`Type`] of this value.
706     pub fn ty(&self) -> Type {
707         match self {
708             Val::Bool(_) => Type::Bool,
709             Val::S8(_) => Type::S8,
710             Val::U8(_) => Type::U8,
711             Val::S16(_) => Type::S16,
712             Val::U16(_) => Type::U16,
713             Val::S32(_) => Type::S32,
714             Val::U32(_) => Type::U32,
715             Val::S64(_) => Type::S64,
716             Val::U64(_) => Type::U64,
717             Val::Float32(_) => Type::Float32,
718             Val::Float64(_) => Type::Float64,
719             Val::Char(_) => Type::Char,
720             Val::String(_) => Type::String,
721             Val::List(List { ty, .. }) => Type::List(ty.clone()),
722             Val::Record(Record { ty, .. }) => Type::Record(ty.clone()),
723             Val::Tuple(Tuple { ty, .. }) => Type::Tuple(ty.clone()),
724             Val::Variant(Variant { ty, .. }) => Type::Variant(ty.clone()),
725             Val::Enum(Enum { ty, .. }) => Type::Enum(ty.clone()),
726             Val::Option(OptionVal { ty, .. }) => Type::Option(ty.clone()),
727             Val::Result(ResultVal { ty, .. }) => Type::Result(ty.clone()),
728             Val::Flags(Flags { ty, .. }) => Type::Flags(ty.clone()),
729             Val::Resource(r) => {
730                 if r.owned() {
731                     Type::Own(r.ty())
732                 } else {
733                     Type::Borrow(r.ty())
734                 }
735             }
736         }
737     }
738 
739     /// Deserialize a value of this type from core Wasm stack values.
740     pub(crate) fn lift(
741         cx: &mut LiftContext<'_>,
742         ty: InterfaceType,
743         src: &mut std::slice::Iter<'_, ValRaw>,
744     ) -> Result<Val> {
745         Ok(match ty {
746             InterfaceType::Bool => Val::Bool(bool::lift(cx, ty, next(src))?),
747             InterfaceType::S8 => Val::S8(i8::lift(cx, ty, next(src))?),
748             InterfaceType::U8 => Val::U8(u8::lift(cx, ty, next(src))?),
749             InterfaceType::S16 => Val::S16(i16::lift(cx, ty, next(src))?),
750             InterfaceType::U16 => Val::U16(u16::lift(cx, ty, next(src))?),
751             InterfaceType::S32 => Val::S32(i32::lift(cx, ty, next(src))?),
752             InterfaceType::U32 => Val::U32(u32::lift(cx, ty, next(src))?),
753             InterfaceType::S64 => Val::S64(i64::lift(cx, ty, next(src))?),
754             InterfaceType::U64 => Val::U64(u64::lift(cx, ty, next(src))?),
755             InterfaceType::Float32 => Val::Float32(f32::lift(cx, ty, next(src))?),
756             InterfaceType::Float64 => Val::Float64(f64::lift(cx, ty, next(src))?),
757             InterfaceType::Char => Val::Char(char::lift(cx, ty, next(src))?),
758             InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
759                 Val::Resource(ResourceAny::lift(cx, ty, next(src))?)
760             }
761             InterfaceType::String => {
762                 Val::String(Box::<str>::lift(cx, ty, &[*next(src), *next(src)])?)
763             }
764             InterfaceType::List(i) => {
765                 // FIXME: needs memory64 treatment
766                 let ptr = u32::lift(cx, InterfaceType::U32, next(src))? as usize;
767                 let len = u32::lift(cx, InterfaceType::U32, next(src))? as usize;
768                 load_list(cx, i, ptr, len)?
769             }
770             InterfaceType::Record(i) => Val::Record(Record {
771                 ty: types::Record::from(i, &cx.instance_type()),
772                 values: cx.types[i]
773                     .fields
774                     .iter()
775                     .map(|field| Self::lift(cx, field.ty, src))
776                     .collect::<Result<_>>()?,
777             }),
778             InterfaceType::Tuple(i) => Val::Tuple(Tuple {
779                 ty: types::Tuple::from(i, &cx.instance_type()),
780                 values: cx.types[i]
781                     .types
782                     .iter()
783                     .map(|ty| Self::lift(cx, *ty, src))
784                     .collect::<Result<_>>()?,
785             }),
786             InterfaceType::Variant(i) => {
787                 let (discriminant, value) = lift_variant(
788                     cx,
789                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
790                     cx.types[i].cases.iter().map(|case| case.ty),
791                     src,
792                 )?;
793 
794                 Val::Variant(Variant {
795                     ty: types::Variant::from(i, &cx.instance_type()),
796                     discriminant,
797                     value,
798                 })
799             }
800             InterfaceType::Enum(i) => {
801                 let (discriminant, _) = lift_variant(
802                     cx,
803                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
804                     cx.types[i].names.iter().map(|_| None),
805                     src,
806                 )?;
807 
808                 Val::Enum(Enum {
809                     ty: types::Enum::from(i, &cx.instance_type()),
810                     discriminant,
811                 })
812             }
813             InterfaceType::Option(i) => {
814                 let (discriminant, value) = lift_variant(
815                     cx,
816                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
817                     [None, Some(cx.types[i].ty)].into_iter(),
818                     src,
819                 )?;
820 
821                 Val::Option(OptionVal {
822                     ty: types::OptionType::from(i, &cx.instance_type()),
823                     discriminant,
824                     value,
825                 })
826             }
827             InterfaceType::Result(i) => {
828                 let result_ty = &cx.types[i];
829                 let (discriminant, value) = lift_variant(
830                     cx,
831                     cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
832                     [result_ty.ok, result_ty.err].into_iter(),
833                     src,
834                 )?;
835 
836                 Val::Result(ResultVal {
837                     ty: types::ResultType::from(i, &cx.instance_type()),
838                     discriminant,
839                     value,
840                 })
841             }
842             InterfaceType::Flags(i) => {
843                 let count = u32::try_from(cx.types[i].names.len()).unwrap();
844                 let u32_count = cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap();
845                 let value = iter::repeat_with(|| u32::lift(cx, InterfaceType::U32, next(src)))
846                     .take(u32_count)
847                     .collect::<Result<_>>()?;
848 
849                 Val::Flags(Flags {
850                     ty: types::Flags::from(i, &cx.instance_type()),
851                     count,
852                     value,
853                 })
854             }
855         })
856     }
857 
858     /// Deserialize a value of this type from the heap.
859     pub(crate) fn load(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Val> {
860         Ok(match ty {
861             InterfaceType::Bool => Val::Bool(bool::load(cx, ty, bytes)?),
862             InterfaceType::S8 => Val::S8(i8::load(cx, ty, bytes)?),
863             InterfaceType::U8 => Val::U8(u8::load(cx, ty, bytes)?),
864             InterfaceType::S16 => Val::S16(i16::load(cx, ty, bytes)?),
865             InterfaceType::U16 => Val::U16(u16::load(cx, ty, bytes)?),
866             InterfaceType::S32 => Val::S32(i32::load(cx, ty, bytes)?),
867             InterfaceType::U32 => Val::U32(u32::load(cx, ty, bytes)?),
868             InterfaceType::S64 => Val::S64(i64::load(cx, ty, bytes)?),
869             InterfaceType::U64 => Val::U64(u64::load(cx, ty, bytes)?),
870             InterfaceType::Float32 => Val::Float32(f32::load(cx, ty, bytes)?),
871             InterfaceType::Float64 => Val::Float64(f64::load(cx, ty, bytes)?),
872             InterfaceType::Char => Val::Char(char::load(cx, ty, bytes)?),
873             InterfaceType::String => Val::String(<Box<str>>::load(cx, ty, bytes)?),
874             InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
875                 Val::Resource(ResourceAny::load(cx, ty, bytes)?)
876             }
877             InterfaceType::List(i) => {
878                 // FIXME: needs memory64 treatment
879                 let ptr = u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize;
880                 let len = u32::from_le_bytes(bytes[4..].try_into().unwrap()) as usize;
881                 load_list(cx, i, ptr, len)?
882             }
883 
884             InterfaceType::Record(i) => Val::Record(Record {
885                 ty: types::Record::from(i, &cx.instance_type()),
886                 values: load_record(cx, cx.types[i].fields.iter().map(|field| field.ty), bytes)?,
887             }),
888             InterfaceType::Tuple(i) => Val::Tuple(Tuple {
889                 ty: types::Tuple::from(i, &cx.instance_type()),
890                 values: load_record(cx, cx.types[i].types.iter().copied(), bytes)?,
891             }),
892             InterfaceType::Variant(i) => {
893                 let ty = &cx.types[i];
894                 let (discriminant, value) =
895                     load_variant(cx, &ty.info, ty.cases.iter().map(|case| case.ty), bytes)?;
896 
897                 Val::Variant(Variant {
898                     ty: types::Variant::from(i, &cx.instance_type()),
899                     discriminant,
900                     value,
901                 })
902             }
903             InterfaceType::Enum(i) => {
904                 let ty = &cx.types[i];
905                 let (discriminant, _) =
906                     load_variant(cx, &ty.info, ty.names.iter().map(|_| None), bytes)?;
907 
908                 Val::Enum(Enum {
909                     ty: types::Enum::from(i, &cx.instance_type()),
910                     discriminant,
911                 })
912             }
913             InterfaceType::Option(i) => {
914                 let ty = &cx.types[i];
915                 let (discriminant, value) =
916                     load_variant(cx, &ty.info, [None, Some(ty.ty)].into_iter(), bytes)?;
917 
918                 Val::Option(OptionVal {
919                     ty: types::OptionType::from(i, &cx.instance_type()),
920                     discriminant,
921                     value,
922                 })
923             }
924             InterfaceType::Result(i) => {
925                 let ty = &cx.types[i];
926                 let (discriminant, value) =
927                     load_variant(cx, &ty.info, [ty.ok, ty.err].into_iter(), bytes)?;
928 
929                 Val::Result(ResultVal {
930                     ty: types::ResultType::from(i, &cx.instance_type()),
931                     discriminant,
932                     value,
933                 })
934             }
935             InterfaceType::Flags(i) => Val::Flags(Flags {
936                 ty: types::Flags::from(i, &cx.instance_type()),
937                 count: u32::try_from(cx.types[i].names.len())?,
938                 value: match FlagsSize::from_count(cx.types[i].names.len()) {
939                     FlagsSize::Size0 => Box::new([]),
940                     FlagsSize::Size1 => {
941                         iter::once(u8::load(cx, InterfaceType::U8, bytes)?.into()).collect()
942                     }
943                     FlagsSize::Size2 => {
944                         iter::once(u16::load(cx, InterfaceType::U16, bytes)?.into()).collect()
945                     }
946                     FlagsSize::Size4Plus(n) => (0..n)
947                         .map(|index| {
948                             u32::load(
949                                 cx,
950                                 InterfaceType::U32,
951                                 &bytes[usize::from(index) * 4..][..4],
952                             )
953                         })
954                         .collect::<Result<_>>()?,
955                 },
956             }),
957         })
958     }
959 
960     /// Serialize this value as core Wasm stack values.
961     pub(crate) fn lower<T>(
962         &self,
963         cx: &mut LowerContext<'_, T>,
964         ty: InterfaceType,
965         dst: &mut std::slice::IterMut<'_, MaybeUninit<ValRaw>>,
966     ) -> Result<()> {
967         match self {
968             Val::Bool(value) => value.lower(cx, ty, next_mut(dst))?,
969             Val::S8(value) => value.lower(cx, ty, next_mut(dst))?,
970             Val::U8(value) => value.lower(cx, ty, next_mut(dst))?,
971             Val::S16(value) => value.lower(cx, ty, next_mut(dst))?,
972             Val::U16(value) => value.lower(cx, ty, next_mut(dst))?,
973             Val::S32(value) => value.lower(cx, ty, next_mut(dst))?,
974             Val::U32(value) => value.lower(cx, ty, next_mut(dst))?,
975             Val::S64(value) => value.lower(cx, ty, next_mut(dst))?,
976             Val::U64(value) => value.lower(cx, ty, next_mut(dst))?,
977             Val::Float32(value) => value.lower(cx, ty, next_mut(dst))?,
978             Val::Float64(value) => value.lower(cx, ty, next_mut(dst))?,
979             Val::Char(value) => value.lower(cx, ty, next_mut(dst))?,
980             Val::Resource(value) => value.lower(cx, ty, next_mut(dst))?,
981             Val::String(value) => {
982                 let my_dst = &mut MaybeUninit::<[ValRaw; 2]>::uninit();
983                 value.lower(cx, ty, my_dst)?;
984                 let my_dst = unsafe { my_dst.assume_init() };
985                 next_mut(dst).write(my_dst[0]);
986                 next_mut(dst).write(my_dst[1]);
987             }
988             Val::List(List { values, .. }) => {
989                 let ty = match ty {
990                     InterfaceType::List(i) => &cx.types[i],
991                     _ => bad_type_info(),
992                 };
993                 let (ptr, len) = lower_list(cx, ty.element, values)?;
994                 next_mut(dst).write(ValRaw::i64(ptr as i64));
995                 next_mut(dst).write(ValRaw::i64(len as i64));
996             }
997             Val::Record(Record { values, .. }) => {
998                 let ty = match ty {
999                     InterfaceType::Record(i) => &cx.types[i],
1000                     _ => bad_type_info(),
1001                 };
1002                 for (value, field) in values.iter().zip(ty.fields.iter()) {
1003                     value.lower(cx, field.ty, dst)?;
1004                 }
1005             }
1006             Val::Tuple(Tuple { values, .. }) => {
1007                 let ty = match ty {
1008                     InterfaceType::Tuple(i) => &cx.types[i],
1009                     _ => bad_type_info(),
1010                 };
1011                 for (value, ty) in values.iter().zip(ty.types.iter()) {
1012                     value.lower(cx, *ty, dst)?;
1013                 }
1014             }
1015             Val::Variant(v) => v.as_generic(cx.types, ty).lower(cx, dst)?,
1016             Val::Option(v) => v.as_generic(cx.types, ty).lower(cx, dst)?,
1017             Val::Result(v) => v.as_generic(cx.types, ty).lower(cx, dst)?,
1018             Val::Enum(Enum { discriminant, .. }) => {
1019                 next_mut(dst).write(ValRaw::u32(*discriminant));
1020             }
1021             Val::Flags(Flags { value, .. }) => {
1022                 for value in value.deref() {
1023                     next_mut(dst).write(ValRaw::u32(*value));
1024                 }
1025             }
1026         }
1027 
1028         Ok(())
1029     }
1030 
1031     /// Serialize this value to the heap at the specified memory location.
1032     pub(crate) fn store<T>(
1033         &self,
1034         cx: &mut LowerContext<'_, T>,
1035         ty: InterfaceType,
1036         offset: usize,
1037     ) -> Result<()> {
1038         debug_assert!(offset % usize::try_from(cx.types.canonical_abi(&ty).align32)? == 0);
1039 
1040         match self {
1041             Val::Bool(value) => value.store(cx, ty, offset)?,
1042             Val::U8(value) => value.store(cx, ty, offset)?,
1043             Val::S8(value) => value.store(cx, ty, offset)?,
1044             Val::U16(value) => value.store(cx, ty, offset)?,
1045             Val::S16(value) => value.store(cx, ty, offset)?,
1046             Val::U32(value) => value.store(cx, ty, offset)?,
1047             Val::S32(value) => value.store(cx, ty, offset)?,
1048             Val::U64(value) => value.store(cx, ty, offset)?,
1049             Val::S64(value) => value.store(cx, ty, offset)?,
1050             Val::Float32(value) => value.store(cx, ty, offset)?,
1051             Val::Float64(value) => value.store(cx, ty, offset)?,
1052             Val::Char(value) => value.store(cx, ty, offset)?,
1053             Val::String(value) => value.store(cx, ty, offset)?,
1054             Val::Resource(value) => value.store(cx, ty, offset)?,
1055             Val::List(List { values, .. }) => {
1056                 let ty = match ty {
1057                     InterfaceType::List(i) => &cx.types[i],
1058                     _ => bad_type_info(),
1059                 };
1060                 let (ptr, len) = lower_list(cx, ty.element, values)?;
1061                 // FIXME: needs memory64 handling
1062                 *cx.get(offset + 0) = (ptr as i32).to_le_bytes();
1063                 *cx.get(offset + 4) = (len as i32).to_le_bytes();
1064             }
1065             Val::Record(Record { values, .. }) => {
1066                 let ty = match ty {
1067                     InterfaceType::Record(i) => &cx.types[i],
1068                     _ => bad_type_info(),
1069                 };
1070                 let mut offset = offset;
1071                 for (value, field) in values.iter().zip(ty.fields.iter()) {
1072                     value.store(
1073                         cx,
1074                         field.ty,
1075                         cx.types
1076                             .canonical_abi(&field.ty)
1077                             .next_field32_size(&mut offset),
1078                     )?;
1079                 }
1080             }
1081             Val::Tuple(Tuple { values, .. }) => {
1082                 let ty = match ty {
1083                     InterfaceType::Tuple(i) => &cx.types[i],
1084                     _ => bad_type_info(),
1085                 };
1086                 let mut offset = offset;
1087                 for (value, ty) in values.iter().zip(ty.types.iter()) {
1088                     value.store(
1089                         cx,
1090                         *ty,
1091                         cx.types.canonical_abi(ty).next_field32_size(&mut offset),
1092                     )?;
1093                 }
1094             }
1095 
1096             Val::Variant(v) => v.as_generic(cx.types, ty).store(cx, offset)?,
1097             Val::Enum(v) => v.as_generic(cx.types, ty).store(cx, offset)?,
1098             Val::Option(v) => v.as_generic(cx.types, ty).store(cx, offset)?,
1099             Val::Result(v) => v.as_generic(cx.types, ty).store(cx, offset)?,
1100 
1101             Val::Flags(Flags { count, value, .. }) => {
1102                 match FlagsSize::from_count(*count as usize) {
1103                     FlagsSize::Size0 => {}
1104                     FlagsSize::Size1 => {
1105                         u8::try_from(value[0])
1106                             .unwrap()
1107                             .store(cx, InterfaceType::U8, offset)?
1108                     }
1109                     FlagsSize::Size2 => {
1110                         u16::try_from(value[0])
1111                             .unwrap()
1112                             .store(cx, InterfaceType::U16, offset)?
1113                     }
1114                     FlagsSize::Size4Plus(_) => {
1115                         let mut offset = offset;
1116                         for value in value.deref() {
1117                             value.store(cx, InterfaceType::U32, offset)?;
1118                             offset += 4;
1119                         }
1120                     }
1121                 }
1122             }
1123         }
1124 
1125         Ok(())
1126     }
1127 }
1128 
1129 impl PartialEq for Val {
1130     fn eq(&self, other: &Self) -> bool {
1131         match (self, other) {
1132             // IEEE 754 equality considers NaN inequal to NaN and negative zero
1133             // equal to positive zero, however we do the opposite here, because
1134             // this logic is used by testing and fuzzing, which want to know
1135             // whether two values are semantically the same, rather than
1136             // numerically equal.
1137             (Self::Float32(l), Self::Float32(r)) => {
1138                 (*l != 0.0 && l == r)
1139                     || (*l == 0.0 && l.to_bits() == r.to_bits())
1140                     || (l.is_nan() && r.is_nan())
1141             }
1142             (Self::Float32(_), _) => false,
1143             (Self::Float64(l), Self::Float64(r)) => {
1144                 (*l != 0.0 && l == r)
1145                     || (*l == 0.0 && l.to_bits() == r.to_bits())
1146                     || (l.is_nan() && r.is_nan())
1147             }
1148             (Self::Float64(_), _) => false,
1149 
1150             (Self::Bool(l), Self::Bool(r)) => l == r,
1151             (Self::Bool(_), _) => false,
1152             (Self::S8(l), Self::S8(r)) => l == r,
1153             (Self::S8(_), _) => false,
1154             (Self::U8(l), Self::U8(r)) => l == r,
1155             (Self::U8(_), _) => false,
1156             (Self::S16(l), Self::S16(r)) => l == r,
1157             (Self::S16(_), _) => false,
1158             (Self::U16(l), Self::U16(r)) => l == r,
1159             (Self::U16(_), _) => false,
1160             (Self::S32(l), Self::S32(r)) => l == r,
1161             (Self::S32(_), _) => false,
1162             (Self::U32(l), Self::U32(r)) => l == r,
1163             (Self::U32(_), _) => false,
1164             (Self::S64(l), Self::S64(r)) => l == r,
1165             (Self::S64(_), _) => false,
1166             (Self::U64(l), Self::U64(r)) => l == r,
1167             (Self::U64(_), _) => false,
1168             (Self::Char(l), Self::Char(r)) => l == r,
1169             (Self::Char(_), _) => false,
1170             (Self::String(l), Self::String(r)) => l == r,
1171             (Self::String(_), _) => false,
1172             (Self::List(l), Self::List(r)) => l == r,
1173             (Self::List(_), _) => false,
1174             (Self::Record(l), Self::Record(r)) => l == r,
1175             (Self::Record(_), _) => false,
1176             (Self::Tuple(l), Self::Tuple(r)) => l == r,
1177             (Self::Tuple(_), _) => false,
1178             (Self::Variant(l), Self::Variant(r)) => l == r,
1179             (Self::Variant(_), _) => false,
1180             (Self::Enum(l), Self::Enum(r)) => l == r,
1181             (Self::Enum(_), _) => false,
1182             (Self::Option(l), Self::Option(r)) => l == r,
1183             (Self::Option(_), _) => false,
1184             (Self::Result(l), Self::Result(r)) => l == r,
1185             (Self::Result(_), _) => false,
1186             (Self::Flags(l), Self::Flags(r)) => l == r,
1187             (Self::Flags(_), _) => false,
1188             (Self::Resource(l), Self::Resource(r)) => l == r,
1189             (Self::Resource(_), _) => false,
1190         }
1191     }
1192 }
1193 
1194 impl Eq for Val {}
1195 
1196 struct GenericVariant<'a> {
1197     discriminant: u32,
1198     payload: Option<(&'a Val, InterfaceType)>,
1199     abi: &'a CanonicalAbiInfo,
1200     info: &'a VariantInfo,
1201 }
1202 
1203 impl GenericVariant<'_> {
1204     fn lower<T>(
1205         &self,
1206         cx: &mut LowerContext<'_, T>,
1207         dst: &mut std::slice::IterMut<'_, MaybeUninit<ValRaw>>,
1208     ) -> Result<()> {
1209         next_mut(dst).write(ValRaw::u32(self.discriminant));
1210 
1211         // For the remaining lowered representation of this variant that
1212         // the payload didn't write we write out zeros here to ensure
1213         // the entire variant is written.
1214         let value_flat = match self.payload {
1215             Some((value, ty)) => {
1216                 value.lower(cx, ty, dst)?;
1217                 cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap()
1218             }
1219             None => 0,
1220         };
1221         let variant_flat = self.abi.flat_count(usize::MAX).unwrap();
1222         for _ in (1 + value_flat)..variant_flat {
1223             next_mut(dst).write(ValRaw::u64(0));
1224         }
1225         Ok(())
1226     }
1227 
1228     fn store<T>(&self, cx: &mut LowerContext<'_, T>, offset: usize) -> Result<()> {
1229         match self.info.size {
1230             DiscriminantSize::Size1 => {
1231                 u8::try_from(self.discriminant)
1232                     .unwrap()
1233                     .store(cx, InterfaceType::U8, offset)?
1234             }
1235             DiscriminantSize::Size2 => {
1236                 u16::try_from(self.discriminant)
1237                     .unwrap()
1238                     .store(cx, InterfaceType::U16, offset)?
1239             }
1240             DiscriminantSize::Size4 => self.discriminant.store(cx, InterfaceType::U32, offset)?,
1241         }
1242 
1243         if let Some((value, ty)) = self.payload {
1244             let offset = offset + usize::try_from(self.info.payload_offset32).unwrap();
1245             value.store(cx, ty, offset)?;
1246         }
1247 
1248         Ok(())
1249     }
1250 }
1251 
1252 fn load_list(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize) -> Result<Val> {
1253     let elem = cx.types[ty].element;
1254     let abi = cx.types.canonical_abi(&elem);
1255     let element_size = usize::try_from(abi.size32).unwrap();
1256     let element_alignment = abi.align32;
1257 
1258     match len
1259         .checked_mul(element_size)
1260         .and_then(|len| ptr.checked_add(len))
1261     {
1262         Some(n) if n <= cx.memory().len() => {}
1263         _ => bail!("list pointer/length out of bounds of memory"),
1264     }
1265     if ptr % usize::try_from(element_alignment)? != 0 {
1266         bail!("list pointer is not aligned")
1267     }
1268 
1269     Ok(Val::List(List {
1270         ty: types::List::from(ty, &cx.instance_type()),
1271         values: (0..len)
1272             .map(|index| {
1273                 Val::load(
1274                     cx,
1275                     elem,
1276                     &cx.memory()[ptr + (index * element_size)..][..element_size],
1277                 )
1278             })
1279             .collect::<Result<_>>()?,
1280     }))
1281 }
1282 
1283 fn load_record(
1284     cx: &mut LiftContext<'_>,
1285     types: impl Iterator<Item = InterfaceType>,
1286     bytes: &[u8],
1287 ) -> Result<Box<[Val]>> {
1288     let mut offset = 0;
1289     types
1290         .map(|ty| {
1291             let abi = cx.types.canonical_abi(&ty);
1292             let offset = abi.next_field32(&mut offset);
1293             let offset = usize::try_from(offset).unwrap();
1294             let size = usize::try_from(abi.size32).unwrap();
1295             Val::load(cx, ty, &bytes[offset..][..size])
1296         })
1297         .collect()
1298 }
1299 
1300 fn load_variant(
1301     cx: &mut LiftContext<'_>,
1302     info: &VariantInfo,
1303     mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
1304     bytes: &[u8],
1305 ) -> Result<(u32, Option<Box<Val>>)> {
1306     let discriminant = match info.size {
1307         DiscriminantSize::Size1 => u32::from(u8::load(cx, InterfaceType::U8, &bytes[..1])?),
1308         DiscriminantSize::Size2 => u32::from(u16::load(cx, InterfaceType::U16, &bytes[..2])?),
1309         DiscriminantSize::Size4 => u32::load(cx, InterfaceType::U32, &bytes[..4])?,
1310     };
1311     let case_ty = types.nth(discriminant as usize).ok_or_else(|| {
1312         anyhow!(
1313             "discriminant {} out of range [0..{})",
1314             discriminant,
1315             types.len()
1316         )
1317     })?;
1318     let value = match case_ty {
1319         Some(case_ty) => {
1320             let payload_offset = usize::try_from(info.payload_offset32).unwrap();
1321             let case_abi = cx.types.canonical_abi(&case_ty);
1322             let case_size = usize::try_from(case_abi.size32).unwrap();
1323             Some(Box::new(Val::load(
1324                 cx,
1325                 case_ty,
1326                 &bytes[payload_offset..][..case_size],
1327             )?))
1328         }
1329         None => None,
1330     };
1331     Ok((discriminant, value))
1332 }
1333 
1334 fn lift_variant(
1335     cx: &mut LiftContext<'_>,
1336     flatten_count: usize,
1337     mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
1338     src: &mut std::slice::Iter<'_, ValRaw>,
1339 ) -> Result<(u32, Option<Box<Val>>)> {
1340     let len = types.len();
1341     let discriminant = next(src).get_u32();
1342     let ty = types
1343         .nth(discriminant as usize)
1344         .ok_or_else(|| anyhow!("discriminant {} out of range [0..{})", discriminant, len))?;
1345     let (value, value_flat) = match ty {
1346         Some(ty) => (
1347             Some(Box::new(Val::lift(cx, ty, src)?)),
1348             cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
1349         ),
1350         None => (None, 0),
1351     };
1352     for _ in (1 + value_flat)..flatten_count {
1353         next(src);
1354     }
1355     Ok((discriminant, value))
1356 }
1357 
1358 /// Lower a list with the specified element type and values.
1359 fn lower_list<T>(
1360     cx: &mut LowerContext<'_, T>,
1361     element_type: InterfaceType,
1362     items: &[Val],
1363 ) -> Result<(usize, usize)> {
1364     let abi = cx.types.canonical_abi(&element_type);
1365     let elt_size = usize::try_from(abi.size32)?;
1366     let elt_align = abi.align32;
1367     let size = items
1368         .len()
1369         .checked_mul(elt_size)
1370         .ok_or_else(|| anyhow::anyhow!("size overflow copying a list"))?;
1371     let ptr = cx.realloc(0, 0, elt_align, size)?;
1372     let mut element_ptr = ptr;
1373     for item in items {
1374         item.store(cx, element_type, element_ptr)?;
1375         element_ptr += elt_size;
1376     }
1377     Ok((ptr, items.len()))
1378 }
1379 
1380 fn next<'a>(src: &mut std::slice::Iter<'a, ValRaw>) -> &'a ValRaw {
1381     src.next().unwrap()
1382 }
1383 
1384 fn next_mut<'a>(
1385     dst: &mut std::slice::IterMut<'a, MaybeUninit<ValRaw>>,
1386 ) -> &'a mut MaybeUninit<ValRaw> {
1387     dst.next().unwrap()
1388 }
1389