1use crate::component::{MAX_FLAT_PARAMS, MAX_FLAT_RESULTS};
2use crate::prelude::*;
3use crate::{EntityType, ModuleInternedTypeIndex, ModuleTypes, PrimaryMap};
4use core::hash::{Hash, Hasher};
5use core::ops::Index;
6use serde_derive::{Deserialize, Serialize};
7use wasmparser::component_types::ComponentAnyTypeId;
8use wasmtime_component_util::{DiscriminantSize, FlagsSize};
9
10pub use crate::StaticModuleIndex;
11
12macro_rules! indices {
13 ($(
14 $(#[$a:meta])*
15 pub struct $name:ident(u32);
16 )*) => ($(
17 $(#[$a])*
18 #[derive(
19 Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
20 Serialize, Deserialize,
21 )]
22 #[repr(transparent)]
23 pub struct $name(u32);
24 cranelift_entity::entity_impl!($name);
25 )*);
26}
27
28indices! {
29 pub struct ComponentTypeIndex(u32);
37
38 pub struct ModuleIndex(u32);
40
41 pub struct ComponentIndex(u32);
43
44 pub struct ModuleInstanceIndex(u32);
46
47 pub struct ComponentInstanceIndex(u32);
49
50 pub struct ComponentFuncIndex(u32);
52
53 pub struct TypeComponentIndex(u32);
61
62 pub struct TypeComponentInstanceIndex(u32);
65
66 pub struct TypeModuleIndex(u32);
69
70 pub struct TypeFuncIndex(u32);
73
74 pub struct TypeRecordIndex(u32);
76 pub struct TypeVariantIndex(u32);
78 pub struct TypeTupleIndex(u32);
80 pub struct TypeFlagsIndex(u32);
82 pub struct TypeEnumIndex(u32);
84 pub struct TypeOptionIndex(u32);
87 pub struct TypeResultIndex(u32);
90 pub struct TypeListIndex(u32);
92 pub struct TypeFutureIndex(u32);
94 pub struct TypeFutureTableIndex(u32);
99 pub struct TypeStreamIndex(u32);
101 pub struct TypeStreamTableIndex(u32);
106
107 pub struct TypeComponentLocalErrorContextTableIndex(u32);
112
113 pub struct TypeComponentGlobalErrorContextTableIndex(u32);
119
120 pub struct TypeTaskReturnIndex(u32);
122
123 pub struct TypeResourceTableIndex(u32);
138
139 pub struct ResourceIndex(u32);
152
153 pub struct DefinedResourceIndex(u32);
159
160 pub struct ModuleUpvarIndex(u32);
167
168 pub struct ComponentUpvarIndex(u32);
170
171 pub struct StaticComponentIndex(u32);
173
174 pub struct RuntimeInstanceIndex(u32);
183
184 pub struct RuntimeComponentInstanceIndex(u32);
186
187 pub struct ImportIndex(u32);
192
193 pub struct RuntimeImportIndex(u32);
199
200 pub struct LoweredIndex(u32);
206
207 pub struct RuntimeMemoryIndex(u32);
215
216 pub struct RuntimeReallocIndex(u32);
218
219 pub struct RuntimeCallbackIndex(u32);
221
222 pub struct RuntimePostReturnIndex(u32);
224
225 pub struct TrampolineIndex(u32);
232
233 pub struct ExportIndex(u32);
235}
236
237pub use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex};
240
241#[derive(Debug, Clone, Copy)]
244#[allow(missing_docs, reason = "self-describing variants")]
245pub enum ComponentItem {
246 Func(ComponentFuncIndex),
247 Module(ModuleIndex),
248 Component(ComponentIndex),
249 ComponentInstance(ComponentInstanceIndex),
250 Type(ComponentAnyTypeId),
251}
252
253#[derive(Default, Serialize, Deserialize)]
259pub struct ComponentTypes {
260 pub(super) modules: PrimaryMap<TypeModuleIndex, TypeModule>,
261 pub(super) components: PrimaryMap<TypeComponentIndex, TypeComponent>,
262 pub(super) component_instances: PrimaryMap<TypeComponentInstanceIndex, TypeComponentInstance>,
263 pub(super) functions: PrimaryMap<TypeFuncIndex, TypeFunc>,
264 pub(super) lists: PrimaryMap<TypeListIndex, TypeList>,
265 pub(super) records: PrimaryMap<TypeRecordIndex, TypeRecord>,
266 pub(super) variants: PrimaryMap<TypeVariantIndex, TypeVariant>,
267 pub(super) tuples: PrimaryMap<TypeTupleIndex, TypeTuple>,
268 pub(super) enums: PrimaryMap<TypeEnumIndex, TypeEnum>,
269 pub(super) flags: PrimaryMap<TypeFlagsIndex, TypeFlags>,
270 pub(super) options: PrimaryMap<TypeOptionIndex, TypeOption>,
271 pub(super) results: PrimaryMap<TypeResultIndex, TypeResult>,
272 pub(super) resource_tables: PrimaryMap<TypeResourceTableIndex, TypeResourceTable>,
273 pub(super) module_types: Option<ModuleTypes>,
274 pub(super) futures: PrimaryMap<TypeFutureIndex, TypeFuture>,
275 pub(super) future_tables: PrimaryMap<TypeFutureTableIndex, TypeFutureTable>,
276 pub(super) streams: PrimaryMap<TypeStreamIndex, TypeStream>,
277 pub(super) stream_tables: PrimaryMap<TypeStreamTableIndex, TypeStreamTable>,
278 pub(super) error_context_tables:
279 PrimaryMap<TypeComponentLocalErrorContextTableIndex, TypeErrorContextTable>,
280 pub(super) task_returns: PrimaryMap<TypeTaskReturnIndex, TypeTaskReturn>,
281}
282
283impl ComponentTypes {
284 pub fn module_types(&self) -> &ModuleTypes {
286 self.module_types.as_ref().unwrap()
287 }
288
289 pub fn canonical_abi(&self, ty: &InterfaceType) -> &CanonicalAbiInfo {
291 match ty {
292 InterfaceType::U8 | InterfaceType::S8 | InterfaceType::Bool => {
293 &CanonicalAbiInfo::SCALAR1
294 }
295
296 InterfaceType::U16 | InterfaceType::S16 => &CanonicalAbiInfo::SCALAR2,
297
298 InterfaceType::U32
299 | InterfaceType::S32
300 | InterfaceType::Float32
301 | InterfaceType::Char
302 | InterfaceType::Own(_)
303 | InterfaceType::Borrow(_)
304 | InterfaceType::Future(_)
305 | InterfaceType::Stream(_)
306 | InterfaceType::ErrorContext(_) => &CanonicalAbiInfo::SCALAR4,
307
308 InterfaceType::U64 | InterfaceType::S64 | InterfaceType::Float64 => {
309 &CanonicalAbiInfo::SCALAR8
310 }
311
312 InterfaceType::String | InterfaceType::List(_) => &CanonicalAbiInfo::POINTER_PAIR,
313
314 InterfaceType::Record(i) => &self[*i].abi,
315 InterfaceType::Variant(i) => &self[*i].abi,
316 InterfaceType::Tuple(i) => &self[*i].abi,
317 InterfaceType::Flags(i) => &self[*i].abi,
318 InterfaceType::Enum(i) => &self[*i].abi,
319 InterfaceType::Option(i) => &self[*i].abi,
320 InterfaceType::Result(i) => &self[*i].abi,
321 }
322 }
323
324 pub fn push_resource_table(&mut self, table: TypeResourceTable) -> TypeResourceTableIndex {
326 self.resource_tables.push(table)
327 }
328}
329
330macro_rules! impl_index {
331 ($(impl Index<$ty:ident> for ComponentTypes { $output:ident => $field:ident })*) => ($(
332 impl core::ops::Index<$ty> for ComponentTypes {
333 type Output = $output;
334 #[inline]
335 fn index(&self, idx: $ty) -> &$output {
336 &self.$field[idx]
337 }
338 }
339
340 #[cfg(feature = "compile")]
341 impl core::ops::Index<$ty> for super::ComponentTypesBuilder {
342 type Output = $output;
343 #[inline]
344 fn index(&self, idx: $ty) -> &$output {
345 &self.component_types()[idx]
346 }
347 }
348 )*)
349}
350
351impl_index! {
352 impl Index<TypeModuleIndex> for ComponentTypes { TypeModule => modules }
353 impl Index<TypeComponentIndex> for ComponentTypes { TypeComponent => components }
354 impl Index<TypeComponentInstanceIndex> for ComponentTypes { TypeComponentInstance => component_instances }
355 impl Index<TypeFuncIndex> for ComponentTypes { TypeFunc => functions }
356 impl Index<TypeRecordIndex> for ComponentTypes { TypeRecord => records }
357 impl Index<TypeVariantIndex> for ComponentTypes { TypeVariant => variants }
358 impl Index<TypeTupleIndex> for ComponentTypes { TypeTuple => tuples }
359 impl Index<TypeEnumIndex> for ComponentTypes { TypeEnum => enums }
360 impl Index<TypeFlagsIndex> for ComponentTypes { TypeFlags => flags }
361 impl Index<TypeOptionIndex> for ComponentTypes { TypeOption => options }
362 impl Index<TypeResultIndex> for ComponentTypes { TypeResult => results }
363 impl Index<TypeListIndex> for ComponentTypes { TypeList => lists }
364 impl Index<TypeResourceTableIndex> for ComponentTypes { TypeResourceTable => resource_tables }
365 impl Index<TypeFutureIndex> for ComponentTypes { TypeFuture => futures }
366 impl Index<TypeStreamIndex> for ComponentTypes { TypeStream => streams }
367 impl Index<TypeFutureTableIndex> for ComponentTypes { TypeFutureTable => future_tables }
368 impl Index<TypeStreamTableIndex> for ComponentTypes { TypeStreamTable => stream_tables }
369 impl Index<TypeComponentLocalErrorContextTableIndex> for ComponentTypes { TypeErrorContextTable => error_context_tables }
370}
371
372impl<T> Index<T> for ComponentTypes
375where
376 ModuleTypes: Index<T>,
377{
378 type Output = <ModuleTypes as Index<T>>::Output;
379 fn index(&self, idx: T) -> &Self::Output {
380 self.module_types.as_ref().unwrap().index(idx)
381 }
382}
383
384#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
390pub enum TypeDef {
391 Component(TypeComponentIndex),
393 ComponentInstance(TypeComponentInstanceIndex),
395 ComponentFunc(TypeFuncIndex),
397 Interface(InterfaceType),
399 Module(TypeModuleIndex),
401 CoreFunc(ModuleInternedTypeIndex),
403 Resource(TypeResourceTableIndex),
408}
409
410impl TypeDef {
411 pub fn desc(&self) -> &str {
413 match self {
414 TypeDef::Component(_) => "component",
415 TypeDef::ComponentInstance(_) => "instance",
416 TypeDef::ComponentFunc(_) => "function",
417 TypeDef::Interface(_) => "type",
418 TypeDef::Module(_) => "core module",
419 TypeDef::CoreFunc(_) => "core function",
420 TypeDef::Resource(_) => "resource",
421 }
422 }
423}
424
425#[derive(Serialize, Deserialize, Default)]
435pub struct TypeModule {
436 pub imports: IndexMap<(String, String), EntityType>,
444
445 pub exports: IndexMap<String, EntityType>,
450}
451
452#[derive(Serialize, Deserialize, Default)]
454pub struct TypeComponent {
455 pub imports: IndexMap<String, TypeDef>,
457 pub exports: IndexMap<String, TypeDef>,
459}
460
461#[derive(Serialize, Deserialize, Default)]
466pub struct TypeComponentInstance {
467 pub exports: IndexMap<String, TypeDef>,
469}
470
471#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
473pub struct TypeFunc {
474 pub param_names: Vec<String>,
476 pub params: TypeTupleIndex,
478 pub results: TypeTupleIndex,
480 pub task_return_type32: TypeTaskReturnIndex,
482 pub task_return_type64: TypeTaskReturnIndex,
484}
485
486#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
489pub struct TypeTaskReturn {
490 pub params: Vec<FlatType>,
494}
495
496#[derive(Serialize, Deserialize, Copy, Clone, Hash, Eq, PartialEq, Debug)]
503#[allow(missing_docs, reason = "self-describing variants")]
504pub enum InterfaceType {
505 Bool,
506 S8,
507 U8,
508 S16,
509 U16,
510 S32,
511 U32,
512 S64,
513 U64,
514 Float32,
515 Float64,
516 Char,
517 String,
518 Record(TypeRecordIndex),
519 Variant(TypeVariantIndex),
520 List(TypeListIndex),
521 Tuple(TypeTupleIndex),
522 Flags(TypeFlagsIndex),
523 Enum(TypeEnumIndex),
524 Option(TypeOptionIndex),
525 Result(TypeResultIndex),
526 Own(TypeResourceTableIndex),
527 Borrow(TypeResourceTableIndex),
528 Future(TypeFutureTableIndex),
529 Stream(TypeStreamTableIndex),
530 ErrorContext(TypeComponentLocalErrorContextTableIndex),
531}
532
533impl From<&wasmparser::PrimitiveValType> for InterfaceType {
534 fn from(ty: &wasmparser::PrimitiveValType) -> InterfaceType {
535 match ty {
536 wasmparser::PrimitiveValType::Bool => InterfaceType::Bool,
537 wasmparser::PrimitiveValType::S8 => InterfaceType::S8,
538 wasmparser::PrimitiveValType::U8 => InterfaceType::U8,
539 wasmparser::PrimitiveValType::S16 => InterfaceType::S16,
540 wasmparser::PrimitiveValType::U16 => InterfaceType::U16,
541 wasmparser::PrimitiveValType::S32 => InterfaceType::S32,
542 wasmparser::PrimitiveValType::U32 => InterfaceType::U32,
543 wasmparser::PrimitiveValType::S64 => InterfaceType::S64,
544 wasmparser::PrimitiveValType::U64 => InterfaceType::U64,
545 wasmparser::PrimitiveValType::F32 => InterfaceType::Float32,
546 wasmparser::PrimitiveValType::F64 => InterfaceType::Float64,
547 wasmparser::PrimitiveValType::Char => InterfaceType::Char,
548 wasmparser::PrimitiveValType::String => InterfaceType::String,
549 }
550 }
551}
552
553#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
556pub struct CanonicalAbiInfo {
557 pub size32: u32,
559 pub align32: u32,
561 pub size64: u32,
563 pub align64: u32,
565 pub flat_count: Option<u8>,
572}
573
574impl Default for CanonicalAbiInfo {
575 fn default() -> CanonicalAbiInfo {
576 CanonicalAbiInfo {
577 size32: 0,
578 align32: 1,
579 size64: 0,
580 align64: 1,
581 flat_count: Some(0),
582 }
583 }
584}
585
586const fn align_to(a: u32, b: u32) -> u32 {
587 assert!(b.is_power_of_two());
588 (a + (b - 1)) & !(b - 1)
589}
590
591const fn max(a: u32, b: u32) -> u32 {
592 if a > b {
593 a
594 } else {
595 b
596 }
597}
598
599impl CanonicalAbiInfo {
600 const ZERO: CanonicalAbiInfo = CanonicalAbiInfo {
602 size32: 0,
603 align32: 1,
604 size64: 0,
605 align64: 1,
606 flat_count: Some(0),
607 };
608
609 pub const SCALAR1: CanonicalAbiInfo = CanonicalAbiInfo::scalar(1);
611 pub const SCALAR2: CanonicalAbiInfo = CanonicalAbiInfo::scalar(2);
613 pub const SCALAR4: CanonicalAbiInfo = CanonicalAbiInfo::scalar(4);
615 pub const SCALAR8: CanonicalAbiInfo = CanonicalAbiInfo::scalar(8);
617
618 const fn scalar(size: u32) -> CanonicalAbiInfo {
619 CanonicalAbiInfo {
620 size32: size,
621 align32: size,
622 size64: size,
623 align64: size,
624 flat_count: Some(1),
625 }
626 }
627
628 pub const POINTER_PAIR: CanonicalAbiInfo = CanonicalAbiInfo {
630 size32: 8,
631 align32: 4,
632 size64: 16,
633 align64: 8,
634 flat_count: Some(2),
635 };
636
637 pub fn record<'a>(fields: impl Iterator<Item = &'a CanonicalAbiInfo>) -> CanonicalAbiInfo {
639 let mut ret = CanonicalAbiInfo::default();
643 for field in fields {
644 ret.size32 = align_to(ret.size32, field.align32) + field.size32;
645 ret.align32 = ret.align32.max(field.align32);
646 ret.size64 = align_to(ret.size64, field.align64) + field.size64;
647 ret.align64 = ret.align64.max(field.align64);
648 ret.flat_count = add_flat(ret.flat_count, field.flat_count);
649 }
650 ret.size32 = align_to(ret.size32, ret.align32);
651 ret.size64 = align_to(ret.size64, ret.align64);
652 return ret;
653 }
654
655 pub const fn record_static(fields: &[CanonicalAbiInfo]) -> CanonicalAbiInfo {
657 let mut ret = CanonicalAbiInfo::ZERO;
661 let mut i = 0;
662 while i < fields.len() {
663 let field = &fields[i];
664 ret.size32 = align_to(ret.size32, field.align32) + field.size32;
665 ret.align32 = max(ret.align32, field.align32);
666 ret.size64 = align_to(ret.size64, field.align64) + field.size64;
667 ret.align64 = max(ret.align64, field.align64);
668 ret.flat_count = add_flat(ret.flat_count, field.flat_count);
669 i += 1;
670 }
671 ret.size32 = align_to(ret.size32, ret.align32);
672 ret.size64 = align_to(ret.size64, ret.align64);
673 return ret;
674 }
675
676 pub fn next_field32(&self, offset: &mut u32) -> u32 {
679 *offset = align_to(*offset, self.align32) + self.size32;
680 *offset - self.size32
681 }
682
683 pub fn next_field32_size(&self, offset: &mut usize) -> usize {
685 let cur = u32::try_from(*offset).unwrap();
686 let cur = align_to(cur, self.align32) + self.size32;
687 *offset = usize::try_from(cur).unwrap();
688 usize::try_from(cur - self.size32).unwrap()
689 }
690
691 pub fn next_field64(&self, offset: &mut u32) -> u32 {
694 *offset = align_to(*offset, self.align64) + self.size64;
695 *offset - self.size64
696 }
697
698 pub fn next_field64_size(&self, offset: &mut usize) -> usize {
700 let cur = u32::try_from(*offset).unwrap();
701 let cur = align_to(cur, self.align64) + self.size64;
702 *offset = usize::try_from(cur).unwrap();
703 usize::try_from(cur - self.size64).unwrap()
704 }
705
706 pub const fn flags(count: usize) -> CanonicalAbiInfo {
708 let (size, align, flat_count) = match FlagsSize::from_count(count) {
709 FlagsSize::Size0 => (0, 1, 0),
710 FlagsSize::Size1 => (1, 1, 1),
711 FlagsSize::Size2 => (2, 2, 1),
712 FlagsSize::Size4Plus(n) => ((n as u32) * 4, 4, n),
713 };
714 CanonicalAbiInfo {
715 size32: size,
716 align32: align,
717 size64: size,
718 align64: align,
719 flat_count: Some(flat_count),
720 }
721 }
722
723 fn variant<'a, I>(cases: I) -> CanonicalAbiInfo
724 where
725 I: IntoIterator<Item = Option<&'a CanonicalAbiInfo>>,
726 I::IntoIter: ExactSizeIterator,
727 {
728 let cases = cases.into_iter();
732 let discrim_size = u32::from(DiscriminantSize::from_count(cases.len()).unwrap());
733 let mut max_size32 = 0;
734 let mut max_align32 = discrim_size;
735 let mut max_size64 = 0;
736 let mut max_align64 = discrim_size;
737 let mut max_case_count = Some(0);
738 for case in cases {
739 if let Some(case) = case {
740 max_size32 = max_size32.max(case.size32);
741 max_align32 = max_align32.max(case.align32);
742 max_size64 = max_size64.max(case.size64);
743 max_align64 = max_align64.max(case.align64);
744 max_case_count = max_flat(max_case_count, case.flat_count);
745 }
746 }
747 CanonicalAbiInfo {
748 size32: align_to(
749 align_to(discrim_size, max_align32) + max_size32,
750 max_align32,
751 ),
752 align32: max_align32,
753 size64: align_to(
754 align_to(discrim_size, max_align64) + max_size64,
755 max_align64,
756 ),
757 align64: max_align64,
758 flat_count: add_flat(max_case_count, Some(1)),
759 }
760 }
761
762 pub const fn variant_static(cases: &[Option<CanonicalAbiInfo>]) -> CanonicalAbiInfo {
764 let discrim_size = match DiscriminantSize::from_count(cases.len()) {
768 Some(size) => size.byte_size(),
769 None => unreachable!(),
770 };
771 let mut max_size32 = 0;
772 let mut max_align32 = discrim_size;
773 let mut max_size64 = 0;
774 let mut max_align64 = discrim_size;
775 let mut max_case_count = Some(0);
776 let mut i = 0;
777 while i < cases.len() {
778 let case = &cases[i];
779 if let Some(case) = case {
780 max_size32 = max(max_size32, case.size32);
781 max_align32 = max(max_align32, case.align32);
782 max_size64 = max(max_size64, case.size64);
783 max_align64 = max(max_align64, case.align64);
784 max_case_count = max_flat(max_case_count, case.flat_count);
785 }
786 i += 1;
787 }
788 CanonicalAbiInfo {
789 size32: align_to(
790 align_to(discrim_size, max_align32) + max_size32,
791 max_align32,
792 ),
793 align32: max_align32,
794 size64: align_to(
795 align_to(discrim_size, max_align64) + max_size64,
796 max_align64,
797 ),
798 align64: max_align64,
799 flat_count: add_flat(max_case_count, Some(1)),
800 }
801 }
802
803 pub const fn enum_(cases: usize) -> CanonicalAbiInfo {
805 let discrim_size = match DiscriminantSize::from_count(cases) {
809 Some(size) => size.byte_size(),
810 None => unreachable!(),
811 };
812 CanonicalAbiInfo {
813 size32: discrim_size,
814 align32: discrim_size,
815 size64: discrim_size,
816 align64: discrim_size,
817 flat_count: Some(1),
818 }
819 }
820
821 pub fn flat_count(&self, max: usize) -> Option<usize> {
824 let flat = usize::from(self.flat_count?);
825 if flat > max {
826 None
827 } else {
828 Some(flat)
829 }
830 }
831}
832
833#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
835pub struct VariantInfo {
836 #[serde(with = "serde_discrim_size")]
838 pub size: DiscriminantSize,
839 pub payload_offset32: u32,
842 pub payload_offset64: u32,
845}
846
847impl VariantInfo {
848 pub fn new<'a, I>(cases: I) -> (VariantInfo, CanonicalAbiInfo)
851 where
852 I: IntoIterator<Item = Option<&'a CanonicalAbiInfo>>,
853 I::IntoIter: ExactSizeIterator,
854 {
855 let cases = cases.into_iter();
856 let size = DiscriminantSize::from_count(cases.len()).unwrap();
857 let abi = CanonicalAbiInfo::variant(cases);
858 (
859 VariantInfo {
860 size,
861 payload_offset32: align_to(u32::from(size), abi.align32),
862 payload_offset64: align_to(u32::from(size), abi.align64),
863 },
864 abi,
865 )
866 }
867 pub const fn new_static(cases: &[Option<CanonicalAbiInfo>]) -> VariantInfo {
869 let size = match DiscriminantSize::from_count(cases.len()) {
870 Some(size) => size,
871 None => unreachable!(),
872 };
873 let abi = CanonicalAbiInfo::variant_static(cases);
874 VariantInfo {
875 size,
876 payload_offset32: align_to(size.byte_size(), abi.align32),
877 payload_offset64: align_to(size.byte_size(), abi.align64),
878 }
879 }
880}
881
882mod serde_discrim_size {
883 use super::DiscriminantSize;
884 use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
885
886 pub fn serialize<S>(disc: &DiscriminantSize, ser: S) -> Result<S::Ok, S::Error>
887 where
888 S: Serializer,
889 {
890 u32::from(*disc).serialize(ser)
891 }
892
893 pub fn deserialize<'de, D>(deser: D) -> Result<DiscriminantSize, D::Error>
894 where
895 D: Deserializer<'de>,
896 {
897 match u32::deserialize(deser)? {
898 1 => Ok(DiscriminantSize::Size1),
899 2 => Ok(DiscriminantSize::Size2),
900 4 => Ok(DiscriminantSize::Size4),
901 _ => Err(D::Error::custom("invalid discriminant size")),
902 }
903 }
904}
905
906#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
910pub struct TypeRecord {
911 pub fields: Box<[RecordField]>,
913 pub abi: CanonicalAbiInfo,
915}
916
917#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
919pub struct RecordField {
920 pub name: String,
922 pub ty: InterfaceType,
924}
925
926#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)]
932pub struct TypeVariant {
933 pub cases: IndexMap<String, Option<InterfaceType>>,
935 pub abi: CanonicalAbiInfo,
937 pub info: VariantInfo,
939}
940
941impl Hash for TypeVariant {
942 fn hash<H: Hasher>(&self, h: &mut H) {
943 let TypeVariant { cases, abi, info } = self;
944 cases.len().hash(h);
945 for pair in cases {
946 pair.hash(h);
947 }
948 abi.hash(h);
949 info.hash(h);
950 }
951}
952
953#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
958pub struct TypeTuple {
959 pub types: Box<[InterfaceType]>,
961 pub abi: CanonicalAbiInfo,
963}
964
965#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)]
970pub struct TypeFlags {
971 pub names: IndexSet<String>,
973 pub abi: CanonicalAbiInfo,
975}
976
977impl Hash for TypeFlags {
978 fn hash<H: Hasher>(&self, h: &mut H) {
979 let TypeFlags { names, abi } = self;
980 names.len().hash(h);
981 for name in names {
982 name.hash(h);
983 }
984 abi.hash(h);
985 }
986}
987
988#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)]
994pub struct TypeEnum {
995 pub names: IndexSet<String>,
997 pub abi: CanonicalAbiInfo,
999 pub info: VariantInfo,
1001}
1002
1003impl Hash for TypeEnum {
1004 fn hash<H: Hasher>(&self, h: &mut H) {
1005 let TypeEnum { names, abi, info } = self;
1006 names.len().hash(h);
1007 for name in names {
1008 name.hash(h);
1009 }
1010 abi.hash(h);
1011 info.hash(h);
1012 }
1013}
1014
1015#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1017pub struct TypeOption {
1018 pub ty: InterfaceType,
1020 pub abi: CanonicalAbiInfo,
1022 pub info: VariantInfo,
1024}
1025
1026#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1028pub struct TypeResult {
1029 pub ok: Option<InterfaceType>,
1031 pub err: Option<InterfaceType>,
1033 pub abi: CanonicalAbiInfo,
1035 pub info: VariantInfo,
1037}
1038
1039#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1041pub struct TypeFuture {
1042 pub payload: Option<InterfaceType>,
1044}
1045
1046#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1048pub struct TypeFutureTable {
1049 pub ty: TypeFutureIndex,
1051 pub instance: RuntimeComponentInstanceIndex,
1053}
1054
1055#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1057pub struct TypeStream {
1058 pub payload: Option<InterfaceType>,
1060}
1061
1062#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1064pub struct TypeStreamTable {
1065 pub ty: TypeStreamIndex,
1067 pub instance: RuntimeComponentInstanceIndex,
1069}
1070
1071#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1073pub struct TypeErrorContextTable {
1074 pub instance: RuntimeComponentInstanceIndex,
1076}
1077
1078#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1080pub struct TypeResourceTable {
1081 pub ty: ResourceIndex,
1086
1087 pub instance: RuntimeComponentInstanceIndex,
1089}
1090
1091#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1093pub struct TypeList {
1094 pub element: InterfaceType,
1096}
1097
1098pub const MAX_FLAT_TYPES: usize = if MAX_FLAT_PARAMS > MAX_FLAT_RESULTS {
1100 MAX_FLAT_PARAMS
1101} else {
1102 MAX_FLAT_RESULTS
1103};
1104
1105const fn add_flat(a: Option<u8>, b: Option<u8>) -> Option<u8> {
1106 const MAX: u8 = MAX_FLAT_TYPES as u8;
1107 let sum = match (a, b) {
1108 (Some(a), Some(b)) => match a.checked_add(b) {
1109 Some(c) => c,
1110 None => return None,
1111 },
1112 _ => return None,
1113 };
1114 if sum > MAX {
1115 None
1116 } else {
1117 Some(sum)
1118 }
1119}
1120
1121const fn max_flat(a: Option<u8>, b: Option<u8>) -> Option<u8> {
1122 match (a, b) {
1123 (Some(a), Some(b)) => {
1124 if a > b {
1125 Some(a)
1126 } else {
1127 Some(b)
1128 }
1129 }
1130 _ => None,
1131 }
1132}
1133
1134pub struct FlatTypes<'a> {
1136 pub memory32: &'a [FlatType],
1138 pub memory64: &'a [FlatType],
1140}
1141
1142impl FlatTypes<'_> {
1143 pub fn len(&self) -> usize {
1147 assert_eq!(self.memory32.len(), self.memory64.len());
1148 self.memory32.len()
1149 }
1150}
1151
1152#[derive(Serialize, Deserialize, Hash, Debug, PartialEq, Eq, Copy, Clone)]
1156#[allow(missing_docs, reason = "self-describing variants")]
1157pub enum FlatType {
1158 I32,
1159 I64,
1160 F32,
1161 F64,
1162}