1d4242001SAdam Bratschi-Kaye use crate::ValRaw;
290ac295eSAlex Crichton use crate::component::ResourceAny;
3f586be11SAlex Crichton use crate::component::concurrent::{self, ErrorContext, FutureAny, StreamAny};
490ac295eSAlex Crichton use crate::component::func::{Lift, LiftContext, Lower, LowerContext, desc};
590ac295eSAlex Crichton use crate::prelude::*;
681a89169SAlex Crichton use core::mem::MaybeUninit;
781a89169SAlex Crichton use core::slice::{Iter, IterMut};
8d4242001SAdam Bratschi-Kaye use wasmtime_component_util::{DiscriminantSize, FlagsSize};
9d4242001SAdam Bratschi-Kaye use wasmtime_environ::component::{
101b59b579SYordis Prieto CanonicalAbiInfo, InterfaceType, TypeEnum, TypeFlags, TypeListIndex, TypeMap, TypeMapIndex,
111b59b579SYordis Prieto TypeOption, TypeResult, TypeVariant, VariantInfo,
12d4242001SAdam Bratschi-Kaye };
13d4242001SAdam Bratschi-Kaye
14d4242001SAdam Bratschi-Kaye /// Represents possible runtime values which a component function can either
15d4242001SAdam Bratschi-Kaye /// consume or produce
16d4242001SAdam Bratschi-Kaye ///
17d4242001SAdam Bratschi-Kaye /// This is a dynamic representation of possible values in the component model.
18d4242001SAdam Bratschi-Kaye /// Note that this is not an efficient representation but is instead intended to
19d4242001SAdam Bratschi-Kaye /// be a flexible and somewhat convenient representation. The most efficient
20d4242001SAdam Bratschi-Kaye /// representation of component model types is to use the `bindgen!` macro to
21d4242001SAdam Bratschi-Kaye /// generate native Rust types with specialized liftings and lowerings.
22d4242001SAdam Bratschi-Kaye ///
23d4242001SAdam Bratschi-Kaye /// This type is used in conjunction with [`Func::call`] for example if the
24d4242001SAdam Bratschi-Kaye /// signature of a component is not statically known ahead of time.
25d4242001SAdam Bratschi-Kaye ///
269de6828eSAlex Crichton /// # Equality and `Val`
27d4242001SAdam Bratschi-Kaye ///
28d4242001SAdam Bratschi-Kaye /// This type implements both the Rust `PartialEq` and `Eq` traits. This type
29d4242001SAdam Bratschi-Kaye /// additionally contains values which are not necessarily easily equated,
30d4242001SAdam Bratschi-Kaye /// however, such as floats (`Float32` and `Float64`) and resources. Equality
31d4242001SAdam Bratschi-Kaye /// does require that two values have the same type, and then these cases are
32d4242001SAdam Bratschi-Kaye /// handled as:
33d4242001SAdam Bratschi-Kaye ///
34d4242001SAdam Bratschi-Kaye /// * Floats are tested if they are "semantically the same" meaning all NaN
35d4242001SAdam Bratschi-Kaye /// values are equal to all other NaN values. Additionally zero values must be
36d4242001SAdam Bratschi-Kaye /// exactly the same, so positive zero is not equal to negative zero. The
37d4242001SAdam Bratschi-Kaye /// primary use case at this time is fuzzing-related equality which this is
38d4242001SAdam Bratschi-Kaye /// sufficient for.
39d4242001SAdam Bratschi-Kaye ///
40d4242001SAdam Bratschi-Kaye /// * Resources are tested if their types and indices into the host table are
41d4242001SAdam Bratschi-Kaye /// equal. This does not compare the underlying representation so borrows of
42d4242001SAdam Bratschi-Kaye /// the same guest resource are not considered equal. This additionally
43d4242001SAdam Bratschi-Kaye /// doesn't go further and test for equality in the guest itself (for example
44d4242001SAdam Bratschi-Kaye /// two different heap allocations of `Box<u32>` can be equal in normal Rust
45d4242001SAdam Bratschi-Kaye /// if they contain the same value, but will never be considered equal when
46d4242001SAdam Bratschi-Kaye /// compared as `Val::Resource`s).
47d4242001SAdam Bratschi-Kaye ///
48d4242001SAdam Bratschi-Kaye /// In general if a strict guarantee about equality is required here it's
49d4242001SAdam Bratschi-Kaye /// recommended to "build your own" as this equality intended for fuzzing
50d4242001SAdam Bratschi-Kaye /// Wasmtime may not be suitable for you.
51d4242001SAdam Bratschi-Kaye ///
529de6828eSAlex Crichton /// # Component model types and `Val`
539de6828eSAlex Crichton ///
549de6828eSAlex Crichton /// The `Val` type here does not contain enough information to say what the
559de6828eSAlex Crichton /// component model type of a `Val` is. This is instead more of an AST of sorts.
569de6828eSAlex Crichton /// For example the `Val::Enum` only carries information about a single
579de6828eSAlex Crichton /// discriminant, not the entire enumeration or what it's a discriminant of.
589de6828eSAlex Crichton ///
599de6828eSAlex Crichton /// This means that when a `Val` is passed to Wasmtime, for example as a
609de6828eSAlex Crichton /// function parameter when calling a function or as a return value from an
619de6828eSAlex Crichton /// host-defined imported function, then it must pass a type-check. Instances of
629de6828eSAlex Crichton /// `Val` are type-checked against what's required by the component itself.
639de6828eSAlex Crichton ///
64d4242001SAdam Bratschi-Kaye /// [`Func::call`]: crate::component::Func::call
65d4242001SAdam Bratschi-Kaye #[derive(Debug, Clone)]
66838ed2d0SAlex Crichton #[expect(missing_docs, reason = "self-describing variants")]
67d4242001SAdam Bratschi-Kaye pub enum Val {
68d4242001SAdam Bratschi-Kaye Bool(bool),
69d4242001SAdam Bratschi-Kaye S8(i8),
70d4242001SAdam Bratschi-Kaye U8(u8),
71d4242001SAdam Bratschi-Kaye S16(i16),
72d4242001SAdam Bratschi-Kaye U16(u16),
73d4242001SAdam Bratschi-Kaye S32(i32),
74d4242001SAdam Bratschi-Kaye U32(u32),
75d4242001SAdam Bratschi-Kaye S64(i64),
76d4242001SAdam Bratschi-Kaye U64(u64),
77d4242001SAdam Bratschi-Kaye Float32(f32),
78d4242001SAdam Bratschi-Kaye Float64(f64),
79d4242001SAdam Bratschi-Kaye Char(char),
809de6828eSAlex Crichton String(String),
819de6828eSAlex Crichton List(Vec<Val>),
821b59b579SYordis Prieto /// A map type represented as a list of key-value pairs.
831b59b579SYordis Prieto /// Duplicate keys are allowed and follow "last value wins" semantics.
841b59b579SYordis Prieto Map(Vec<(Val, Val)>),
859de6828eSAlex Crichton Record(Vec<(String, Val)>),
869de6828eSAlex Crichton Tuple(Vec<Val>),
879de6828eSAlex Crichton Variant(String, Option<Box<Val>>),
889de6828eSAlex Crichton Enum(String),
899de6828eSAlex Crichton Option(Option<Box<Val>>),
909de6828eSAlex Crichton Result(Result<Option<Box<Val>>, Option<Box<Val>>>),
919de6828eSAlex Crichton Flags(Vec<String>),
92d4242001SAdam Bratschi-Kaye Resource(ResourceAny),
93b221fca7SJoel Dice Future(FutureAny),
94b221fca7SJoel Dice Stream(StreamAny),
95b221fca7SJoel Dice ErrorContext(ErrorContextAny),
96d4242001SAdam Bratschi-Kaye }
97d4242001SAdam Bratschi-Kaye
98d4242001SAdam Bratschi-Kaye impl Val {
99d4242001SAdam Bratschi-Kaye /// Deserialize a value of this type from core Wasm stack values.
lift( cx: &mut LiftContext<'_>, ty: InterfaceType, src: &mut Iter<'_, ValRaw>, ) -> Result<Val>100d4242001SAdam Bratschi-Kaye pub(crate) fn lift(
101d4242001SAdam Bratschi-Kaye cx: &mut LiftContext<'_>,
102d4242001SAdam Bratschi-Kaye ty: InterfaceType,
10381a89169SAlex Crichton src: &mut Iter<'_, ValRaw>,
104d4242001SAdam Bratschi-Kaye ) -> Result<Val> {
105d4242001SAdam Bratschi-Kaye Ok(match ty {
1067dba8efdSNick Fitzgerald InterfaceType::Bool => Val::Bool(bool::linear_lift_from_flat(cx, ty, next(src))?),
1077dba8efdSNick Fitzgerald InterfaceType::S8 => Val::S8(i8::linear_lift_from_flat(cx, ty, next(src))?),
1087dba8efdSNick Fitzgerald InterfaceType::U8 => Val::U8(u8::linear_lift_from_flat(cx, ty, next(src))?),
1097dba8efdSNick Fitzgerald InterfaceType::S16 => Val::S16(i16::linear_lift_from_flat(cx, ty, next(src))?),
1107dba8efdSNick Fitzgerald InterfaceType::U16 => Val::U16(u16::linear_lift_from_flat(cx, ty, next(src))?),
1117dba8efdSNick Fitzgerald InterfaceType::S32 => Val::S32(i32::linear_lift_from_flat(cx, ty, next(src))?),
1127dba8efdSNick Fitzgerald InterfaceType::U32 => Val::U32(u32::linear_lift_from_flat(cx, ty, next(src))?),
1137dba8efdSNick Fitzgerald InterfaceType::S64 => Val::S64(i64::linear_lift_from_flat(cx, ty, next(src))?),
1147dba8efdSNick Fitzgerald InterfaceType::U64 => Val::U64(u64::linear_lift_from_flat(cx, ty, next(src))?),
1157dba8efdSNick Fitzgerald InterfaceType::Float32 => Val::Float32(f32::linear_lift_from_flat(cx, ty, next(src))?),
1167dba8efdSNick Fitzgerald InterfaceType::Float64 => Val::Float64(f64::linear_lift_from_flat(cx, ty, next(src))?),
1177dba8efdSNick Fitzgerald InterfaceType::Char => Val::Char(char::linear_lift_from_flat(cx, ty, next(src))?),
118d4242001SAdam Bratschi-Kaye InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
1197dba8efdSNick Fitzgerald Val::Resource(ResourceAny::linear_lift_from_flat(cx, ty, next(src))?)
120d4242001SAdam Bratschi-Kaye }
1217dba8efdSNick Fitzgerald InterfaceType::String => Val::String(<_>::linear_lift_from_flat(
1227dba8efdSNick Fitzgerald cx,
1237dba8efdSNick Fitzgerald ty,
1247dba8efdSNick Fitzgerald &[*next(src), *next(src)],
1257dba8efdSNick Fitzgerald )?),
126d4242001SAdam Bratschi-Kaye InterfaceType::List(i) => {
127a0d5346dSAlex Crichton let (ptr, len) = lift_flat_pointer_pair(cx, src)?;
128d4242001SAdam Bratschi-Kaye load_list(cx, i, ptr, len)?
129d4242001SAdam Bratschi-Kaye }
1301b59b579SYordis Prieto InterfaceType::Map(i) => {
131a0d5346dSAlex Crichton let (ptr, len) = lift_flat_pointer_pair(cx, src)?;
1321b59b579SYordis Prieto load_map(cx, i, ptr, len)?
1331b59b579SYordis Prieto }
1349de6828eSAlex Crichton InterfaceType::Record(i) => Val::Record(
1359de6828eSAlex Crichton cx.types[i]
136d4242001SAdam Bratschi-Kaye .fields
137d4242001SAdam Bratschi-Kaye .iter()
1389de6828eSAlex Crichton .map(|field| {
1399de6828eSAlex Crichton let val = Self::lift(cx, field.ty, src)?;
1409de6828eSAlex Crichton Ok((field.name.to_string(), val))
1419de6828eSAlex Crichton })
142d4242001SAdam Bratschi-Kaye .collect::<Result<_>>()?,
1439de6828eSAlex Crichton ),
1449de6828eSAlex Crichton InterfaceType::Tuple(i) => Val::Tuple(
1459de6828eSAlex Crichton cx.types[i]
146d4242001SAdam Bratschi-Kaye .types
147d4242001SAdam Bratschi-Kaye .iter()
148d4242001SAdam Bratschi-Kaye .map(|ty| Self::lift(cx, *ty, src))
149d4242001SAdam Bratschi-Kaye .collect::<Result<_>>()?,
1509de6828eSAlex Crichton ),
151d4242001SAdam Bratschi-Kaye InterfaceType::Variant(i) => {
1529de6828eSAlex Crichton let vty = &cx.types[i];
153d4242001SAdam Bratschi-Kaye let (discriminant, value) = lift_variant(
154d4242001SAdam Bratschi-Kaye cx,
155d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
1569de6828eSAlex Crichton vty.cases.values().copied(),
157d4242001SAdam Bratschi-Kaye src,
158d4242001SAdam Bratschi-Kaye )?;
159d4242001SAdam Bratschi-Kaye
1609de6828eSAlex Crichton let (k, _) = vty.cases.get_index(discriminant as usize).unwrap();
1619de6828eSAlex Crichton Val::Variant(k.clone(), value)
162d4242001SAdam Bratschi-Kaye }
163d4242001SAdam Bratschi-Kaye InterfaceType::Enum(i) => {
1649de6828eSAlex Crichton let ety = &cx.types[i];
165d4242001SAdam Bratschi-Kaye let (discriminant, _) = lift_variant(
166d4242001SAdam Bratschi-Kaye cx,
167d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
1689de6828eSAlex Crichton ety.names.iter().map(|_| None),
169d4242001SAdam Bratschi-Kaye src,
170d4242001SAdam Bratschi-Kaye )?;
171d4242001SAdam Bratschi-Kaye
1729de6828eSAlex Crichton Val::Enum(ety.names[discriminant as usize].clone())
173d4242001SAdam Bratschi-Kaye }
174d4242001SAdam Bratschi-Kaye InterfaceType::Option(i) => {
1759de6828eSAlex Crichton let (_discriminant, value) = lift_variant(
176d4242001SAdam Bratschi-Kaye cx,
177d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
178d4242001SAdam Bratschi-Kaye [None, Some(cx.types[i].ty)].into_iter(),
179d4242001SAdam Bratschi-Kaye src,
180d4242001SAdam Bratschi-Kaye )?;
181d4242001SAdam Bratschi-Kaye
1829de6828eSAlex Crichton Val::Option(value)
183d4242001SAdam Bratschi-Kaye }
184d4242001SAdam Bratschi-Kaye InterfaceType::Result(i) => {
185d4242001SAdam Bratschi-Kaye let result_ty = &cx.types[i];
186d4242001SAdam Bratschi-Kaye let (discriminant, value) = lift_variant(
187d4242001SAdam Bratschi-Kaye cx,
188d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
189d4242001SAdam Bratschi-Kaye [result_ty.ok, result_ty.err].into_iter(),
190d4242001SAdam Bratschi-Kaye src,
191d4242001SAdam Bratschi-Kaye )?;
192d4242001SAdam Bratschi-Kaye
1939de6828eSAlex Crichton Val::Result(if discriminant == 0 {
1949de6828eSAlex Crichton Ok(value)
1959de6828eSAlex Crichton } else {
1969de6828eSAlex Crichton Err(value)
197d4242001SAdam Bratschi-Kaye })
198d4242001SAdam Bratschi-Kaye }
199d4242001SAdam Bratschi-Kaye InterfaceType::Flags(i) => {
200d4242001SAdam Bratschi-Kaye let u32_count = cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap();
2019de6828eSAlex Crichton let ty = &cx.types[i];
2029de6828eSAlex Crichton let mut flags = Vec::new();
2030bce0968SAlex Crichton for i in 0..u32::try_from(u32_count).unwrap() {
2049de6828eSAlex Crichton push_flags(
2059de6828eSAlex Crichton ty,
2069de6828eSAlex Crichton &mut flags,
2070bce0968SAlex Crichton i * 32,
2087dba8efdSNick Fitzgerald u32::linear_lift_from_flat(cx, InterfaceType::U32, next(src))?,
2099de6828eSAlex Crichton );
2109de6828eSAlex Crichton }
211d4242001SAdam Bratschi-Kaye
212703871a2SAlex Crichton Val::Flags(flags)
213d4242001SAdam Bratschi-Kaye }
214b221fca7SJoel Dice InterfaceType::Future(_) => {
215f586be11SAlex Crichton Val::Future(FutureAny::linear_lift_from_flat(cx, ty, next(src))?)
216b221fca7SJoel Dice }
217b221fca7SJoel Dice InterfaceType::Stream(_) => {
218f586be11SAlex Crichton Val::Stream(StreamAny::linear_lift_from_flat(cx, ty, next(src))?)
219b221fca7SJoel Dice }
220b221fca7SJoel Dice InterfaceType::ErrorContext(_) => {
221b221fca7SJoel Dice ErrorContext::linear_lift_from_flat(cx, ty, next(src))?.into_val()
222b221fca7SJoel Dice }
223caf0f752SChristof Petig InterfaceType::FixedLengthList(_) => todo!(), // FIXME(#12279)
224d4242001SAdam Bratschi-Kaye })
225d4242001SAdam Bratschi-Kaye }
226d4242001SAdam Bratschi-Kaye
227d4242001SAdam Bratschi-Kaye /// Deserialize a value of this type from the heap.
load(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Val>228d4242001SAdam Bratschi-Kaye pub(crate) fn load(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Val> {
229d4242001SAdam Bratschi-Kaye Ok(match ty {
2307dba8efdSNick Fitzgerald InterfaceType::Bool => Val::Bool(bool::linear_lift_from_memory(cx, ty, bytes)?),
2317dba8efdSNick Fitzgerald InterfaceType::S8 => Val::S8(i8::linear_lift_from_memory(cx, ty, bytes)?),
2327dba8efdSNick Fitzgerald InterfaceType::U8 => Val::U8(u8::linear_lift_from_memory(cx, ty, bytes)?),
2337dba8efdSNick Fitzgerald InterfaceType::S16 => Val::S16(i16::linear_lift_from_memory(cx, ty, bytes)?),
2347dba8efdSNick Fitzgerald InterfaceType::U16 => Val::U16(u16::linear_lift_from_memory(cx, ty, bytes)?),
2357dba8efdSNick Fitzgerald InterfaceType::S32 => Val::S32(i32::linear_lift_from_memory(cx, ty, bytes)?),
2367dba8efdSNick Fitzgerald InterfaceType::U32 => Val::U32(u32::linear_lift_from_memory(cx, ty, bytes)?),
2377dba8efdSNick Fitzgerald InterfaceType::S64 => Val::S64(i64::linear_lift_from_memory(cx, ty, bytes)?),
2387dba8efdSNick Fitzgerald InterfaceType::U64 => Val::U64(u64::linear_lift_from_memory(cx, ty, bytes)?),
2397dba8efdSNick Fitzgerald InterfaceType::Float32 => Val::Float32(f32::linear_lift_from_memory(cx, ty, bytes)?),
2407dba8efdSNick Fitzgerald InterfaceType::Float64 => Val::Float64(f64::linear_lift_from_memory(cx, ty, bytes)?),
2417dba8efdSNick Fitzgerald InterfaceType::Char => Val::Char(char::linear_lift_from_memory(cx, ty, bytes)?),
2427dba8efdSNick Fitzgerald InterfaceType::String => Val::String(<_>::linear_lift_from_memory(cx, ty, bytes)?),
243d4242001SAdam Bratschi-Kaye InterfaceType::Own(_) | InterfaceType::Borrow(_) => {
2447dba8efdSNick Fitzgerald Val::Resource(ResourceAny::linear_lift_from_memory(cx, ty, bytes)?)
245d4242001SAdam Bratschi-Kaye }
246d4242001SAdam Bratschi-Kaye InterfaceType::List(i) => {
247a0d5346dSAlex Crichton let (ptr, len) = load_flat_pointer_pair(bytes);
248d4242001SAdam Bratschi-Kaye load_list(cx, i, ptr, len)?
249d4242001SAdam Bratschi-Kaye }
2501b59b579SYordis Prieto InterfaceType::Map(i) => {
251a0d5346dSAlex Crichton let (ptr, len) = load_flat_pointer_pair(bytes);
2521b59b579SYordis Prieto load_map(cx, i, ptr, len)?
2531b59b579SYordis Prieto }
254d4242001SAdam Bratschi-Kaye
2559de6828eSAlex Crichton InterfaceType::Record(i) => {
2569de6828eSAlex Crichton let mut offset = 0;
2579de6828eSAlex Crichton let fields = cx.types[i].fields.iter();
2589de6828eSAlex Crichton Val::Record(
2599de6828eSAlex Crichton fields
2609de6828eSAlex Crichton .map(|field| -> Result<(String, Val)> {
2619de6828eSAlex Crichton let abi = cx.types.canonical_abi(&field.ty);
2629de6828eSAlex Crichton let offset = abi.next_field32(&mut offset);
2639de6828eSAlex Crichton let offset = usize::try_from(offset).unwrap();
2649de6828eSAlex Crichton let size = usize::try_from(abi.size32).unwrap();
2659de6828eSAlex Crichton Ok((
2669de6828eSAlex Crichton field.name.to_string(),
2679de6828eSAlex Crichton Val::load(cx, field.ty, &bytes[offset..][..size])?,
2689de6828eSAlex Crichton ))
2699de6828eSAlex Crichton })
2709de6828eSAlex Crichton .collect::<Result<_>>()?,
2719de6828eSAlex Crichton )
2729de6828eSAlex Crichton }
2739de6828eSAlex Crichton InterfaceType::Tuple(i) => {
2749de6828eSAlex Crichton let types = cx.types[i].types.iter().copied();
2759de6828eSAlex Crichton let mut offset = 0;
2769de6828eSAlex Crichton Val::Tuple(
2779de6828eSAlex Crichton types
2789de6828eSAlex Crichton .map(|ty| {
2799de6828eSAlex Crichton let abi = cx.types.canonical_abi(&ty);
2809de6828eSAlex Crichton let offset = abi.next_field32(&mut offset);
2819de6828eSAlex Crichton let offset = usize::try_from(offset).unwrap();
2829de6828eSAlex Crichton let size = usize::try_from(abi.size32).unwrap();
2839de6828eSAlex Crichton Val::load(cx, ty, &bytes[offset..][..size])
2849de6828eSAlex Crichton })
2859de6828eSAlex Crichton .collect::<Result<_>>()?,
2869de6828eSAlex Crichton )
2879de6828eSAlex Crichton }
288d4242001SAdam Bratschi-Kaye InterfaceType::Variant(i) => {
289d4242001SAdam Bratschi-Kaye let ty = &cx.types[i];
290d4242001SAdam Bratschi-Kaye let (discriminant, value) =
2919de6828eSAlex Crichton load_variant(cx, &ty.info, ty.cases.values().copied(), bytes)?;
292d4242001SAdam Bratschi-Kaye
2939de6828eSAlex Crichton let (k, _) = ty.cases.get_index(discriminant as usize).unwrap();
2949de6828eSAlex Crichton Val::Variant(k.clone(), value)
295d4242001SAdam Bratschi-Kaye }
296d4242001SAdam Bratschi-Kaye InterfaceType::Enum(i) => {
297d4242001SAdam Bratschi-Kaye let ty = &cx.types[i];
298d4242001SAdam Bratschi-Kaye let (discriminant, _) =
299d4242001SAdam Bratschi-Kaye load_variant(cx, &ty.info, ty.names.iter().map(|_| None), bytes)?;
300d4242001SAdam Bratschi-Kaye
3019de6828eSAlex Crichton Val::Enum(ty.names[discriminant as usize].clone())
302d4242001SAdam Bratschi-Kaye }
303d4242001SAdam Bratschi-Kaye InterfaceType::Option(i) => {
304d4242001SAdam Bratschi-Kaye let ty = &cx.types[i];
3059de6828eSAlex Crichton let (_discriminant, value) =
306d4242001SAdam Bratschi-Kaye load_variant(cx, &ty.info, [None, Some(ty.ty)].into_iter(), bytes)?;
307d4242001SAdam Bratschi-Kaye
3089de6828eSAlex Crichton Val::Option(value)
309d4242001SAdam Bratschi-Kaye }
310d4242001SAdam Bratschi-Kaye InterfaceType::Result(i) => {
311d4242001SAdam Bratschi-Kaye let ty = &cx.types[i];
312d4242001SAdam Bratschi-Kaye let (discriminant, value) =
313d4242001SAdam Bratschi-Kaye load_variant(cx, &ty.info, [ty.ok, ty.err].into_iter(), bytes)?;
314d4242001SAdam Bratschi-Kaye
3159de6828eSAlex Crichton Val::Result(if discriminant == 0 {
3169de6828eSAlex Crichton Ok(value)
3179de6828eSAlex Crichton } else {
3189de6828eSAlex Crichton Err(value)
319d4242001SAdam Bratschi-Kaye })
320d4242001SAdam Bratschi-Kaye }
3219de6828eSAlex Crichton InterfaceType::Flags(i) => {
3229de6828eSAlex Crichton let ty = &cx.types[i];
3239de6828eSAlex Crichton let mut flags = Vec::new();
3249de6828eSAlex Crichton match FlagsSize::from_count(ty.names.len()) {
3259de6828eSAlex Crichton FlagsSize::Size0 => {}
326d4242001SAdam Bratschi-Kaye FlagsSize::Size1 => {
3277dba8efdSNick Fitzgerald let bits = u8::linear_lift_from_memory(cx, InterfaceType::U8, bytes)?;
3289de6828eSAlex Crichton push_flags(ty, &mut flags, 0, u32::from(bits));
329d4242001SAdam Bratschi-Kaye }
330d4242001SAdam Bratschi-Kaye FlagsSize::Size2 => {
3317dba8efdSNick Fitzgerald let bits = u16::linear_lift_from_memory(cx, InterfaceType::U16, bytes)?;
3329de6828eSAlex Crichton push_flags(ty, &mut flags, 0, u32::from(bits));
333d4242001SAdam Bratschi-Kaye }
3349de6828eSAlex Crichton FlagsSize::Size4Plus(n) => {
3359de6828eSAlex Crichton for i in 0..n {
3367dba8efdSNick Fitzgerald let bits = u32::linear_lift_from_memory(
337d4242001SAdam Bratschi-Kaye cx,
338d4242001SAdam Bratschi-Kaye InterfaceType::U32,
3399de6828eSAlex Crichton &bytes[usize::from(i) * 4..][..4],
3409de6828eSAlex Crichton )?;
3419de6828eSAlex Crichton push_flags(ty, &mut flags, u32::from(i) * 32, bits);
3429de6828eSAlex Crichton }
3439de6828eSAlex Crichton }
3449de6828eSAlex Crichton }
345703871a2SAlex Crichton Val::Flags(flags)
3469de6828eSAlex Crichton }
347f586be11SAlex Crichton InterfaceType::Future(_) => FutureAny::linear_lift_from_memory(cx, ty, bytes)?.into(),
348f586be11SAlex Crichton InterfaceType::Stream(_) => StreamAny::linear_lift_from_memory(cx, ty, bytes)?.into(),
349b221fca7SJoel Dice InterfaceType::ErrorContext(_) => {
350b221fca7SJoel Dice ErrorContext::linear_lift_from_memory(cx, ty, bytes)?.into_val()
351b221fca7SJoel Dice }
352caf0f752SChristof Petig InterfaceType::FixedLengthList(_) => todo!(), // FIXME(#12279)
353d4242001SAdam Bratschi-Kaye })
354d4242001SAdam Bratschi-Kaye }
355d4242001SAdam Bratschi-Kaye
356d4242001SAdam Bratschi-Kaye /// Serialize this value as core Wasm stack values.
lower<T>( &self, cx: &mut LowerContext<'_, T>, ty: InterfaceType, dst: &mut IterMut<'_, MaybeUninit<ValRaw>>, ) -> Result<()>357d4242001SAdam Bratschi-Kaye pub(crate) fn lower<T>(
358d4242001SAdam Bratschi-Kaye &self,
359d4242001SAdam Bratschi-Kaye cx: &mut LowerContext<'_, T>,
360d4242001SAdam Bratschi-Kaye ty: InterfaceType,
36181a89169SAlex Crichton dst: &mut IterMut<'_, MaybeUninit<ValRaw>>,
362d4242001SAdam Bratschi-Kaye ) -> Result<()> {
3639de6828eSAlex Crichton match (ty, self) {
3647dba8efdSNick Fitzgerald (InterfaceType::Bool, Val::Bool(value)) => {
3657dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3667dba8efdSNick Fitzgerald }
3679de6828eSAlex Crichton (InterfaceType::Bool, _) => unexpected(ty, self),
3687dba8efdSNick Fitzgerald (InterfaceType::S8, Val::S8(value)) => {
3697dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3707dba8efdSNick Fitzgerald }
3719de6828eSAlex Crichton (InterfaceType::S8, _) => unexpected(ty, self),
3727dba8efdSNick Fitzgerald (InterfaceType::U8, Val::U8(value)) => {
3737dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3747dba8efdSNick Fitzgerald }
3759de6828eSAlex Crichton (InterfaceType::U8, _) => unexpected(ty, self),
3767dba8efdSNick Fitzgerald (InterfaceType::S16, Val::S16(value)) => {
3777dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3787dba8efdSNick Fitzgerald }
3799de6828eSAlex Crichton (InterfaceType::S16, _) => unexpected(ty, self),
3807dba8efdSNick Fitzgerald (InterfaceType::U16, Val::U16(value)) => {
3817dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3827dba8efdSNick Fitzgerald }
3839de6828eSAlex Crichton (InterfaceType::U16, _) => unexpected(ty, self),
3847dba8efdSNick Fitzgerald (InterfaceType::S32, Val::S32(value)) => {
3857dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3867dba8efdSNick Fitzgerald }
3879de6828eSAlex Crichton (InterfaceType::S32, _) => unexpected(ty, self),
3887dba8efdSNick Fitzgerald (InterfaceType::U32, Val::U32(value)) => {
3897dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3907dba8efdSNick Fitzgerald }
3919de6828eSAlex Crichton (InterfaceType::U32, _) => unexpected(ty, self),
3927dba8efdSNick Fitzgerald (InterfaceType::S64, Val::S64(value)) => {
3937dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3947dba8efdSNick Fitzgerald }
3959de6828eSAlex Crichton (InterfaceType::S64, _) => unexpected(ty, self),
3967dba8efdSNick Fitzgerald (InterfaceType::U64, Val::U64(value)) => {
3977dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
3987dba8efdSNick Fitzgerald }
3999de6828eSAlex Crichton (InterfaceType::U64, _) => unexpected(ty, self),
4007dba8efdSNick Fitzgerald (InterfaceType::Float32, Val::Float32(value)) => {
4017dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
4027dba8efdSNick Fitzgerald }
4039de6828eSAlex Crichton (InterfaceType::Float32, _) => unexpected(ty, self),
4047dba8efdSNick Fitzgerald (InterfaceType::Float64, Val::Float64(value)) => {
4057dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
4067dba8efdSNick Fitzgerald }
4079de6828eSAlex Crichton (InterfaceType::Float64, _) => unexpected(ty, self),
4087dba8efdSNick Fitzgerald (InterfaceType::Char, Val::Char(value)) => {
4097dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
4107dba8efdSNick Fitzgerald }
4119de6828eSAlex Crichton (InterfaceType::Char, _) => unexpected(ty, self),
4129de6828eSAlex Crichton // NB: `lower` on `ResourceAny` does its own type-checking, so skip
4139de6828eSAlex Crichton // looking at it here.
4149de6828eSAlex Crichton (InterfaceType::Borrow(_) | InterfaceType::Own(_), Val::Resource(value)) => {
4157dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, next_mut(dst))
4169de6828eSAlex Crichton }
4179de6828eSAlex Crichton (InterfaceType::Borrow(_) | InterfaceType::Own(_), _) => unexpected(ty, self),
4189de6828eSAlex Crichton (InterfaceType::String, Val::String(value)) => {
419d4242001SAdam Bratschi-Kaye let my_dst = &mut MaybeUninit::<[ValRaw; 2]>::uninit();
4207dba8efdSNick Fitzgerald value.linear_lower_to_flat(cx, ty, my_dst)?;
421d4242001SAdam Bratschi-Kaye let my_dst = unsafe { my_dst.assume_init() };
422d4242001SAdam Bratschi-Kaye next_mut(dst).write(my_dst[0]);
423d4242001SAdam Bratschi-Kaye next_mut(dst).write(my_dst[1]);
4249de6828eSAlex Crichton Ok(())
425d4242001SAdam Bratschi-Kaye }
4269de6828eSAlex Crichton (InterfaceType::String, _) => unexpected(ty, self),
4279de6828eSAlex Crichton (InterfaceType::List(ty), Val::List(values)) => {
4289de6828eSAlex Crichton let ty = &cx.types[ty];
429d4242001SAdam Bratschi-Kaye let (ptr, len) = lower_list(cx, ty.element, values)?;
430d4242001SAdam Bratschi-Kaye next_mut(dst).write(ValRaw::i64(ptr as i64));
431d4242001SAdam Bratschi-Kaye next_mut(dst).write(ValRaw::i64(len as i64));
4329de6828eSAlex Crichton Ok(())
433d4242001SAdam Bratschi-Kaye }
4349de6828eSAlex Crichton (InterfaceType::List(_), _) => unexpected(ty, self),
4351b59b579SYordis Prieto (InterfaceType::Map(ty), Val::Map(pairs)) => {
4361b59b579SYordis Prieto let map_ty = &cx.types[ty];
4371b59b579SYordis Prieto let (ptr, len) = lower_map(cx, map_ty, pairs)?;
4381b59b579SYordis Prieto next_mut(dst).write(ValRaw::i64(ptr as i64));
4391b59b579SYordis Prieto next_mut(dst).write(ValRaw::i64(len as i64));
4401b59b579SYordis Prieto Ok(())
4411b59b579SYordis Prieto }
4421b59b579SYordis Prieto (InterfaceType::Map(_), _) => unexpected(ty, self),
4439de6828eSAlex Crichton (InterfaceType::Record(ty), Val::Record(values)) => {
4449de6828eSAlex Crichton let ty = &cx.types[ty];
4459de6828eSAlex Crichton if ty.fields.len() != values.len() {
4469de6828eSAlex Crichton bail!("expected {} fields, got {}", ty.fields.len(), values.len());
4479de6828eSAlex Crichton }
4489de6828eSAlex Crichton for ((name, value), field) in values.iter().zip(ty.fields.iter()) {
4499de6828eSAlex Crichton if *name != field.name {
4509de6828eSAlex Crichton bail!("expected field `{}`, got `{name}`", field.name);
4519de6828eSAlex Crichton }
452d4242001SAdam Bratschi-Kaye value.lower(cx, field.ty, dst)?;
453d4242001SAdam Bratschi-Kaye }
4549de6828eSAlex Crichton Ok(())
455d4242001SAdam Bratschi-Kaye }
4569de6828eSAlex Crichton (InterfaceType::Record(_), _) => unexpected(ty, self),
4579de6828eSAlex Crichton (InterfaceType::Tuple(ty), Val::Tuple(values)) => {
4589de6828eSAlex Crichton let ty = &cx.types[ty];
4599de6828eSAlex Crichton if ty.types.len() != values.len() {
4609de6828eSAlex Crichton bail!("expected {} types, got {}", ty.types.len(), values.len());
4619de6828eSAlex Crichton }
462d4242001SAdam Bratschi-Kaye for (value, ty) in values.iter().zip(ty.types.iter()) {
463d4242001SAdam Bratschi-Kaye value.lower(cx, *ty, dst)?;
464d4242001SAdam Bratschi-Kaye }
465d4242001SAdam Bratschi-Kaye Ok(())
466d4242001SAdam Bratschi-Kaye }
4679de6828eSAlex Crichton (InterfaceType::Tuple(_), _) => unexpected(ty, self),
4689de6828eSAlex Crichton (InterfaceType::Variant(ty), Val::Variant(n, v)) => {
4699de6828eSAlex Crichton GenericVariant::variant(&cx.types[ty], n, v)?.lower(cx, dst)
4709de6828eSAlex Crichton }
4719de6828eSAlex Crichton (InterfaceType::Variant(_), _) => unexpected(ty, self),
4729de6828eSAlex Crichton (InterfaceType::Option(ty), Val::Option(v)) => {
4739de6828eSAlex Crichton GenericVariant::option(&cx.types[ty], v).lower(cx, dst)
4749de6828eSAlex Crichton }
4759de6828eSAlex Crichton (InterfaceType::Option(_), _) => unexpected(ty, self),
4769de6828eSAlex Crichton (InterfaceType::Result(ty), Val::Result(v)) => {
4779de6828eSAlex Crichton GenericVariant::result(&cx.types[ty], v)?.lower(cx, dst)
4789de6828eSAlex Crichton }
4799de6828eSAlex Crichton (InterfaceType::Result(_), _) => unexpected(ty, self),
4809de6828eSAlex Crichton (InterfaceType::Enum(ty), Val::Enum(discriminant)) => {
4819de6828eSAlex Crichton let discriminant = get_enum_discriminant(&cx.types[ty], discriminant)?;
4829de6828eSAlex Crichton next_mut(dst).write(ValRaw::u32(discriminant));
4839de6828eSAlex Crichton Ok(())
4849de6828eSAlex Crichton }
4859de6828eSAlex Crichton (InterfaceType::Enum(_), _) => unexpected(ty, self),
4869de6828eSAlex Crichton (InterfaceType::Flags(ty), Val::Flags(value)) => {
4879de6828eSAlex Crichton let ty = &cx.types[ty];
4889de6828eSAlex Crichton let storage = flags_to_storage(ty, value)?;
4899de6828eSAlex Crichton for value in storage {
4909de6828eSAlex Crichton next_mut(dst).write(ValRaw::u32(value));
4919de6828eSAlex Crichton }
4929de6828eSAlex Crichton Ok(())
4939de6828eSAlex Crichton }
4949de6828eSAlex Crichton (InterfaceType::Flags(_), _) => unexpected(ty, self),
495f586be11SAlex Crichton (InterfaceType::Future(_), Val::Future(f)) => {
496f586be11SAlex Crichton f.linear_lower_to_flat(cx, ty, next_mut(dst))
497b221fca7SJoel Dice }
498b221fca7SJoel Dice (InterfaceType::Future(_), _) => unexpected(ty, self),
499f586be11SAlex Crichton (InterfaceType::Stream(_), Val::Stream(s)) => {
500f586be11SAlex Crichton s.linear_lower_to_flat(cx, ty, next_mut(dst))
501b221fca7SJoel Dice }
502b221fca7SJoel Dice (InterfaceType::Stream(_), _) => unexpected(ty, self),
503b221fca7SJoel Dice (InterfaceType::ErrorContext(_), Val::ErrorContext(ErrorContextAny(rep))) => {
504b221fca7SJoel Dice concurrent::lower_error_context_to_index(*rep, cx, ty)?.linear_lower_to_flat(
505b221fca7SJoel Dice cx,
506b221fca7SJoel Dice InterfaceType::U32,
507b221fca7SJoel Dice next_mut(dst),
508b221fca7SJoel Dice )
509b221fca7SJoel Dice }
510b221fca7SJoel Dice (InterfaceType::ErrorContext(_), _) => unexpected(ty, self),
511caf0f752SChristof Petig (InterfaceType::FixedLengthList(_), _) => todo!(), // FIXME(#12279)
5129de6828eSAlex Crichton }
5139de6828eSAlex Crichton }
514d4242001SAdam Bratschi-Kaye
515d4242001SAdam Bratschi-Kaye /// Serialize this value to the heap at the specified memory location.
store<T>( &self, cx: &mut LowerContext<'_, T>, ty: InterfaceType, offset: usize, ) -> Result<()>516d4242001SAdam Bratschi-Kaye pub(crate) fn store<T>(
517d4242001SAdam Bratschi-Kaye &self,
518d4242001SAdam Bratschi-Kaye cx: &mut LowerContext<'_, T>,
519d4242001SAdam Bratschi-Kaye ty: InterfaceType,
520d4242001SAdam Bratschi-Kaye offset: usize,
521d4242001SAdam Bratschi-Kaye ) -> Result<()> {
5229034e101SAlex Crichton debug_assert!(offset % usize::try_from(cx.types.canonical_abi(&ty).align32)? == 0);
523d4242001SAdam Bratschi-Kaye
5249de6828eSAlex Crichton match (ty, self) {
5257dba8efdSNick Fitzgerald (InterfaceType::Bool, Val::Bool(value)) => value.linear_lower_to_memory(cx, ty, offset),
5269de6828eSAlex Crichton (InterfaceType::Bool, _) => unexpected(ty, self),
5277dba8efdSNick Fitzgerald (InterfaceType::U8, Val::U8(value)) => value.linear_lower_to_memory(cx, ty, offset),
5289de6828eSAlex Crichton (InterfaceType::U8, _) => unexpected(ty, self),
5297dba8efdSNick Fitzgerald (InterfaceType::S8, Val::S8(value)) => value.linear_lower_to_memory(cx, ty, offset),
5309de6828eSAlex Crichton (InterfaceType::S8, _) => unexpected(ty, self),
5317dba8efdSNick Fitzgerald (InterfaceType::U16, Val::U16(value)) => value.linear_lower_to_memory(cx, ty, offset),
5329de6828eSAlex Crichton (InterfaceType::U16, _) => unexpected(ty, self),
5337dba8efdSNick Fitzgerald (InterfaceType::S16, Val::S16(value)) => value.linear_lower_to_memory(cx, ty, offset),
5349de6828eSAlex Crichton (InterfaceType::S16, _) => unexpected(ty, self),
5357dba8efdSNick Fitzgerald (InterfaceType::U32, Val::U32(value)) => value.linear_lower_to_memory(cx, ty, offset),
5369de6828eSAlex Crichton (InterfaceType::U32, _) => unexpected(ty, self),
5377dba8efdSNick Fitzgerald (InterfaceType::S32, Val::S32(value)) => value.linear_lower_to_memory(cx, ty, offset),
5389de6828eSAlex Crichton (InterfaceType::S32, _) => unexpected(ty, self),
5397dba8efdSNick Fitzgerald (InterfaceType::U64, Val::U64(value)) => value.linear_lower_to_memory(cx, ty, offset),
5409de6828eSAlex Crichton (InterfaceType::U64, _) => unexpected(ty, self),
5417dba8efdSNick Fitzgerald (InterfaceType::S64, Val::S64(value)) => value.linear_lower_to_memory(cx, ty, offset),
5429de6828eSAlex Crichton (InterfaceType::S64, _) => unexpected(ty, self),
5437dba8efdSNick Fitzgerald (InterfaceType::Float32, Val::Float32(value)) => {
5447dba8efdSNick Fitzgerald value.linear_lower_to_memory(cx, ty, offset)
5457dba8efdSNick Fitzgerald }
5469de6828eSAlex Crichton (InterfaceType::Float32, _) => unexpected(ty, self),
5477dba8efdSNick Fitzgerald (InterfaceType::Float64, Val::Float64(value)) => {
5487dba8efdSNick Fitzgerald value.linear_lower_to_memory(cx, ty, offset)
5497dba8efdSNick Fitzgerald }
5509de6828eSAlex Crichton (InterfaceType::Float64, _) => unexpected(ty, self),
5517dba8efdSNick Fitzgerald (InterfaceType::Char, Val::Char(value)) => value.linear_lower_to_memory(cx, ty, offset),
5529de6828eSAlex Crichton (InterfaceType::Char, _) => unexpected(ty, self),
5537dba8efdSNick Fitzgerald (InterfaceType::String, Val::String(value)) => {
5547dba8efdSNick Fitzgerald value.linear_lower_to_memory(cx, ty, offset)
5557dba8efdSNick Fitzgerald }
5569de6828eSAlex Crichton (InterfaceType::String, _) => unexpected(ty, self),
5579de6828eSAlex Crichton
5589de6828eSAlex Crichton // NB: resources do type-checking when they lower.
5599de6828eSAlex Crichton (InterfaceType::Borrow(_) | InterfaceType::Own(_), Val::Resource(value)) => {
5607dba8efdSNick Fitzgerald value.linear_lower_to_memory(cx, ty, offset)
5619de6828eSAlex Crichton }
5629de6828eSAlex Crichton (InterfaceType::Borrow(_) | InterfaceType::Own(_), _) => unexpected(ty, self),
5639de6828eSAlex Crichton (InterfaceType::List(ty), Val::List(values)) => {
5649de6828eSAlex Crichton let ty = &cx.types[ty];
565d4242001SAdam Bratschi-Kaye let (ptr, len) = lower_list(cx, ty.element, values)?;
566ef1ec37eSAlex Crichton // FIXME(#4311): needs memory64 handling
5670bce0968SAlex Crichton *cx.get(offset + 0) = u32::try_from(ptr).unwrap().to_le_bytes();
5680bce0968SAlex Crichton *cx.get(offset + 4) = u32::try_from(len).unwrap().to_le_bytes();
5699de6828eSAlex Crichton Ok(())
570d4242001SAdam Bratschi-Kaye }
5719de6828eSAlex Crichton (InterfaceType::List(_), _) => unexpected(ty, self),
5721b59b579SYordis Prieto (InterfaceType::Map(ty_idx), Val::Map(values)) => {
5731b59b579SYordis Prieto let map_ty = &cx.types[ty_idx];
5741b59b579SYordis Prieto let (ptr, len) = lower_map(cx, map_ty, values)?;
5751b59b579SYordis Prieto // FIXME(#4311): needs memory64 handling
5761b59b579SYordis Prieto *cx.get(offset + 0) = u32::try_from(ptr).unwrap().to_le_bytes();
5771b59b579SYordis Prieto *cx.get(offset + 4) = u32::try_from(len).unwrap().to_le_bytes();
5781b59b579SYordis Prieto Ok(())
5791b59b579SYordis Prieto }
5801b59b579SYordis Prieto (InterfaceType::Map(_), _) => unexpected(ty, self),
5819de6828eSAlex Crichton (InterfaceType::Record(ty), Val::Record(values)) => {
5829de6828eSAlex Crichton let ty = &cx.types[ty];
5839de6828eSAlex Crichton if ty.fields.len() != values.len() {
5849de6828eSAlex Crichton bail!("expected {} fields, got {}", ty.fields.len(), values.len());
5859de6828eSAlex Crichton }
586d4242001SAdam Bratschi-Kaye let mut offset = offset;
5879de6828eSAlex Crichton for ((name, value), field) in values.iter().zip(ty.fields.iter()) {
5889de6828eSAlex Crichton if *name != field.name {
5899de6828eSAlex Crichton bail!("expected field `{}`, got `{name}`", field.name);
5909de6828eSAlex Crichton }
591d4242001SAdam Bratschi-Kaye value.store(
592d4242001SAdam Bratschi-Kaye cx,
593d4242001SAdam Bratschi-Kaye field.ty,
594d4242001SAdam Bratschi-Kaye cx.types
595d4242001SAdam Bratschi-Kaye .canonical_abi(&field.ty)
596d4242001SAdam Bratschi-Kaye .next_field32_size(&mut offset),
597d4242001SAdam Bratschi-Kaye )?;
598d4242001SAdam Bratschi-Kaye }
5999de6828eSAlex Crichton Ok(())
600d4242001SAdam Bratschi-Kaye }
6019de6828eSAlex Crichton (InterfaceType::Record(_), _) => unexpected(ty, self),
6029de6828eSAlex Crichton (InterfaceType::Tuple(ty), Val::Tuple(values)) => {
6039de6828eSAlex Crichton let ty = &cx.types[ty];
6049de6828eSAlex Crichton if ty.types.len() != values.len() {
6059de6828eSAlex Crichton bail!("expected {} types, got {}", ty.types.len(), values.len());
6069de6828eSAlex Crichton }
607d4242001SAdam Bratschi-Kaye let mut offset = offset;
608d4242001SAdam Bratschi-Kaye for (value, ty) in values.iter().zip(ty.types.iter()) {
609d4242001SAdam Bratschi-Kaye value.store(
610d4242001SAdam Bratschi-Kaye cx,
611d4242001SAdam Bratschi-Kaye *ty,
612d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(ty).next_field32_size(&mut offset),
613d4242001SAdam Bratschi-Kaye )?;
614d4242001SAdam Bratschi-Kaye }
6159de6828eSAlex Crichton Ok(())
616d4242001SAdam Bratschi-Kaye }
6179de6828eSAlex Crichton (InterfaceType::Tuple(_), _) => unexpected(ty, self),
618d4242001SAdam Bratschi-Kaye
6199de6828eSAlex Crichton (InterfaceType::Variant(ty), Val::Variant(n, v)) => {
6209de6828eSAlex Crichton GenericVariant::variant(&cx.types[ty], n, v)?.store(cx, offset)
6219de6828eSAlex Crichton }
6229de6828eSAlex Crichton (InterfaceType::Variant(_), _) => unexpected(ty, self),
6239de6828eSAlex Crichton (InterfaceType::Enum(ty), Val::Enum(v)) => {
6249de6828eSAlex Crichton GenericVariant::enum_(&cx.types[ty], v)?.store(cx, offset)
6259de6828eSAlex Crichton }
6269de6828eSAlex Crichton (InterfaceType::Enum(_), _) => unexpected(ty, self),
6279de6828eSAlex Crichton (InterfaceType::Option(ty), Val::Option(v)) => {
6289de6828eSAlex Crichton GenericVariant::option(&cx.types[ty], v).store(cx, offset)
6299de6828eSAlex Crichton }
6309de6828eSAlex Crichton (InterfaceType::Option(_), _) => unexpected(ty, self),
6319de6828eSAlex Crichton (InterfaceType::Result(ty), Val::Result(v)) => {
6329de6828eSAlex Crichton GenericVariant::result(&cx.types[ty], v)?.store(cx, offset)
6339de6828eSAlex Crichton }
6349de6828eSAlex Crichton (InterfaceType::Result(_), _) => unexpected(ty, self),
635d4242001SAdam Bratschi-Kaye
6369de6828eSAlex Crichton (InterfaceType::Flags(ty), Val::Flags(flags)) => {
6379de6828eSAlex Crichton let ty = &cx.types[ty];
6389de6828eSAlex Crichton let storage = flags_to_storage(ty, flags)?;
6399de6828eSAlex Crichton match FlagsSize::from_count(ty.names.len()) {
640d4242001SAdam Bratschi-Kaye FlagsSize::Size0 => {}
6417dba8efdSNick Fitzgerald FlagsSize::Size1 => u8::try_from(storage[0]).unwrap().linear_lower_to_memory(
6427dba8efdSNick Fitzgerald cx,
6437dba8efdSNick Fitzgerald InterfaceType::U8,
6447dba8efdSNick Fitzgerald offset,
6457dba8efdSNick Fitzgerald )?,
6467dba8efdSNick Fitzgerald FlagsSize::Size2 => u16::try_from(storage[0]).unwrap().linear_lower_to_memory(
6477dba8efdSNick Fitzgerald cx,
6487dba8efdSNick Fitzgerald InterfaceType::U16,
6497dba8efdSNick Fitzgerald offset,
6507dba8efdSNick Fitzgerald )?,
651d4242001SAdam Bratschi-Kaye FlagsSize::Size4Plus(_) => {
652d4242001SAdam Bratschi-Kaye let mut offset = offset;
6539de6828eSAlex Crichton for value in storage {
6547dba8efdSNick Fitzgerald value.linear_lower_to_memory(cx, InterfaceType::U32, offset)?;
655d4242001SAdam Bratschi-Kaye offset += 4;
656d4242001SAdam Bratschi-Kaye }
657d4242001SAdam Bratschi-Kaye }
658d4242001SAdam Bratschi-Kaye }
6599de6828eSAlex Crichton Ok(())
6609de6828eSAlex Crichton }
6619de6828eSAlex Crichton (InterfaceType::Flags(_), _) => unexpected(ty, self),
662f586be11SAlex Crichton (InterfaceType::Future(_), Val::Future(f)) => f.linear_lower_to_memory(cx, ty, offset),
663b221fca7SJoel Dice (InterfaceType::Future(_), _) => unexpected(ty, self),
664f586be11SAlex Crichton (InterfaceType::Stream(_), Val::Stream(s)) => s.linear_lower_to_memory(cx, ty, offset),
665b221fca7SJoel Dice (InterfaceType::Stream(_), _) => unexpected(ty, self),
666b221fca7SJoel Dice (InterfaceType::ErrorContext(_), Val::ErrorContext(ErrorContextAny(rep))) => {
667b221fca7SJoel Dice concurrent::lower_error_context_to_index(*rep, cx, ty)?.linear_lower_to_memory(
668b221fca7SJoel Dice cx,
669b221fca7SJoel Dice InterfaceType::U32,
670b221fca7SJoel Dice offset,
671b221fca7SJoel Dice )
672b221fca7SJoel Dice }
673b221fca7SJoel Dice (InterfaceType::ErrorContext(_), _) => unexpected(ty, self),
674caf0f752SChristof Petig (InterfaceType::FixedLengthList(_), _) => todo!(), // FIXME(#12279)
675d4242001SAdam Bratschi-Kaye }
676d4242001SAdam Bratschi-Kaye }
677d4242001SAdam Bratschi-Kaye
desc(&self) -> &'static str678b221fca7SJoel Dice pub(crate) fn desc(&self) -> &'static str {
6799de6828eSAlex Crichton match self {
6809de6828eSAlex Crichton Val::Bool(_) => "bool",
6819de6828eSAlex Crichton Val::U8(_) => "u8",
6829de6828eSAlex Crichton Val::S8(_) => "s8",
6839de6828eSAlex Crichton Val::U16(_) => "u16",
6849de6828eSAlex Crichton Val::S16(_) => "s16",
6859de6828eSAlex Crichton Val::U32(_) => "u32",
6869de6828eSAlex Crichton Val::S32(_) => "s32",
6879de6828eSAlex Crichton Val::U64(_) => "u64",
6889de6828eSAlex Crichton Val::S64(_) => "s64",
6899de6828eSAlex Crichton Val::Float32(_) => "f32",
6909de6828eSAlex Crichton Val::Float64(_) => "f64",
6919de6828eSAlex Crichton Val::Char(_) => "char",
6929de6828eSAlex Crichton Val::List(_) => "list",
6931b59b579SYordis Prieto Val::Map(_) => "map",
6949de6828eSAlex Crichton Val::String(_) => "string",
6959de6828eSAlex Crichton Val::Record(_) => "record",
6969de6828eSAlex Crichton Val::Enum(_) => "enum",
6979de6828eSAlex Crichton Val::Variant(..) => "variant",
6989de6828eSAlex Crichton Val::Tuple(_) => "tuple",
6999de6828eSAlex Crichton Val::Option(_) => "option",
7009de6828eSAlex Crichton Val::Result(_) => "result",
7019de6828eSAlex Crichton Val::Resource(_) => "resource",
7029de6828eSAlex Crichton Val::Flags(_) => "flags",
703b221fca7SJoel Dice Val::Future(_) => "future",
704b221fca7SJoel Dice Val::Stream(_) => "stream",
705b221fca7SJoel Dice Val::ErrorContext(_) => "error-context",
7069de6828eSAlex Crichton }
707d4242001SAdam Bratschi-Kaye }
7084c6739f1SPat Hickey
7094c6739f1SPat Hickey /// Deserialize a [`Val`] from its [`crate::component::wasm_wave`] encoding. Deserialization
7101e5d77d6Sshenpengfeng /// requires a target [`crate::component::Type`].
7114c6739f1SPat Hickey #[cfg(feature = "wave")]
from_wave(ty: &crate::component::Type, s: &str) -> Result<Self>7124c6739f1SPat Hickey pub fn from_wave(ty: &crate::component::Type, s: &str) -> Result<Self> {
7134c6739f1SPat Hickey Ok(wasm_wave::from_str(ty, s)?)
7144c6739f1SPat Hickey }
7154c6739f1SPat Hickey
7164c6739f1SPat Hickey /// Serialize a [`Val`] to its [`crate::component::wasm_wave`] encoding.
7174c6739f1SPat Hickey #[cfg(feature = "wave")]
to_wave(&self) -> Result<String>7184c6739f1SPat Hickey pub fn to_wave(&self) -> Result<String> {
7194c6739f1SPat Hickey Ok(wasm_wave::to_string(self)?)
7204c6739f1SPat Hickey }
721d4242001SAdam Bratschi-Kaye }
722d4242001SAdam Bratschi-Kaye
723d4242001SAdam Bratschi-Kaye impl PartialEq for Val {
eq(&self, other: &Self) -> bool724d4242001SAdam Bratschi-Kaye fn eq(&self, other: &Self) -> bool {
725d4242001SAdam Bratschi-Kaye match (self, other) {
726d4242001SAdam Bratschi-Kaye // IEEE 754 equality considers NaN inequal to NaN and negative zero
727d4242001SAdam Bratschi-Kaye // equal to positive zero, however we do the opposite here, because
728d4242001SAdam Bratschi-Kaye // this logic is used by testing and fuzzing, which want to know
729d4242001SAdam Bratschi-Kaye // whether two values are semantically the same, rather than
730d4242001SAdam Bratschi-Kaye // numerically equal.
731d4242001SAdam Bratschi-Kaye (Self::Float32(l), Self::Float32(r)) => {
732d4242001SAdam Bratschi-Kaye (*l != 0.0 && l == r)
733d4242001SAdam Bratschi-Kaye || (*l == 0.0 && l.to_bits() == r.to_bits())
734d4242001SAdam Bratschi-Kaye || (l.is_nan() && r.is_nan())
735d4242001SAdam Bratschi-Kaye }
736d4242001SAdam Bratschi-Kaye (Self::Float32(_), _) => false,
737d4242001SAdam Bratschi-Kaye (Self::Float64(l), Self::Float64(r)) => {
738d4242001SAdam Bratschi-Kaye (*l != 0.0 && l == r)
739d4242001SAdam Bratschi-Kaye || (*l == 0.0 && l.to_bits() == r.to_bits())
740d4242001SAdam Bratschi-Kaye || (l.is_nan() && r.is_nan())
741d4242001SAdam Bratschi-Kaye }
742d4242001SAdam Bratschi-Kaye (Self::Float64(_), _) => false,
743d4242001SAdam Bratschi-Kaye
744d4242001SAdam Bratschi-Kaye (Self::Bool(l), Self::Bool(r)) => l == r,
745d4242001SAdam Bratschi-Kaye (Self::Bool(_), _) => false,
746d4242001SAdam Bratschi-Kaye (Self::S8(l), Self::S8(r)) => l == r,
747d4242001SAdam Bratschi-Kaye (Self::S8(_), _) => false,
748d4242001SAdam Bratschi-Kaye (Self::U8(l), Self::U8(r)) => l == r,
749d4242001SAdam Bratschi-Kaye (Self::U8(_), _) => false,
750d4242001SAdam Bratschi-Kaye (Self::S16(l), Self::S16(r)) => l == r,
751d4242001SAdam Bratschi-Kaye (Self::S16(_), _) => false,
752d4242001SAdam Bratschi-Kaye (Self::U16(l), Self::U16(r)) => l == r,
753d4242001SAdam Bratschi-Kaye (Self::U16(_), _) => false,
754d4242001SAdam Bratschi-Kaye (Self::S32(l), Self::S32(r)) => l == r,
755d4242001SAdam Bratschi-Kaye (Self::S32(_), _) => false,
756d4242001SAdam Bratschi-Kaye (Self::U32(l), Self::U32(r)) => l == r,
757d4242001SAdam Bratschi-Kaye (Self::U32(_), _) => false,
758d4242001SAdam Bratschi-Kaye (Self::S64(l), Self::S64(r)) => l == r,
759d4242001SAdam Bratschi-Kaye (Self::S64(_), _) => false,
760d4242001SAdam Bratschi-Kaye (Self::U64(l), Self::U64(r)) => l == r,
761d4242001SAdam Bratschi-Kaye (Self::U64(_), _) => false,
762d4242001SAdam Bratschi-Kaye (Self::Char(l), Self::Char(r)) => l == r,
763d4242001SAdam Bratschi-Kaye (Self::Char(_), _) => false,
764d4242001SAdam Bratschi-Kaye (Self::String(l), Self::String(r)) => l == r,
765d4242001SAdam Bratschi-Kaye (Self::String(_), _) => false,
766d4242001SAdam Bratschi-Kaye (Self::List(l), Self::List(r)) => l == r,
767d4242001SAdam Bratschi-Kaye (Self::List(_), _) => false,
7681b59b579SYordis Prieto (Self::Map(l), Self::Map(r)) => l == r,
7691b59b579SYordis Prieto (Self::Map(_), _) => false,
770d4242001SAdam Bratschi-Kaye (Self::Record(l), Self::Record(r)) => l == r,
771d4242001SAdam Bratschi-Kaye (Self::Record(_), _) => false,
772d4242001SAdam Bratschi-Kaye (Self::Tuple(l), Self::Tuple(r)) => l == r,
773d4242001SAdam Bratschi-Kaye (Self::Tuple(_), _) => false,
7749de6828eSAlex Crichton (Self::Variant(ln, lv), Self::Variant(rn, rv)) => ln == rn && lv == rv,
7759de6828eSAlex Crichton (Self::Variant(..), _) => false,
776d4242001SAdam Bratschi-Kaye (Self::Enum(l), Self::Enum(r)) => l == r,
777d4242001SAdam Bratschi-Kaye (Self::Enum(_), _) => false,
778d4242001SAdam Bratschi-Kaye (Self::Option(l), Self::Option(r)) => l == r,
779d4242001SAdam Bratschi-Kaye (Self::Option(_), _) => false,
780d4242001SAdam Bratschi-Kaye (Self::Result(l), Self::Result(r)) => l == r,
781d4242001SAdam Bratschi-Kaye (Self::Result(_), _) => false,
782d4242001SAdam Bratschi-Kaye (Self::Flags(l), Self::Flags(r)) => l == r,
783d4242001SAdam Bratschi-Kaye (Self::Flags(_), _) => false,
784d4242001SAdam Bratschi-Kaye (Self::Resource(l), Self::Resource(r)) => l == r,
785d4242001SAdam Bratschi-Kaye (Self::Resource(_), _) => false,
786b221fca7SJoel Dice (Self::Future(l), Self::Future(r)) => l == r,
787b221fca7SJoel Dice (Self::Future(_), _) => false,
788b221fca7SJoel Dice (Self::Stream(l), Self::Stream(r)) => l == r,
789b221fca7SJoel Dice (Self::Stream(_), _) => false,
790b221fca7SJoel Dice (Self::ErrorContext(l), Self::ErrorContext(r)) => l == r,
791b221fca7SJoel Dice (Self::ErrorContext(_), _) => false,
792d4242001SAdam Bratschi-Kaye }
793d4242001SAdam Bratschi-Kaye }
794d4242001SAdam Bratschi-Kaye }
795d4242001SAdam Bratschi-Kaye
796d4242001SAdam Bratschi-Kaye impl Eq for Val {}
797d4242001SAdam Bratschi-Kaye
798d4242001SAdam Bratschi-Kaye struct GenericVariant<'a> {
799d4242001SAdam Bratschi-Kaye discriminant: u32,
800d4242001SAdam Bratschi-Kaye payload: Option<(&'a Val, InterfaceType)>,
801d4242001SAdam Bratschi-Kaye abi: &'a CanonicalAbiInfo,
802d4242001SAdam Bratschi-Kaye info: &'a VariantInfo,
803d4242001SAdam Bratschi-Kaye }
804d4242001SAdam Bratschi-Kaye
805d4242001SAdam Bratschi-Kaye impl GenericVariant<'_> {
result<'a>( ty: &'a TypeResult, r: &'a Result<Option<Box<Val>>, Option<Box<Val>>>, ) -> Result<GenericVariant<'a>>8069de6828eSAlex Crichton fn result<'a>(
8079de6828eSAlex Crichton ty: &'a TypeResult,
8089de6828eSAlex Crichton r: &'a Result<Option<Box<Val>>, Option<Box<Val>>>,
8099de6828eSAlex Crichton ) -> Result<GenericVariant<'a>> {
8109de6828eSAlex Crichton let (discriminant, payload) = match r {
8119de6828eSAlex Crichton Ok(val) => {
8129de6828eSAlex Crichton let payload = match (val, ty.ok) {
8139de6828eSAlex Crichton (Some(val), Some(ty)) => Some((&**val, ty)),
8149de6828eSAlex Crichton (None, None) => None,
8159de6828eSAlex Crichton (Some(_), None) => {
8169de6828eSAlex Crichton bail!("payload provided to `ok` but not expected");
8179de6828eSAlex Crichton }
8189de6828eSAlex Crichton (None, Some(_)) => {
8199de6828eSAlex Crichton bail!("payload expected to `ok` but not provided");
8209de6828eSAlex Crichton }
8219de6828eSAlex Crichton };
8229de6828eSAlex Crichton (0, payload)
8239de6828eSAlex Crichton }
8249de6828eSAlex Crichton Err(val) => {
8259de6828eSAlex Crichton let payload = match (val, ty.err) {
8269de6828eSAlex Crichton (Some(val), Some(ty)) => Some((&**val, ty)),
8279de6828eSAlex Crichton (None, None) => None,
8289de6828eSAlex Crichton (Some(_), None) => {
8299de6828eSAlex Crichton bail!("payload provided to `err` but not expected");
8309de6828eSAlex Crichton }
8319de6828eSAlex Crichton (None, Some(_)) => {
8329de6828eSAlex Crichton bail!("payload expected to `err` but not provided");
8339de6828eSAlex Crichton }
8349de6828eSAlex Crichton };
8359de6828eSAlex Crichton (1, payload)
8369de6828eSAlex Crichton }
8379de6828eSAlex Crichton };
8389de6828eSAlex Crichton Ok(GenericVariant {
8399de6828eSAlex Crichton discriminant,
8409de6828eSAlex Crichton payload,
8419de6828eSAlex Crichton abi: &ty.abi,
8429de6828eSAlex Crichton info: &ty.info,
8439de6828eSAlex Crichton })
8449de6828eSAlex Crichton }
8459de6828eSAlex Crichton
option<'a>(ty: &'a TypeOption, r: &'a Option<Box<Val>>) -> GenericVariant<'a>8469de6828eSAlex Crichton fn option<'a>(ty: &'a TypeOption, r: &'a Option<Box<Val>>) -> GenericVariant<'a> {
8479de6828eSAlex Crichton let (discriminant, payload) = match r {
8489de6828eSAlex Crichton None => (0, None),
8499de6828eSAlex Crichton Some(val) => (1, Some((&**val, ty.ty))),
8509de6828eSAlex Crichton };
8519de6828eSAlex Crichton GenericVariant {
8529de6828eSAlex Crichton discriminant,
8539de6828eSAlex Crichton payload,
8549de6828eSAlex Crichton abi: &ty.abi,
8559de6828eSAlex Crichton info: &ty.info,
8569de6828eSAlex Crichton }
8579de6828eSAlex Crichton }
8589de6828eSAlex Crichton
enum_<'a>(ty: &'a TypeEnum, discriminant: &str) -> Result<GenericVariant<'a>>8599de6828eSAlex Crichton fn enum_<'a>(ty: &'a TypeEnum, discriminant: &str) -> Result<GenericVariant<'a>> {
8609de6828eSAlex Crichton let discriminant = get_enum_discriminant(ty, discriminant)?;
8619de6828eSAlex Crichton
8629de6828eSAlex Crichton Ok(GenericVariant {
8639de6828eSAlex Crichton discriminant,
8649de6828eSAlex Crichton payload: None,
8659de6828eSAlex Crichton abi: &ty.abi,
8669de6828eSAlex Crichton info: &ty.info,
8679de6828eSAlex Crichton })
8689de6828eSAlex Crichton }
8699de6828eSAlex Crichton
variant<'a>( ty: &'a TypeVariant, discriminant_name: &str, payload: &'a Option<Box<Val>>, ) -> Result<GenericVariant<'a>>8709de6828eSAlex Crichton fn variant<'a>(
8719de6828eSAlex Crichton ty: &'a TypeVariant,
8729de6828eSAlex Crichton discriminant_name: &str,
8739de6828eSAlex Crichton payload: &'a Option<Box<Val>>,
8749de6828eSAlex Crichton ) -> Result<GenericVariant<'a>> {
8759de6828eSAlex Crichton let (discriminant, payload_ty) = get_variant_discriminant(ty, discriminant_name)?;
8769de6828eSAlex Crichton
8779de6828eSAlex Crichton let payload = match (payload, payload_ty) {
8789de6828eSAlex Crichton (Some(val), Some(ty)) => Some((&**val, *ty)),
8799de6828eSAlex Crichton (None, None) => None,
8809de6828eSAlex Crichton (Some(_), None) => bail!("did not expect a payload for case `{discriminant_name}`"),
8819de6828eSAlex Crichton (None, Some(_)) => bail!("expected a payload for case `{discriminant_name}`"),
8829de6828eSAlex Crichton };
8839de6828eSAlex Crichton
8849de6828eSAlex Crichton Ok(GenericVariant {
8859de6828eSAlex Crichton discriminant,
8869de6828eSAlex Crichton payload,
8879de6828eSAlex Crichton abi: &ty.abi,
8889de6828eSAlex Crichton info: &ty.info,
8899de6828eSAlex Crichton })
8909de6828eSAlex Crichton }
8919de6828eSAlex Crichton
lower<T>( &self, cx: &mut LowerContext<'_, T>, dst: &mut IterMut<'_, MaybeUninit<ValRaw>>, ) -> Result<()>892d4242001SAdam Bratschi-Kaye fn lower<T>(
893d4242001SAdam Bratschi-Kaye &self,
894d4242001SAdam Bratschi-Kaye cx: &mut LowerContext<'_, T>,
89581a89169SAlex Crichton dst: &mut IterMut<'_, MaybeUninit<ValRaw>>,
896d4242001SAdam Bratschi-Kaye ) -> Result<()> {
897d4242001SAdam Bratschi-Kaye next_mut(dst).write(ValRaw::u32(self.discriminant));
898d4242001SAdam Bratschi-Kaye
899d4242001SAdam Bratschi-Kaye // For the remaining lowered representation of this variant that
900d4242001SAdam Bratschi-Kaye // the payload didn't write we write out zeros here to ensure
901d4242001SAdam Bratschi-Kaye // the entire variant is written.
902d4242001SAdam Bratschi-Kaye let value_flat = match self.payload {
903d4242001SAdam Bratschi-Kaye Some((value, ty)) => {
904d4242001SAdam Bratschi-Kaye value.lower(cx, ty, dst)?;
905d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap()
906d4242001SAdam Bratschi-Kaye }
907d4242001SAdam Bratschi-Kaye None => 0,
908d4242001SAdam Bratschi-Kaye };
909d4242001SAdam Bratschi-Kaye let variant_flat = self.abi.flat_count(usize::MAX).unwrap();
910d4242001SAdam Bratschi-Kaye for _ in (1 + value_flat)..variant_flat {
911d4242001SAdam Bratschi-Kaye next_mut(dst).write(ValRaw::u64(0));
912d4242001SAdam Bratschi-Kaye }
913d4242001SAdam Bratschi-Kaye Ok(())
914d4242001SAdam Bratschi-Kaye }
915d4242001SAdam Bratschi-Kaye
store<T>(&self, cx: &mut LowerContext<'_, T>, offset: usize) -> Result<()>916d4242001SAdam Bratschi-Kaye fn store<T>(&self, cx: &mut LowerContext<'_, T>, offset: usize) -> Result<()> {
917d4242001SAdam Bratschi-Kaye match self.info.size {
9187dba8efdSNick Fitzgerald DiscriminantSize::Size1 => u8::try_from(self.discriminant)
919d4242001SAdam Bratschi-Kaye .unwrap()
9207dba8efdSNick Fitzgerald .linear_lower_to_memory(cx, InterfaceType::U8, offset)?,
9217dba8efdSNick Fitzgerald DiscriminantSize::Size2 => u16::try_from(self.discriminant)
922d4242001SAdam Bratschi-Kaye .unwrap()
9237dba8efdSNick Fitzgerald .linear_lower_to_memory(cx, InterfaceType::U16, offset)?,
9247dba8efdSNick Fitzgerald DiscriminantSize::Size4 => {
9257dba8efdSNick Fitzgerald self.discriminant
9267dba8efdSNick Fitzgerald .linear_lower_to_memory(cx, InterfaceType::U32, offset)?
927d4242001SAdam Bratschi-Kaye }
928d4242001SAdam Bratschi-Kaye }
929d4242001SAdam Bratschi-Kaye
930d4242001SAdam Bratschi-Kaye if let Some((value, ty)) = self.payload {
931d4242001SAdam Bratschi-Kaye let offset = offset + usize::try_from(self.info.payload_offset32).unwrap();
932d4242001SAdam Bratschi-Kaye value.store(cx, ty, offset)?;
933d4242001SAdam Bratschi-Kaye }
934d4242001SAdam Bratschi-Kaye
935d4242001SAdam Bratschi-Kaye Ok(())
936d4242001SAdam Bratschi-Kaye }
937d4242001SAdam Bratschi-Kaye }
938d4242001SAdam Bratschi-Kaye
lift_flat_pointer_pair( cx: &mut LiftContext<'_>, src: &mut Iter<'_, ValRaw>, ) -> Result<(usize, usize)>939a0d5346dSAlex Crichton fn lift_flat_pointer_pair(
940a0d5346dSAlex Crichton cx: &mut LiftContext<'_>,
941a0d5346dSAlex Crichton src: &mut Iter<'_, ValRaw>,
942a0d5346dSAlex Crichton ) -> Result<(usize, usize)> {
943a0d5346dSAlex Crichton // FIXME(#4311): needs memory64 treatment
944a0d5346dSAlex Crichton let ptr = u32::linear_lift_from_flat(cx, InterfaceType::U32, next(src))? as usize;
945a0d5346dSAlex Crichton let len = u32::linear_lift_from_flat(cx, InterfaceType::U32, next(src))? as usize;
946a0d5346dSAlex Crichton Ok((ptr, len))
947a0d5346dSAlex Crichton }
948a0d5346dSAlex Crichton
load_flat_pointer_pair(bytes: &[u8]) -> (usize, usize)949a0d5346dSAlex Crichton fn load_flat_pointer_pair(bytes: &[u8]) -> (usize, usize) {
950a0d5346dSAlex Crichton let ptr = u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize;
951a0d5346dSAlex Crichton let len = u32::from_le_bytes(bytes[4..].try_into().unwrap()) as usize;
952a0d5346dSAlex Crichton (ptr, len)
953a0d5346dSAlex Crichton }
954a0d5346dSAlex Crichton
load_list(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize) -> Result<Val>955d4242001SAdam Bratschi-Kaye fn load_list(cx: &mut LiftContext<'_>, ty: TypeListIndex, ptr: usize, len: usize) -> Result<Val> {
956d4242001SAdam Bratschi-Kaye let elem = cx.types[ty].element;
957d4242001SAdam Bratschi-Kaye let abi = cx.types.canonical_abi(&elem);
958d4242001SAdam Bratschi-Kaye let element_size = usize::try_from(abi.size32).unwrap();
959d4242001SAdam Bratschi-Kaye let element_alignment = abi.align32;
960d4242001SAdam Bratschi-Kaye
961d4242001SAdam Bratschi-Kaye match len
962d4242001SAdam Bratschi-Kaye .checked_mul(element_size)
963d4242001SAdam Bratschi-Kaye .and_then(|len| ptr.checked_add(len))
964d4242001SAdam Bratschi-Kaye {
965c5675cc5SAlex Crichton Some(n) if n <= cx.memory().len() => cx.consume_fuel_array(len, size_of::<Val>())?,
966d4242001SAdam Bratschi-Kaye _ => bail!("list pointer/length out of bounds of memory"),
967d4242001SAdam Bratschi-Kaye }
9689034e101SAlex Crichton if ptr % usize::try_from(element_alignment)? != 0 {
969d4242001SAdam Bratschi-Kaye bail!("list pointer is not aligned")
970d4242001SAdam Bratschi-Kaye }
971d4242001SAdam Bratschi-Kaye
9729de6828eSAlex Crichton Ok(Val::List(
9739de6828eSAlex Crichton (0..len)
974d4242001SAdam Bratschi-Kaye .map(|index| {
975d4242001SAdam Bratschi-Kaye Val::load(
976d4242001SAdam Bratschi-Kaye cx,
977d4242001SAdam Bratschi-Kaye elem,
978d4242001SAdam Bratschi-Kaye &cx.memory()[ptr + (index * element_size)..][..element_size],
979d4242001SAdam Bratschi-Kaye )
980d4242001SAdam Bratschi-Kaye })
981d4242001SAdam Bratschi-Kaye .collect::<Result<_>>()?,
9829de6828eSAlex Crichton ))
983d4242001SAdam Bratschi-Kaye }
984d4242001SAdam Bratschi-Kaye
load_map(cx: &mut LiftContext<'_>, ty: TypeMapIndex, ptr: usize, len: usize) -> Result<Val>9851b59b579SYordis Prieto fn load_map(cx: &mut LiftContext<'_>, ty: TypeMapIndex, ptr: usize, len: usize) -> Result<Val> {
9861b59b579SYordis Prieto // Maps are stored as list<tuple<k, v>> in canonical ABI
9871b59b579SYordis Prieto let map_ty = &cx.types[ty];
9881b59b579SYordis Prieto let key_ty = map_ty.key;
9891b59b579SYordis Prieto let value_ty = map_ty.value;
9901b59b579SYordis Prieto
9911b59b579SYordis Prieto let key_abi = cx.types.canonical_abi(&key_ty);
9921b59b579SYordis Prieto let value_abi = cx.types.canonical_abi(&value_ty);
9931b59b579SYordis Prieto let key_size = usize::try_from(key_abi.size32).unwrap();
9941b59b579SYordis Prieto let value_size = usize::try_from(value_abi.size32).unwrap();
9951b59b579SYordis Prieto let value_offset = usize::try_from(map_ty.value_offset32).unwrap();
9961b59b579SYordis Prieto let tuple_alignment = map_ty.entry_abi.align32;
9971b59b579SYordis Prieto let tuple_size = usize::try_from(map_ty.entry_abi.size32).unwrap();
9981b59b579SYordis Prieto
9991b59b579SYordis Prieto // Bounds check
10001b59b579SYordis Prieto match len
10011b59b579SYordis Prieto .checked_mul(tuple_size)
10021b59b579SYordis Prieto .and_then(|len| ptr.checked_add(len))
10031b59b579SYordis Prieto {
10045d52f56cSAlex Crichton Some(n) if n <= cx.memory().len() => cx.consume_fuel_array(len, size_of::<(Val, Val)>())?,
10051b59b579SYordis Prieto _ => bail!("map pointer/length out of bounds of memory"),
10061b59b579SYordis Prieto }
10071b59b579SYordis Prieto if ptr % usize::try_from(tuple_alignment)? != 0 {
10081b59b579SYordis Prieto bail!("map pointer is not aligned")
10091b59b579SYordis Prieto }
10101b59b579SYordis Prieto
10111b59b579SYordis Prieto // Load each tuple (key, value) into a Vec
10121b59b579SYordis Prieto let mut map = Vec::with_capacity(len);
10131b59b579SYordis Prieto for index in 0..len {
10141b59b579SYordis Prieto let tuple_ptr = ptr + (index * tuple_size);
10151b59b579SYordis Prieto let key = Val::load(cx, key_ty, &cx.memory()[tuple_ptr..][..key_size])?;
10161b59b579SYordis Prieto let value = Val::load(
10171b59b579SYordis Prieto cx,
10181b59b579SYordis Prieto value_ty,
10191b59b579SYordis Prieto &cx.memory()[tuple_ptr + value_offset..][..value_size],
10201b59b579SYordis Prieto )?;
10211b59b579SYordis Prieto map.push((key, value));
10221b59b579SYordis Prieto }
10231b59b579SYordis Prieto
10241b59b579SYordis Prieto Ok(Val::Map(map))
10251b59b579SYordis Prieto }
10261b59b579SYordis Prieto
load_variant( cx: &mut LiftContext<'_>, info: &VariantInfo, mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>, bytes: &[u8], ) -> Result<(u32, Option<Box<Val>>)>1027d4242001SAdam Bratschi-Kaye fn load_variant(
1028d4242001SAdam Bratschi-Kaye cx: &mut LiftContext<'_>,
1029d4242001SAdam Bratschi-Kaye info: &VariantInfo,
1030d4242001SAdam Bratschi-Kaye mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
1031d4242001SAdam Bratschi-Kaye bytes: &[u8],
1032d4242001SAdam Bratschi-Kaye ) -> Result<(u32, Option<Box<Val>>)> {
1033d4242001SAdam Bratschi-Kaye let discriminant = match info.size {
10347dba8efdSNick Fitzgerald DiscriminantSize::Size1 => u32::from(u8::linear_lift_from_memory(
10357dba8efdSNick Fitzgerald cx,
10367dba8efdSNick Fitzgerald InterfaceType::U8,
10377dba8efdSNick Fitzgerald &bytes[..1],
10387dba8efdSNick Fitzgerald )?),
10397dba8efdSNick Fitzgerald DiscriminantSize::Size2 => u32::from(u16::linear_lift_from_memory(
10407dba8efdSNick Fitzgerald cx,
10417dba8efdSNick Fitzgerald InterfaceType::U16,
10427dba8efdSNick Fitzgerald &bytes[..2],
10437dba8efdSNick Fitzgerald )?),
10447dba8efdSNick Fitzgerald DiscriminantSize::Size4 => {
10457dba8efdSNick Fitzgerald u32::linear_lift_from_memory(cx, InterfaceType::U32, &bytes[..4])?
10467dba8efdSNick Fitzgerald }
1047d4242001SAdam Bratschi-Kaye };
1048b8a3e205SAlex Crichton let len = types.len();
1049b8a3e205SAlex Crichton let case_ty = types
1050b8a3e205SAlex Crichton .nth(discriminant as usize)
1051b8a3e205SAlex Crichton .ok_or_else(|| format_err!("discriminant {discriminant} out of range [0..{len})"))?;
1052d4242001SAdam Bratschi-Kaye let value = match case_ty {
1053d4242001SAdam Bratschi-Kaye Some(case_ty) => {
1054d4242001SAdam Bratschi-Kaye let payload_offset = usize::try_from(info.payload_offset32).unwrap();
1055d4242001SAdam Bratschi-Kaye let case_abi = cx.types.canonical_abi(&case_ty);
1056d4242001SAdam Bratschi-Kaye let case_size = usize::try_from(case_abi.size32).unwrap();
1057d4242001SAdam Bratschi-Kaye Some(Box::new(Val::load(
1058d4242001SAdam Bratschi-Kaye cx,
1059d4242001SAdam Bratschi-Kaye case_ty,
1060d4242001SAdam Bratschi-Kaye &bytes[payload_offset..][..case_size],
1061d4242001SAdam Bratschi-Kaye )?))
1062d4242001SAdam Bratschi-Kaye }
1063d4242001SAdam Bratschi-Kaye None => None,
1064d4242001SAdam Bratschi-Kaye };
1065d4242001SAdam Bratschi-Kaye Ok((discriminant, value))
1066d4242001SAdam Bratschi-Kaye }
1067d4242001SAdam Bratschi-Kaye
lift_variant( cx: &mut LiftContext<'_>, flatten_count: usize, mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>, src: &mut Iter<'_, ValRaw>, ) -> Result<(u32, Option<Box<Val>>)>1068d4242001SAdam Bratschi-Kaye fn lift_variant(
1069d4242001SAdam Bratschi-Kaye cx: &mut LiftContext<'_>,
1070d4242001SAdam Bratschi-Kaye flatten_count: usize,
1071d4242001SAdam Bratschi-Kaye mut types: impl ExactSizeIterator<Item = Option<InterfaceType>>,
107281a89169SAlex Crichton src: &mut Iter<'_, ValRaw>,
1073d4242001SAdam Bratschi-Kaye ) -> Result<(u32, Option<Box<Val>>)> {
1074d4242001SAdam Bratschi-Kaye let len = types.len();
1075d4242001SAdam Bratschi-Kaye let discriminant = next(src).get_u32();
1076d4242001SAdam Bratschi-Kaye let ty = types
1077d4242001SAdam Bratschi-Kaye .nth(discriminant as usize)
1078ff33e949SNick Fitzgerald .ok_or_else(|| format_err!("discriminant {discriminant} out of range [0..{len})"))?;
1079d4242001SAdam Bratschi-Kaye let (value, value_flat) = match ty {
1080d4242001SAdam Bratschi-Kaye Some(ty) => (
1081d4242001SAdam Bratschi-Kaye Some(Box::new(Val::lift(cx, ty, src)?)),
1082d4242001SAdam Bratschi-Kaye cx.types.canonical_abi(&ty).flat_count(usize::MAX).unwrap(),
1083d4242001SAdam Bratschi-Kaye ),
1084d4242001SAdam Bratschi-Kaye None => (None, 0),
1085d4242001SAdam Bratschi-Kaye };
1086d4242001SAdam Bratschi-Kaye for _ in (1 + value_flat)..flatten_count {
1087d4242001SAdam Bratschi-Kaye next(src);
1088d4242001SAdam Bratschi-Kaye }
1089d4242001SAdam Bratschi-Kaye Ok((discriminant, value))
1090d4242001SAdam Bratschi-Kaye }
1091d4242001SAdam Bratschi-Kaye
1092d4242001SAdam Bratschi-Kaye /// Lower a list with the specified element type and values.
lower_list<T>( cx: &mut LowerContext<'_, T>, element_type: InterfaceType, items: &[Val], ) -> Result<(usize, usize)>1093d4242001SAdam Bratschi-Kaye fn lower_list<T>(
1094d4242001SAdam Bratschi-Kaye cx: &mut LowerContext<'_, T>,
1095d4242001SAdam Bratschi-Kaye element_type: InterfaceType,
1096d4242001SAdam Bratschi-Kaye items: &[Val],
1097d4242001SAdam Bratschi-Kaye ) -> Result<(usize, usize)> {
1098d4242001SAdam Bratschi-Kaye let abi = cx.types.canonical_abi(&element_type);
10999034e101SAlex Crichton let elt_size = usize::try_from(abi.size32)?;
1100d4242001SAdam Bratschi-Kaye let elt_align = abi.align32;
1101d4242001SAdam Bratschi-Kaye let size = items
1102d4242001SAdam Bratschi-Kaye .len()
1103d4242001SAdam Bratschi-Kaye .checked_mul(elt_size)
110496e19700SNick Fitzgerald .ok_or_else(|| crate::format_err!("size overflow copying a list"))?;
1105d4242001SAdam Bratschi-Kaye let ptr = cx.realloc(0, 0, elt_align, size)?;
1106d4242001SAdam Bratschi-Kaye let mut element_ptr = ptr;
1107d4242001SAdam Bratschi-Kaye for item in items {
1108d4242001SAdam Bratschi-Kaye item.store(cx, element_type, element_ptr)?;
1109d4242001SAdam Bratschi-Kaye element_ptr += elt_size;
1110d4242001SAdam Bratschi-Kaye }
1111d4242001SAdam Bratschi-Kaye Ok((ptr, items.len()))
1112d4242001SAdam Bratschi-Kaye }
1113d4242001SAdam Bratschi-Kaye
11141b59b579SYordis Prieto /// Lower a map as list<tuple<k, v>> with the specified key and value types.
lower_map<T>( cx: &mut LowerContext<'_, T>, map_ty: &TypeMap, pairs: &[(Val, Val)], ) -> Result<(usize, usize)>11151b59b579SYordis Prieto fn lower_map<T>(
11161b59b579SYordis Prieto cx: &mut LowerContext<'_, T>,
11171b59b579SYordis Prieto map_ty: &TypeMap,
11181b59b579SYordis Prieto pairs: &[(Val, Val)],
11191b59b579SYordis Prieto ) -> Result<(usize, usize)> {
11201b59b579SYordis Prieto let key_type = map_ty.key;
11211b59b579SYordis Prieto let value_type = map_ty.value;
11221b59b579SYordis Prieto let value_offset = usize::try_from(map_ty.value_offset32).unwrap();
11231b59b579SYordis Prieto let tuple_align = map_ty.entry_abi.align32;
11241b59b579SYordis Prieto let tuple_size = usize::try_from(map_ty.entry_abi.size32).unwrap();
11251b59b579SYordis Prieto
11261b59b579SYordis Prieto let size = pairs
11271b59b579SYordis Prieto .len()
11281b59b579SYordis Prieto .checked_mul(tuple_size)
11291b59b579SYordis Prieto .ok_or_else(|| crate::format_err!("size overflow copying a map"))?;
11301b59b579SYordis Prieto let ptr = cx.realloc(0, 0, tuple_align, size)?;
11311b59b579SYordis Prieto
11321b59b579SYordis Prieto let mut tuple_ptr = ptr;
11331b59b579SYordis Prieto for (key, value) in pairs {
11341b59b579SYordis Prieto // Store key at tuple_ptr
11351b59b579SYordis Prieto key.store(cx, key_type, tuple_ptr)?;
11361b59b579SYordis Prieto // Store value at tuple_ptr + value_offset (properly aligned)
11371b59b579SYordis Prieto value.store(cx, value_type, tuple_ptr + value_offset)?;
11381b59b579SYordis Prieto tuple_ptr += tuple_size;
11391b59b579SYordis Prieto }
11401b59b579SYordis Prieto
11411b59b579SYordis Prieto Ok((ptr, pairs.len()))
11421b59b579SYordis Prieto }
11431b59b579SYordis Prieto
push_flags(ty: &TypeFlags, flags: &mut Vec<String>, mut offset: u32, mut bits: u32)11449de6828eSAlex Crichton fn push_flags(ty: &TypeFlags, flags: &mut Vec<String>, mut offset: u32, mut bits: u32) {
1145*39e910beSAlex Crichton while bits > 0 && usize::try_from(offset).unwrap() < ty.names.len() {
11469de6828eSAlex Crichton if bits & 1 != 0 {
11479de6828eSAlex Crichton flags.push(ty.names[offset as usize].clone());
11489de6828eSAlex Crichton }
11499de6828eSAlex Crichton bits >>= 1;
11509de6828eSAlex Crichton offset += 1;
11519de6828eSAlex Crichton }
11529de6828eSAlex Crichton }
11539de6828eSAlex Crichton
flags_to_storage(ty: &TypeFlags, flags: &[String]) -> Result<Vec<u32>>11549de6828eSAlex Crichton fn flags_to_storage(ty: &TypeFlags, flags: &[String]) -> Result<Vec<u32>> {
11559de6828eSAlex Crichton let mut storage = match FlagsSize::from_count(ty.names.len()) {
11569de6828eSAlex Crichton FlagsSize::Size0 => Vec::new(),
11579de6828eSAlex Crichton FlagsSize::Size1 | FlagsSize::Size2 => vec![0],
11589de6828eSAlex Crichton FlagsSize::Size4Plus(n) => vec![0; n.into()],
11599de6828eSAlex Crichton };
11609de6828eSAlex Crichton
11619de6828eSAlex Crichton for flag in flags {
11629de6828eSAlex Crichton let bit = ty
11639de6828eSAlex Crichton .names
11649de6828eSAlex Crichton .get_index_of(flag)
116596e19700SNick Fitzgerald .ok_or_else(|| crate::format_err!("unknown flag: `{flag}`"))?;
11669de6828eSAlex Crichton storage[bit / 32] |= 1 << (bit % 32);
11679de6828eSAlex Crichton }
11689de6828eSAlex Crichton Ok(storage)
11699de6828eSAlex Crichton }
11709de6828eSAlex Crichton
get_enum_discriminant(ty: &TypeEnum, n: &str) -> Result<u32>11719de6828eSAlex Crichton fn get_enum_discriminant(ty: &TypeEnum, n: &str) -> Result<u32> {
11729de6828eSAlex Crichton ty.names
11739de6828eSAlex Crichton .get_index_of(n)
117496e19700SNick Fitzgerald .ok_or_else(|| crate::format_err!("enum variant name `{n}` is not valid"))
11750bce0968SAlex Crichton .map(|i| i.try_into().unwrap())
11769de6828eSAlex Crichton }
11779de6828eSAlex Crichton
get_variant_discriminant<'a>( ty: &'a TypeVariant, name: &str, ) -> Result<(u32, &'a Option<InterfaceType>)>11789de6828eSAlex Crichton fn get_variant_discriminant<'a>(
11799de6828eSAlex Crichton ty: &'a TypeVariant,
11809de6828eSAlex Crichton name: &str,
11819de6828eSAlex Crichton ) -> Result<(u32, &'a Option<InterfaceType>)> {
11829de6828eSAlex Crichton let (i, _, ty) = ty
11839de6828eSAlex Crichton .cases
11849de6828eSAlex Crichton .get_full(name)
118596e19700SNick Fitzgerald .ok_or_else(|| crate::format_err!("unknown variant case: `{name}`"))?;
11860bce0968SAlex Crichton Ok((i.try_into().unwrap(), ty))
11879de6828eSAlex Crichton }
11889de6828eSAlex Crichton
next<'a>(src: &mut Iter<'a, ValRaw>) -> &'a ValRaw118981a89169SAlex Crichton fn next<'a>(src: &mut Iter<'a, ValRaw>) -> &'a ValRaw {
1190d4242001SAdam Bratschi-Kaye src.next().unwrap()
1191d4242001SAdam Bratschi-Kaye }
1192d4242001SAdam Bratschi-Kaye
next_mut<'a>(dst: &mut IterMut<'a, MaybeUninit<ValRaw>>) -> &'a mut MaybeUninit<ValRaw>119381a89169SAlex Crichton fn next_mut<'a>(dst: &mut IterMut<'a, MaybeUninit<ValRaw>>) -> &'a mut MaybeUninit<ValRaw> {
1194d4242001SAdam Bratschi-Kaye dst.next().unwrap()
1195d4242001SAdam Bratschi-Kaye }
11969de6828eSAlex Crichton
11979de6828eSAlex Crichton #[cold]
unexpected<T>(ty: InterfaceType, val: &Val) -> Result<T>11989de6828eSAlex Crichton fn unexpected<T>(ty: InterfaceType, val: &Val) -> Result<T> {
11999de6828eSAlex Crichton bail!(
12009de6828eSAlex Crichton "type mismatch: expected {}, found {}",
12019de6828eSAlex Crichton desc(&ty),
12029de6828eSAlex Crichton val.desc()
12039de6828eSAlex Crichton )
12049de6828eSAlex Crichton }
1205b221fca7SJoel Dice
1206b221fca7SJoel Dice /// Represents a component model `error-context`.
1207b221fca7SJoel Dice ///
1208b221fca7SJoel Dice /// Note that this type is not usable at this time as its implementation has not
1209b221fca7SJoel Dice /// been filled out. There are no operations on this and there's additionally no
1210b221fca7SJoel Dice /// ability to "drop" or deallocate this index.
1211b221fca7SJoel Dice //
1212b221fca7SJoel Dice // FIXME(#11161) this needs to be filled out implementation-wise
1213b221fca7SJoel Dice #[derive(Debug, Clone, PartialEq, Eq)]
1214b221fca7SJoel Dice pub struct ErrorContextAny(pub(crate) u32);
1215f586be11SAlex Crichton
1216f586be11SAlex Crichton impl From<bool> for Val {
from(b: bool) -> Self1217f586be11SAlex Crichton fn from(b: bool) -> Self {
1218f586be11SAlex Crichton Val::Bool(b)
1219f586be11SAlex Crichton }
1220f586be11SAlex Crichton }
1221f586be11SAlex Crichton
1222f586be11SAlex Crichton impl From<u8> for Val {
from(u: u8) -> Self1223f586be11SAlex Crichton fn from(u: u8) -> Self {
1224f586be11SAlex Crichton Val::U8(u)
1225f586be11SAlex Crichton }
1226f586be11SAlex Crichton }
1227f586be11SAlex Crichton
1228f586be11SAlex Crichton impl From<i8> for Val {
from(i: i8) -> Self1229f586be11SAlex Crichton fn from(i: i8) -> Self {
1230f586be11SAlex Crichton Val::S8(i)
1231f586be11SAlex Crichton }
1232f586be11SAlex Crichton }
1233f586be11SAlex Crichton
1234f586be11SAlex Crichton impl From<u16> for Val {
from(u: u16) -> Self1235f586be11SAlex Crichton fn from(u: u16) -> Self {
1236f586be11SAlex Crichton Val::U16(u)
1237f586be11SAlex Crichton }
1238f586be11SAlex Crichton }
1239f586be11SAlex Crichton
1240f586be11SAlex Crichton impl From<i16> for Val {
from(i: i16) -> Self1241f586be11SAlex Crichton fn from(i: i16) -> Self {
1242f586be11SAlex Crichton Val::S16(i)
1243f586be11SAlex Crichton }
1244f586be11SAlex Crichton }
1245f586be11SAlex Crichton
1246f586be11SAlex Crichton impl From<u32> for Val {
from(u: u32) -> Self1247f586be11SAlex Crichton fn from(u: u32) -> Self {
1248f586be11SAlex Crichton Val::U32(u)
1249f586be11SAlex Crichton }
1250f586be11SAlex Crichton }
1251f586be11SAlex Crichton
1252f586be11SAlex Crichton impl From<i32> for Val {
from(i: i32) -> Self1253f586be11SAlex Crichton fn from(i: i32) -> Self {
1254f586be11SAlex Crichton Val::S32(i)
1255f586be11SAlex Crichton }
1256f586be11SAlex Crichton }
1257f586be11SAlex Crichton
1258f586be11SAlex Crichton impl From<u64> for Val {
from(u: u64) -> Self1259f586be11SAlex Crichton fn from(u: u64) -> Self {
1260f586be11SAlex Crichton Val::U64(u)
1261f586be11SAlex Crichton }
1262f586be11SAlex Crichton }
1263f586be11SAlex Crichton
1264f586be11SAlex Crichton impl From<i64> for Val {
from(i: i64) -> Self1265f586be11SAlex Crichton fn from(i: i64) -> Self {
1266f586be11SAlex Crichton Val::S64(i)
1267f586be11SAlex Crichton }
1268f586be11SAlex Crichton }
1269f586be11SAlex Crichton
1270f586be11SAlex Crichton impl From<char> for Val {
from(i: char) -> Self1271f586be11SAlex Crichton fn from(i: char) -> Self {
1272f586be11SAlex Crichton Val::Char(i)
1273f586be11SAlex Crichton }
1274f586be11SAlex Crichton }
1275f586be11SAlex Crichton
1276f586be11SAlex Crichton impl From<String> for Val {
from(i: String) -> Self1277f586be11SAlex Crichton fn from(i: String) -> Self {
1278f586be11SAlex Crichton Val::String(i)
1279f586be11SAlex Crichton }
1280f586be11SAlex Crichton }
1281f586be11SAlex Crichton
1282f586be11SAlex Crichton impl From<ResourceAny> for Val {
from(i: ResourceAny) -> Self1283f586be11SAlex Crichton fn from(i: ResourceAny) -> Self {
1284f586be11SAlex Crichton Val::Resource(i)
1285f586be11SAlex Crichton }
1286f586be11SAlex Crichton }
1287f586be11SAlex Crichton
1288f586be11SAlex Crichton impl From<FutureAny> for Val {
from(i: FutureAny) -> Self1289f586be11SAlex Crichton fn from(i: FutureAny) -> Self {
1290f586be11SAlex Crichton Val::Future(i)
1291f586be11SAlex Crichton }
1292f586be11SAlex Crichton }
1293f586be11SAlex Crichton
1294f586be11SAlex Crichton impl From<StreamAny> for Val {
from(i: StreamAny) -> Self1295f586be11SAlex Crichton fn from(i: StreamAny) -> Self {
1296f586be11SAlex Crichton Val::Stream(i)
1297f586be11SAlex Crichton }
1298f586be11SAlex Crichton }
1299