1use super::{
4 component::{ComponentState, ExternKind},
5 core::Module,
6};
7use crate::{collections::map::Entry, AbstractHeapType};
8use crate::{prelude::*, CompositeInnerType};
9use crate::{validator::names::KebabString, HeapType, ValidatorId};
10use crate::{
11 BinaryReaderError, Export, ExternalKind, FuncType, GlobalType, Import, Matches, MemoryType,
12 PackedIndex, PrimitiveValType, RecGroup, RefType, Result, SubType, TableType, TypeRef,
13 UnpackedIndex, ValType, WithRecGroup,
14};
15use alloc::sync::Arc;
16use core::ops::{Deref, DerefMut, Index, Range};
17use core::sync::atomic::{AtomicUsize, Ordering};
18use core::{
19 borrow::Borrow,
20 hash::{Hash, Hasher},
21 mem,
22};
23
24const MAX_FLAT_FUNC_PARAMS: usize = 16;
29const MAX_FLAT_FUNC_RESULTS: usize = 1;
34
35const MAX_LOWERED_TYPES: usize = MAX_FLAT_FUNC_PARAMS + 1;
37
38pub(crate) struct LoweredTypes {
40 types: [ValType; MAX_LOWERED_TYPES],
41 len: usize,
42 max: usize,
43}
44
45impl LoweredTypes {
46 fn new(max: usize) -> Self {
47 assert!(max <= MAX_LOWERED_TYPES);
48 Self {
49 types: [ValType::I32; MAX_LOWERED_TYPES],
50 len: 0,
51 max,
52 }
53 }
54
55 fn len(&self) -> usize {
56 self.len
57 }
58
59 fn maxed(&self) -> bool {
60 self.len == self.max
61 }
62
63 fn get_mut(&mut self, index: usize) -> Option<&mut ValType> {
64 if index < self.len {
65 Some(&mut self.types[index])
66 } else {
67 None
68 }
69 }
70
71 fn push(&mut self, ty: ValType) -> bool {
72 if self.maxed() {
73 return false;
74 }
75
76 self.types[self.len] = ty;
77 self.len += 1;
78 true
79 }
80
81 fn clear(&mut self) {
82 self.len = 0;
83 }
84
85 pub fn as_slice(&self) -> &[ValType] {
86 &self.types[..self.len]
87 }
88
89 pub fn iter(&self) -> impl Iterator<Item = ValType> + '_ {
90 self.as_slice().iter().copied()
91 }
92}
93
94pub(crate) struct LoweringInfo {
96 pub(crate) params: LoweredTypes,
97 pub(crate) results: LoweredTypes,
98 pub(crate) requires_memory: bool,
99 pub(crate) requires_realloc: bool,
100}
101
102impl LoweringInfo {
103 pub(crate) fn into_func_type(self) -> FuncType {
104 FuncType::new(
105 self.params.as_slice().iter().copied(),
106 self.results.as_slice().iter().copied(),
107 )
108 }
109}
110
111impl Default for LoweringInfo {
112 fn default() -> Self {
113 Self {
114 params: LoweredTypes::new(MAX_FLAT_FUNC_PARAMS),
115 results: LoweredTypes::new(MAX_FLAT_FUNC_RESULTS),
116 requires_memory: false,
117 requires_realloc: false,
118 }
119 }
120}
121
122fn push_primitive_wasm_types(ty: &PrimitiveValType, lowered_types: &mut LoweredTypes) -> bool {
123 match ty {
124 PrimitiveValType::Bool
125 | PrimitiveValType::S8
126 | PrimitiveValType::U8
127 | PrimitiveValType::S16
128 | PrimitiveValType::U16
129 | PrimitiveValType::S32
130 | PrimitiveValType::U32
131 | PrimitiveValType::Char => lowered_types.push(ValType::I32),
132 PrimitiveValType::S64 | PrimitiveValType::U64 => lowered_types.push(ValType::I64),
133 PrimitiveValType::F32 => lowered_types.push(ValType::F32),
134 PrimitiveValType::F64 => lowered_types.push(ValType::F64),
135 PrimitiveValType::String => {
136 lowered_types.push(ValType::I32) && lowered_types.push(ValType::I32)
137 }
138 }
139}
140
141pub trait TypeIdentifier: core::fmt::Debug + Copy + Eq + Sized + 'static {
147 type Data: TypeData<Id = Self>;
149
150 #[doc(hidden)]
152 fn from_index(index: u32) -> Self;
153
154 #[doc(hidden)]
157 fn list(types: &TypeList) -> &SnapshotList<Self::Data>;
158
159 #[doc(hidden)]
162 fn list_mut(types: &mut TypeList) -> &mut SnapshotList<Self::Data>;
163
164 #[doc(hidden)]
166 fn index(&self) -> usize;
167}
168
169pub trait TypeData: core::fmt::Debug {
174 type Id: TypeIdentifier<Data = Self>;
176
177 #[doc(hidden)]
179 fn type_info(&self, types: &TypeList) -> TypeInfo;
180}
181
182pub trait Aliasable {
184 #[doc(hidden)]
185 fn alias_id(&self) -> u32;
186
187 #[doc(hidden)]
188 fn set_alias_id(&mut self, alias_id: u32);
189}
190
191const NO_ALIAS: u32 = u32::MAX;
198
199macro_rules! define_type_id {
200 ($name:ident, $data:ty, $list:ident, $type_str:expr) => {
201 #[doc = "Represents a unique identifier for a "]
202 #[doc = $type_str]
203 #[doc = " type known to a [`crate::Validator`]."]
204 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
205 #[repr(C)] pub struct $name {
207 index: u32,
209 }
210
211 impl TypeIdentifier for $name {
212 type Data = $data;
213
214 fn from_index(index: u32) -> Self {
215 $name { index }
216 }
217
218 fn list(types: &TypeList) -> &SnapshotList<Self::Data> {
219 &types.$list
220 }
221
222 fn list_mut(types: &mut TypeList) -> &mut SnapshotList<Self::Data> {
223 &mut types.$list
224 }
225
226 fn index(&self) -> usize {
227 usize::try_from(self.index).unwrap()
228 }
229 }
230
231 impl Aliasable for $name {
232 fn alias_id(&self) -> u32 {
233 NO_ALIAS
234 }
235
236 fn set_alias_id(&mut self, _: u32) {}
237 }
238
239 const _: () = {
242 assert!(core::mem::size_of::<$name>() <= 4);
243 };
244 };
245}
246
247pub enum CoreType {
249 Sub(SubType),
251
252 Module(ModuleType),
257}
258
259#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
262#[repr(C)]
263pub struct CoreTypeId {
264 index: u32,
265}
266
267const _: () = {
268 assert!(core::mem::size_of::<CoreTypeId>() <= 4);
269};
270
271impl TypeIdentifier for CoreTypeId {
272 type Data = SubType;
273
274 fn from_index(index: u32) -> Self {
275 CoreTypeId { index }
276 }
277
278 fn list(types: &TypeList) -> &SnapshotList<Self::Data> {
279 &types.core_types
280 }
281
282 fn list_mut(types: &mut TypeList) -> &mut SnapshotList<Self::Data> {
283 &mut types.core_types
284 }
285
286 fn index(&self) -> usize {
287 usize::try_from(self.index).unwrap()
288 }
289}
290
291impl TypeData for SubType {
292 type Id = CoreTypeId;
293
294 fn type_info(&self, _types: &TypeList) -> TypeInfo {
295 let size = 1 + match &self.composite_type.inner {
297 CompositeInnerType::Func(ty) => 1 + (ty.params().len() + ty.results().len()) as u32,
298 CompositeInnerType::Array(_) => 2,
299 CompositeInnerType::Struct(ty) => 1 + 2 * ty.fields.len() as u32,
300 };
301 TypeInfo::core(size)
302 }
303}
304
305impl CoreType {
306 pub fn unwrap_sub(&self) -> &SubType {
308 match self {
309 CoreType::Sub(s) => s,
310 CoreType::Module(_) => panic!("`unwrap_sub` on module type"),
311 }
312 }
313
314 pub fn unwrap_func(&self) -> &FuncType {
316 match &self.unwrap_sub().composite_type.inner {
317 CompositeInnerType::Func(f) => f,
318 CompositeInnerType::Array(_) | CompositeInnerType::Struct(_) => {
319 panic!("`unwrap_func` on non-func composite type")
320 }
321 }
322 }
323
324 pub fn unwrap_module(&self) -> &ModuleType {
326 match self {
327 CoreType::Module(m) => m,
328 CoreType::Sub(_) => panic!("`unwrap_module` on a subtype"),
329 }
330 }
331}
332
333macro_rules! define_wrapper_id {
334 (
335 $(#[$outer_attrs:meta])*
336 pub enum $name:ident {
337 $(
338 #[unwrap = $unwrap:ident]
339 $(#[$inner_attrs:meta])*
340 $variant:ident ( $inner:ty ) ,
341 )*
342 }
343 ) => {
344 $(#[$outer_attrs])*
345 pub enum $name {
346 $(
347 $(#[$inner_attrs])*
348 $variant ( $inner ) ,
349 )*
350 }
351
352 $(
353 impl From<$inner> for $name {
354 #[inline]
355 fn from(x: $inner) -> Self {
356 Self::$variant(x)
357 }
358 }
359
360 impl TryFrom<$name> for $inner {
361 type Error = ();
362
363 #[inline]
364 fn try_from(x: $name) -> Result<Self, Self::Error> {
365 match x {
366 $name::$variant(x) => Ok(x),
367 _ => Err(())
368 }
369 }
370 }
371 )*
372
373 impl $name {
374 $(
375 #[doc = "Unwrap a `"]
376 #[doc = stringify!($inner)]
377 #[doc = "` or panic."]
378 #[inline]
379 pub fn $unwrap(self) -> $inner {
380 <$inner>::try_from(self).unwrap()
381 }
382 )*
383 }
384 };
385}
386
387macro_rules! define_transitive_conversions {
388 (
389 $(
390 $outer:ty,
391 $middle:ty,
392 $inner:ty,
393 $unwrap:ident;
394 )*
395 ) => {
396 $(
397 impl From<$inner> for $outer {
398 #[inline]
399 fn from(x: $inner) -> Self {
400 <$middle>::from(x).into()
401 }
402 }
403
404 impl TryFrom<$outer> for $inner {
405 type Error = ();
406
407 #[inline]
408 fn try_from(x: $outer) -> Result<Self, Self::Error> {
409 let middle = <$middle>::try_from(x)?;
410 <$inner>::try_from(middle)
411 }
412 }
413
414 impl $outer {
415 #[doc = "Unwrap a `"]
416 #[doc = stringify!($inner)]
417 #[doc = "` or panic."]
418 #[inline]
419 pub fn $unwrap(self) -> $inner {
420 <$inner>::try_from(self).unwrap()
421 }
422 }
423 )*
424 };
425}
426
427define_wrapper_id! {
428 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
430 pub enum AnyTypeId {
431 #[unwrap = unwrap_component_core_type]
432 Core(ComponentCoreTypeId),
434
435 #[unwrap = unwrap_component_any_type]
436 Component(ComponentAnyTypeId),
438 }
439}
440
441define_transitive_conversions! {
442 AnyTypeId, ComponentCoreTypeId, CoreTypeId, unwrap_core_type;
443 AnyTypeId, ComponentCoreTypeId, ComponentCoreModuleTypeId, unwrap_component_core_module_type;
444 AnyTypeId, ComponentAnyTypeId, AliasableResourceId, unwrap_aliasable_resource;
445 AnyTypeId, ComponentAnyTypeId, ComponentDefinedTypeId, unwrap_component_defined_type;
446 AnyTypeId, ComponentAnyTypeId, ComponentFuncTypeId, unwrap_component_func_type;
447 AnyTypeId, ComponentAnyTypeId, ComponentInstanceTypeId, unwrap_component_instance_type;
448 AnyTypeId, ComponentAnyTypeId, ComponentTypeId, unwrap_component_type;
449}
450
451impl AnyTypeId {
452 pub fn peel_alias(&self, types: &Types) -> Option<Self> {
455 match *self {
456 Self::Core(id) => id.peel_alias(types).map(Self::Core),
457 Self::Component(id) => types.peel_alias(id).map(Self::Component),
458 }
459 }
460}
461
462define_wrapper_id! {
463 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
465 pub enum ComponentCoreTypeId {
466 #[unwrap = unwrap_sub]
467 Sub(CoreTypeId),
469
470 #[unwrap = unwrap_module]
471 Module(ComponentCoreModuleTypeId),
473 }
474}
475
476impl ComponentCoreTypeId {
477 pub fn peel_alias(&self, types: &Types) -> Option<Self> {
480 match *self {
481 Self::Sub(_) => None,
482 Self::Module(id) => types.peel_alias(id).map(Self::Module),
483 }
484 }
485}
486
487#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
489pub struct AliasableResourceId {
490 id: ResourceId,
491 alias_id: u32,
492}
493
494impl Aliasable for AliasableResourceId {
495 fn alias_id(&self) -> u32 {
496 self.alias_id
497 }
498
499 fn set_alias_id(&mut self, alias_id: u32) {
500 self.alias_id = alias_id;
501 }
502}
503
504impl AliasableResourceId {
505 pub fn with_resource_id(&self, id: ResourceId) -> Self {
508 Self {
509 id,
510 alias_id: self.alias_id,
511 }
512 }
513
514 pub fn resource(&self) -> ResourceId {
516 self.id
517 }
518
519 pub(crate) fn resource_mut(&mut self) -> &mut ResourceId {
520 &mut self.id
521 }
522}
523
524define_wrapper_id! {
525 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
527 pub enum ComponentAnyTypeId {
528 #[unwrap = unwrap_resource]
529 Resource(AliasableResourceId),
531
532 #[unwrap = unwrap_defined]
533 Defined(ComponentDefinedTypeId),
535
536 #[unwrap = unwrap_func]
537 Func(ComponentFuncTypeId),
539
540 #[unwrap = unwrap_instance]
541 Instance(ComponentInstanceTypeId),
543
544 #[unwrap = unwrap_component]
545 Component(ComponentTypeId),
547 }
548}
549
550impl Aliasable for ComponentAnyTypeId {
551 fn alias_id(&self) -> u32 {
552 match self {
553 ComponentAnyTypeId::Resource(x) => x.alias_id(),
554 ComponentAnyTypeId::Defined(x) => x.alias_id(),
555 ComponentAnyTypeId::Func(x) => x.alias_id(),
556 ComponentAnyTypeId::Instance(x) => x.alias_id(),
557 ComponentAnyTypeId::Component(x) => x.alias_id(),
558 }
559 }
560
561 fn set_alias_id(&mut self, alias_id: u32) {
562 match self {
563 ComponentAnyTypeId::Resource(x) => x.set_alias_id(alias_id),
564 ComponentAnyTypeId::Defined(x) => x.set_alias_id(alias_id),
565 ComponentAnyTypeId::Func(x) => x.set_alias_id(alias_id),
566 ComponentAnyTypeId::Instance(x) => x.set_alias_id(alias_id),
567 ComponentAnyTypeId::Component(x) => x.set_alias_id(alias_id),
568 }
569 }
570}
571
572impl ComponentAnyTypeId {
573 pub(crate) fn info(&self, types: &TypeList) -> TypeInfo {
574 match *self {
575 Self::Resource(_) => TypeInfo::new(),
576 Self::Defined(id) => types[id].type_info(types),
577 Self::Func(id) => types[id].type_info(types),
578 Self::Instance(id) => types[id].type_info(types),
579 Self::Component(id) => types[id].type_info(types),
580 }
581 }
582
583 pub(crate) fn desc(&self) -> &'static str {
584 match self {
585 Self::Resource(_) => "resource",
586 Self::Defined(_) => "defined type",
587 Self::Func(_) => "func",
588 Self::Instance(_) => "instance",
589 Self::Component(_) => "component",
590 }
591 }
592}
593
594define_type_id!(
595 RecGroupId,
596 Range<CoreTypeId>,
597 rec_group_elements,
598 "recursion group"
599);
600
601impl TypeData for Range<CoreTypeId> {
602 type Id = RecGroupId;
603
604 fn type_info(&self, _types: &TypeList) -> TypeInfo {
605 let size = self.end.index() - self.start.index();
606 TypeInfo::core(u32::try_from(size).unwrap())
607 }
608}
609
610define_type_id!(ComponentTypeId, ComponentType, components, "component");
611
612define_type_id!(
613 ComponentValueTypeId,
614 ComponentValType,
615 component_values,
616 "component value"
617);
618
619define_type_id!(
620 ComponentInstanceTypeId,
621 ComponentInstanceType,
622 component_instances,
623 "component instance"
624);
625
626define_type_id!(
627 ComponentFuncTypeId,
628 ComponentFuncType,
629 component_funcs,
630 "component function"
631);
632
633define_type_id!(
634 ComponentCoreInstanceTypeId,
635 InstanceType,
636 core_instances,
637 "component's core instance"
638);
639
640define_type_id!(
641 ComponentCoreModuleTypeId,
642 ModuleType,
643 core_modules,
644 "component's core module"
645);
646
647#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
650#[repr(C)]
651pub struct ComponentDefinedTypeId {
652 index: u32,
653 alias_id: u32,
654}
655
656const _: () = {
657 assert!(core::mem::size_of::<ComponentDefinedTypeId>() <= 8);
658};
659
660impl TypeIdentifier for ComponentDefinedTypeId {
661 type Data = ComponentDefinedType;
662
663 fn from_index(index: u32) -> Self {
664 ComponentDefinedTypeId {
665 index,
666 alias_id: NO_ALIAS,
667 }
668 }
669
670 fn list(types: &TypeList) -> &SnapshotList<Self::Data> {
671 &types.component_defined_types
672 }
673
674 fn list_mut(types: &mut TypeList) -> &mut SnapshotList<Self::Data> {
675 &mut types.component_defined_types
676 }
677
678 fn index(&self) -> usize {
679 usize::try_from(self.index).unwrap()
680 }
681}
682
683impl Aliasable for ComponentDefinedTypeId {
684 fn alias_id(&self) -> u32 {
685 self.alias_id
686 }
687
688 fn set_alias_id(&mut self, alias_id: u32) {
689 self.alias_id = alias_id;
690 }
691}
692
693#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
716#[doc(hidden)]
718pub struct TypeInfo(u32);
719
720impl TypeInfo {
721 pub(crate) fn new() -> TypeInfo {
726 TypeInfo::_new(1, false)
727 }
728
729 pub(crate) fn borrow() -> TypeInfo {
732 TypeInfo::_new(1, true)
733 }
734
735 pub(crate) fn core(size: u32) -> TypeInfo {
738 TypeInfo::_new(size, false)
739 }
740
741 fn _new(size: u32, contains_borrow: bool) -> TypeInfo {
742 assert!(size < (1 << 24));
743 TypeInfo(size | ((contains_borrow as u32) << 31))
744 }
745
746 pub(crate) fn combine(&mut self, other: TypeInfo, offset: usize) -> Result<()> {
755 *self = TypeInfo::_new(
756 super::combine_type_sizes(self.size(), other.size(), offset)?,
757 self.contains_borrow() || other.contains_borrow(),
758 );
759 Ok(())
760 }
761
762 pub(crate) fn size(&self) -> u32 {
763 self.0 & 0xffffff
764 }
765
766 pub(crate) fn contains_borrow(&self) -> bool {
767 (self.0 >> 31) != 0
768 }
769}
770
771#[derive(Debug, Clone, Copy)]
773pub enum ComponentValType {
774 Primitive(PrimitiveValType),
776 Type(ComponentDefinedTypeId),
778}
779
780impl TypeData for ComponentValType {
781 type Id = ComponentValueTypeId;
782
783 fn type_info(&self, types: &TypeList) -> TypeInfo {
784 match self {
785 ComponentValType::Primitive(_) => TypeInfo::new(),
786 ComponentValType::Type(id) => types[*id].type_info(types),
787 }
788 }
789}
790
791impl ComponentValType {
792 pub(crate) fn contains_ptr(&self, types: &TypeList) -> bool {
793 match self {
794 ComponentValType::Primitive(ty) => ty.contains_ptr(),
795 ComponentValType::Type(ty) => types[*ty].contains_ptr(types),
796 }
797 }
798
799 fn push_wasm_types(&self, types: &TypeList, lowered_types: &mut LoweredTypes) -> bool {
800 match self {
801 Self::Primitive(ty) => push_primitive_wasm_types(ty, lowered_types),
802 Self::Type(id) => types[*id].push_wasm_types(types, lowered_types),
803 }
804 }
805
806 pub(crate) fn info(&self, types: &TypeList) -> TypeInfo {
807 match self {
808 Self::Primitive(_) => TypeInfo::new(),
809 Self::Type(id) => types[*id].type_info(types),
810 }
811 }
812}
813
814#[derive(Debug, Clone, Copy)]
816pub enum EntityType {
817 Func(CoreTypeId),
819 Table(TableType),
821 Memory(MemoryType),
823 Global(GlobalType),
825 Tag(CoreTypeId),
827}
828
829impl EntityType {
830 pub(crate) fn desc(&self) -> &'static str {
831 match self {
832 Self::Func(_) => "func",
833 Self::Table(_) => "table",
834 Self::Memory(_) => "memory",
835 Self::Global(_) => "global",
836 Self::Tag(_) => "tag",
837 }
838 }
839
840 pub(crate) fn info(&self, types: &TypeList) -> TypeInfo {
841 match self {
842 Self::Func(id) | Self::Tag(id) => types[*id].type_info(types),
843 Self::Table(_) | Self::Memory(_) | Self::Global(_) => TypeInfo::new(),
844 }
845 }
846}
847
848trait ModuleImportKey {
849 fn module(&self) -> &str;
850 fn name(&self) -> &str;
851}
852
853impl<'a> Borrow<dyn ModuleImportKey + 'a> for (String, String) {
854 fn borrow(&self) -> &(dyn ModuleImportKey + 'a) {
855 self
856 }
857}
858
859impl Hash for (dyn ModuleImportKey + '_) {
860 fn hash<H: Hasher>(&self, state: &mut H) {
861 self.module().hash(state);
862 self.name().hash(state);
863 }
864}
865
866impl PartialEq for (dyn ModuleImportKey + '_) {
867 fn eq(&self, other: &Self) -> bool {
868 self.module() == other.module() && self.name() == other.name()
869 }
870}
871
872impl Eq for (dyn ModuleImportKey + '_) {}
873
874impl Ord for (dyn ModuleImportKey + '_) {
875 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
876 match self.module().cmp(other.module()) {
877 core::cmp::Ordering::Equal => (),
878 order => return order,
879 };
880 self.name().cmp(other.name())
881 }
882}
883
884impl PartialOrd for (dyn ModuleImportKey + '_) {
885 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
886 Some(self.cmp(other))
887 }
888}
889
890impl ModuleImportKey for (String, String) {
891 fn module(&self) -> &str {
892 &self.0
893 }
894
895 fn name(&self) -> &str {
896 &self.1
897 }
898}
899
900impl ModuleImportKey for (&str, &str) {
901 fn module(&self) -> &str {
902 self.0
903 }
904
905 fn name(&self) -> &str {
906 self.1
907 }
908}
909
910#[derive(Debug, Clone)]
912pub struct ModuleType {
913 pub(crate) info: TypeInfo,
915 pub imports: IndexMap<(String, String), EntityType>,
917 pub exports: IndexMap<String, EntityType>,
919}
920
921impl TypeData for ModuleType {
922 type Id = ComponentCoreModuleTypeId;
923
924 fn type_info(&self, _types: &TypeList) -> TypeInfo {
925 self.info
926 }
927}
928
929impl ModuleType {
930 pub fn lookup_import(&self, module: &str, name: &str) -> Option<&EntityType> {
934 self.imports.get(&(module, name) as &dyn ModuleImportKey)
935 }
936}
937
938#[derive(Debug, Clone)]
940pub enum CoreInstanceTypeKind {
941 Instantiated(ComponentCoreModuleTypeId),
943
944 Exports(IndexMap<String, EntityType>),
946}
947
948#[derive(Debug, Clone)]
950pub struct InstanceType {
951 pub(crate) info: TypeInfo,
953 pub kind: CoreInstanceTypeKind,
955}
956
957impl TypeData for InstanceType {
958 type Id = ComponentCoreInstanceTypeId;
959
960 fn type_info(&self, _types: &TypeList) -> TypeInfo {
961 self.info
962 }
963}
964
965impl InstanceType {
966 pub fn exports<'a>(&'a self, types: TypesRef<'a>) -> &'a IndexMap<String, EntityType> {
968 self.internal_exports(types.list)
969 }
970
971 pub(crate) fn internal_exports<'a>(
972 &'a self,
973 types: &'a TypeList,
974 ) -> &'a IndexMap<String, EntityType> {
975 match &self.kind {
976 CoreInstanceTypeKind::Instantiated(id) => &types[*id].exports,
977 CoreInstanceTypeKind::Exports(exports) => exports,
978 }
979 }
980}
981
982#[derive(Debug, Clone, Copy)]
984pub enum ComponentEntityType {
985 Module(ComponentCoreModuleTypeId),
987 Func(ComponentFuncTypeId),
989 Value(ComponentValType),
991 Type {
993 referenced: ComponentAnyTypeId,
996 created: ComponentAnyTypeId,
1003 },
1004 Instance(ComponentInstanceTypeId),
1006 Component(ComponentTypeId),
1008}
1009
1010impl ComponentEntityType {
1011 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
1013 SubtypeCx::new(at.list, bt.list)
1014 .component_entity_type(a, b, 0)
1015 .is_ok()
1016 }
1017
1018 pub(crate) fn desc(&self) -> &'static str {
1019 match self {
1020 Self::Module(_) => "module",
1021 Self::Func(_) => "func",
1022 Self::Value(_) => "value",
1023 Self::Type { .. } => "type",
1024 Self::Instance(_) => "instance",
1025 Self::Component(_) => "component",
1026 }
1027 }
1028
1029 pub(crate) fn info(&self, types: &TypeList) -> TypeInfo {
1030 match self {
1031 Self::Module(ty) => types[*ty].type_info(types),
1032 Self::Func(ty) => types[*ty].type_info(types),
1033 Self::Type { referenced: ty, .. } => ty.info(types),
1034 Self::Instance(ty) => types[*ty].type_info(types),
1035 Self::Component(ty) => types[*ty].type_info(types),
1036 Self::Value(ty) => ty.info(types),
1037 }
1038 }
1039}
1040
1041#[derive(Debug, Clone)]
1043pub struct ComponentType {
1044 pub(crate) info: TypeInfo,
1046
1047 pub imports: IndexMap<String, ComponentEntityType>,
1052
1053 pub exports: IndexMap<String, ComponentEntityType>,
1058
1059 pub imported_resources: Vec<(ResourceId, Vec<usize>)>,
1075
1076 pub defined_resources: Vec<(ResourceId, Vec<usize>)>,
1085
1086 pub explicit_resources: IndexMap<ResourceId, Vec<usize>>,
1095}
1096
1097impl TypeData for ComponentType {
1098 type Id = ComponentTypeId;
1099
1100 fn type_info(&self, _types: &TypeList) -> TypeInfo {
1101 self.info
1102 }
1103}
1104
1105#[derive(Debug, Clone)]
1107pub struct ComponentInstanceType {
1108 pub(crate) info: TypeInfo,
1110
1111 pub exports: IndexMap<String, ComponentEntityType>,
1115
1116 pub defined_resources: Vec<ResourceId>,
1149
1150 pub explicit_resources: IndexMap<ResourceId, Vec<usize>>,
1153}
1154
1155impl TypeData for ComponentInstanceType {
1156 type Id = ComponentInstanceTypeId;
1157
1158 fn type_info(&self, _types: &TypeList) -> TypeInfo {
1159 self.info
1160 }
1161}
1162
1163#[derive(Debug, Clone)]
1165pub struct ComponentFuncType {
1166 pub(crate) info: TypeInfo,
1168 pub params: Box<[(KebabString, ComponentValType)]>,
1170 pub results: Box<[(Option<KebabString>, ComponentValType)]>,
1172}
1173
1174impl TypeData for ComponentFuncType {
1175 type Id = ComponentFuncTypeId;
1176
1177 fn type_info(&self, _types: &TypeList) -> TypeInfo {
1178 self.info
1179 }
1180}
1181
1182impl ComponentFuncType {
1183 pub(crate) fn lower(&self, types: &TypeList, is_lower: bool) -> LoweringInfo {
1186 let mut info = LoweringInfo::default();
1187
1188 for (_, ty) in self.params.iter() {
1189 if is_lower {
1196 if !info.requires_memory {
1197 info.requires_memory = ty.contains_ptr(types);
1198 }
1199 } else {
1200 if !info.requires_realloc {
1201 info.requires_realloc = ty.contains_ptr(types);
1202 }
1203 }
1204
1205 if !ty.push_wasm_types(types, &mut info.params) {
1206 info.params.clear();
1210 assert!(info.params.push(ValType::I32));
1211 info.requires_memory = true;
1212
1213 if !is_lower {
1215 info.requires_realloc = true;
1216 }
1217 break;
1218 }
1219 }
1220
1221 for (_, ty) in self.results.iter() {
1222 if is_lower && !info.requires_realloc {
1227 info.requires_realloc = ty.contains_ptr(types);
1228 }
1229
1230 if !ty.push_wasm_types(types, &mut info.results) {
1231 info.results.clear();
1234 if is_lower {
1235 info.params.max = MAX_LOWERED_TYPES;
1236 assert!(info.params.push(ValType::I32));
1237 } else {
1238 assert!(info.results.push(ValType::I32));
1239 }
1240 info.requires_memory = true;
1241 break;
1242 }
1243 }
1244
1245 info.requires_memory |= info.requires_realloc;
1247
1248 info
1249 }
1250}
1251
1252#[derive(Debug, Clone)]
1254pub struct VariantCase {
1255 pub ty: Option<ComponentValType>,
1257 pub refines: Option<KebabString>,
1259}
1260
1261#[derive(Debug, Clone)]
1263pub struct RecordType {
1264 pub(crate) info: TypeInfo,
1266 pub fields: IndexMap<KebabString, ComponentValType>,
1268}
1269
1270#[derive(Debug, Clone)]
1272pub struct VariantType {
1273 pub(crate) info: TypeInfo,
1275 pub cases: IndexMap<KebabString, VariantCase>,
1277}
1278
1279#[derive(Debug, Clone)]
1281pub struct TupleType {
1282 pub(crate) info: TypeInfo,
1284 pub types: Box<[ComponentValType]>,
1286}
1287
1288#[derive(Debug, Clone)]
1290pub enum ComponentDefinedType {
1291 Primitive(PrimitiveValType),
1293 Record(RecordType),
1295 Variant(VariantType),
1297 List(ComponentValType),
1299 Tuple(TupleType),
1301 Flags(IndexSet<KebabString>),
1303 Enum(IndexSet<KebabString>),
1305 Option(ComponentValType),
1307 Result {
1309 ok: Option<ComponentValType>,
1311 err: Option<ComponentValType>,
1313 },
1314 Own(AliasableResourceId),
1316 Borrow(AliasableResourceId),
1318}
1319
1320impl TypeData for ComponentDefinedType {
1321 type Id = ComponentDefinedTypeId;
1322
1323 fn type_info(&self, types: &TypeList) -> TypeInfo {
1324 match self {
1325 Self::Primitive(_) | Self::Flags(_) | Self::Enum(_) | Self::Own(_) => TypeInfo::new(),
1326 Self::Borrow(_) => TypeInfo::borrow(),
1327 Self::Record(r) => r.info,
1328 Self::Variant(v) => v.info,
1329 Self::Tuple(t) => t.info,
1330 Self::List(ty) | Self::Option(ty) => ty.info(types),
1331 Self::Result { ok, err } => {
1332 let default = TypeInfo::new();
1333 let mut info = ok.map(|ty| ty.type_info(types)).unwrap_or(default);
1334 info.combine(err.map(|ty| ty.type_info(types)).unwrap_or(default), 0)
1335 .unwrap();
1336 info
1337 }
1338 }
1339 }
1340}
1341
1342impl ComponentDefinedType {
1343 pub(crate) fn contains_ptr(&self, types: &TypeList) -> bool {
1344 match self {
1345 Self::Primitive(ty) => ty.contains_ptr(),
1346 Self::Record(r) => r.fields.values().any(|ty| ty.contains_ptr(types)),
1347 Self::Variant(v) => v
1348 .cases
1349 .values()
1350 .any(|case| case.ty.map(|ty| ty.contains_ptr(types)).unwrap_or(false)),
1351 Self::List(_) => true,
1352 Self::Tuple(t) => t.types.iter().any(|ty| ty.contains_ptr(types)),
1353 Self::Flags(_) | Self::Enum(_) | Self::Own(_) | Self::Borrow(_) => false,
1354 Self::Option(ty) => ty.contains_ptr(types),
1355 Self::Result { ok, err } => {
1356 ok.map(|ty| ty.contains_ptr(types)).unwrap_or(false)
1357 || err.map(|ty| ty.contains_ptr(types)).unwrap_or(false)
1358 }
1359 }
1360 }
1361
1362 fn push_wasm_types(&self, types: &TypeList, lowered_types: &mut LoweredTypes) -> bool {
1363 match self {
1364 Self::Primitive(ty) => push_primitive_wasm_types(ty, lowered_types),
1365 Self::Record(r) => r
1366 .fields
1367 .iter()
1368 .all(|(_, ty)| ty.push_wasm_types(types, lowered_types)),
1369 Self::Variant(v) => Self::push_variant_wasm_types(
1370 v.cases.iter().filter_map(|(_, case)| case.ty.as_ref()),
1371 types,
1372 lowered_types,
1373 ),
1374 Self::List(_) => lowered_types.push(ValType::I32) && lowered_types.push(ValType::I32),
1375 Self::Tuple(t) => t
1376 .types
1377 .iter()
1378 .all(|ty| ty.push_wasm_types(types, lowered_types)),
1379 Self::Flags(names) => {
1380 (0..(names.len() + 31) / 32).all(|_| lowered_types.push(ValType::I32))
1381 }
1382 Self::Enum(_) | Self::Own(_) | Self::Borrow(_) => lowered_types.push(ValType::I32),
1383 Self::Option(ty) => {
1384 Self::push_variant_wasm_types([ty].into_iter(), types, lowered_types)
1385 }
1386 Self::Result { ok, err } => {
1387 Self::push_variant_wasm_types(ok.iter().chain(err.iter()), types, lowered_types)
1388 }
1389 }
1390 }
1391
1392 fn push_variant_wasm_types<'a>(
1393 cases: impl Iterator<Item = &'a ComponentValType>,
1394 types: &TypeList,
1395 lowered_types: &mut LoweredTypes,
1396 ) -> bool {
1397 if !lowered_types.push(ValType::I32) {
1399 return false;
1400 }
1401
1402 let start = lowered_types.len();
1403
1404 for ty in cases {
1405 let mut temp = LoweredTypes::new(lowered_types.max);
1406
1407 if !ty.push_wasm_types(types, &mut temp) {
1408 return false;
1409 }
1410
1411 for (i, ty) in temp.iter().enumerate() {
1412 match lowered_types.get_mut(start + i) {
1413 Some(prev) => *prev = Self::join_types(*prev, ty),
1414 None => {
1415 if !lowered_types.push(ty) {
1416 return false;
1417 }
1418 }
1419 }
1420 }
1421 }
1422
1423 true
1424 }
1425
1426 fn join_types(a: ValType, b: ValType) -> ValType {
1427 use ValType::*;
1428
1429 match (a, b) {
1430 (I32, I32) | (I64, I64) | (F32, F32) | (F64, F64) => a,
1431 (I32, F32) | (F32, I32) => I32,
1432 (_, I64 | F64) | (I64 | F64, _) => I64,
1433 _ => panic!("unexpected wasm type for canonical ABI"),
1434 }
1435 }
1436
1437 fn desc(&self) -> &'static str {
1438 match self {
1439 ComponentDefinedType::Record(_) => "record",
1440 ComponentDefinedType::Primitive(_) => "primitive",
1441 ComponentDefinedType::Variant(_) => "variant",
1442 ComponentDefinedType::Tuple(_) => "tuple",
1443 ComponentDefinedType::Enum(_) => "enum",
1444 ComponentDefinedType::Flags(_) => "flags",
1445 ComponentDefinedType::Option(_) => "option",
1446 ComponentDefinedType::List(_) => "list",
1447 ComponentDefinedType::Result { .. } => "result",
1448 ComponentDefinedType::Own(_) => "own",
1449 ComponentDefinedType::Borrow(_) => "borrow",
1450 }
1451 }
1452}
1453
1454#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)]
1457#[repr(packed(4))] pub struct ResourceId {
1459 globally_unique_id: usize,
1469
1470 contextually_unique_id: u32,
1479}
1480
1481#[allow(clippy::large_enum_variant)]
1482enum TypesKind {
1483 Module(Arc<Module>),
1484 Component(ComponentState),
1485}
1486
1487pub struct Types {
1491 id: ValidatorId,
1492 list: TypeList,
1493 kind: TypesKind,
1494}
1495
1496#[derive(Clone, Copy)]
1497enum TypesRefKind<'a> {
1498 Module(&'a Module),
1499 Component(&'a ComponentState),
1500}
1501
1502#[derive(Clone, Copy)]
1506pub struct TypesRef<'a> {
1507 id: ValidatorId,
1508 list: &'a TypeList,
1509 kind: TypesRefKind<'a>,
1510}
1511
1512impl<'a> TypesRef<'a> {
1513 pub(crate) fn from_module(id: ValidatorId, types: &'a TypeList, module: &'a Module) -> Self {
1514 Self {
1515 id,
1516 list: types,
1517 kind: TypesRefKind::Module(module),
1518 }
1519 }
1520
1521 pub(crate) fn from_component(
1522 id: ValidatorId,
1523 types: &'a TypeList,
1524 component: &'a ComponentState,
1525 ) -> Self {
1526 Self {
1527 id,
1528 list: types,
1529 kind: TypesRefKind::Component(component),
1530 }
1531 }
1532
1533 #[inline]
1535 pub fn id(&self) -> ValidatorId {
1536 self.id
1537 }
1538
1539 pub fn get<T>(&self, id: T) -> Option<&'a T::Data>
1543 where
1544 T: TypeIdentifier,
1545 {
1546 self.list.get(id)
1547 }
1548
1549 pub fn rec_group_id_of(&self, id: CoreTypeId) -> RecGroupId {
1551 self.list.rec_group_id_of(id)
1552 }
1553
1554 pub fn rec_group_elements(&self, id: RecGroupId) -> impl ExactSizeIterator<Item = CoreTypeId> {
1556 let range = &self.list.rec_group_elements[id];
1557 (range.start.index..range.end.index).map(|index| CoreTypeId { index })
1558 }
1559
1560 pub fn supertype_of(&self, id: CoreTypeId) -> Option<CoreTypeId> {
1562 self.list.supertype_of(id)
1563 }
1564
1565 pub fn core_type_at(&self, index: u32) -> ComponentCoreTypeId {
1574 match &self.kind {
1575 TypesRefKind::Module(module) => ComponentCoreTypeId::Sub(module.types[index as usize]),
1576 TypesRefKind::Component(component) => component.core_types[index as usize],
1577 }
1578 }
1579
1580 pub fn component_any_type_at(&self, index: u32) -> ComponentAnyTypeId {
1587 match &self.kind {
1588 TypesRefKind::Module(_) => panic!("not a component"),
1589 TypesRefKind::Component(component) => component.types[index as usize],
1590 }
1591 }
1592
1593 pub fn component_type_at(&self, index: u32) -> ComponentTypeId {
1600 match self.component_any_type_at(index) {
1601 ComponentAnyTypeId::Component(id) => id,
1602 _ => panic!("not a component type"),
1603 }
1604 }
1605
1606 pub fn component_defined_type_at(&self, index: u32) -> ComponentDefinedTypeId {
1613 match self.component_any_type_at(index) {
1614 ComponentAnyTypeId::Defined(id) => id,
1615 _ => panic!("not a defined type"),
1616 }
1617 }
1618
1619 pub fn core_type_count(&self) -> u32 {
1621 match &self.kind {
1622 TypesRefKind::Module(module) => module.types.len() as u32,
1623 TypesRefKind::Component(component) => component.core_types.len() as u32,
1624 }
1625 }
1626
1627 pub fn component_type_count(&self) -> u32 {
1629 match &self.kind {
1630 TypesRefKind::Module(_module) => 0,
1631 TypesRefKind::Component(component) => component.types.len() as u32,
1632 }
1633 }
1634
1635 pub fn table_at(&self, index: u32) -> TableType {
1641 let tables = match &self.kind {
1642 TypesRefKind::Module(module) => &module.tables,
1643 TypesRefKind::Component(component) => &component.core_tables,
1644 };
1645 tables[index as usize]
1646 }
1647
1648 pub fn table_count(&self) -> u32 {
1650 match &self.kind {
1651 TypesRefKind::Module(module) => module.tables.len() as u32,
1652 TypesRefKind::Component(component) => component.core_tables.len() as u32,
1653 }
1654 }
1655
1656 pub fn memory_at(&self, index: u32) -> MemoryType {
1662 let memories = match &self.kind {
1663 TypesRefKind::Module(module) => &module.memories,
1664 TypesRefKind::Component(component) => &component.core_memories,
1665 };
1666
1667 memories[index as usize]
1668 }
1669
1670 pub fn memory_count(&self) -> u32 {
1672 match &self.kind {
1673 TypesRefKind::Module(module) => module.memories.len() as u32,
1674 TypesRefKind::Component(component) => component.core_memories.len() as u32,
1675 }
1676 }
1677
1678 pub fn global_at(&self, index: u32) -> GlobalType {
1684 let globals = match &self.kind {
1685 TypesRefKind::Module(module) => &module.globals,
1686 TypesRefKind::Component(component) => &component.core_globals,
1687 };
1688
1689 globals[index as usize]
1690 }
1691
1692 pub fn global_count(&self) -> u32 {
1694 match &self.kind {
1695 TypesRefKind::Module(module) => module.globals.len() as u32,
1696 TypesRefKind::Component(component) => component.core_globals.len() as u32,
1697 }
1698 }
1699
1700 pub fn tag_at(&self, index: u32) -> CoreTypeId {
1706 let tags = match &self.kind {
1707 TypesRefKind::Module(module) => &module.tags,
1708 TypesRefKind::Component(component) => &component.core_tags,
1709 };
1710 tags[index as usize]
1711 }
1712
1713 pub fn tag_count(&self) -> u32 {
1715 match &self.kind {
1716 TypesRefKind::Module(module) => module.tags.len() as u32,
1717 TypesRefKind::Component(component) => component.core_tags.len() as u32,
1718 }
1719 }
1720
1721 pub fn core_function_at(&self, index: u32) -> CoreTypeId {
1727 match &self.kind {
1728 TypesRefKind::Module(module) => module.types[module.functions[index as usize] as usize],
1729 TypesRefKind::Component(component) => component.core_funcs[index as usize],
1730 }
1731 }
1732
1733 pub fn function_count(&self) -> u32 {
1738 match &self.kind {
1739 TypesRefKind::Module(module) => module.functions.len() as u32,
1740 TypesRefKind::Component(component) => component.core_funcs.len() as u32,
1741 }
1742 }
1743
1744 pub fn element_at(&self, index: u32) -> RefType {
1750 match &self.kind {
1751 TypesRefKind::Module(module) => module.element_types[index as usize],
1752 TypesRefKind::Component(_) => {
1753 panic!("no elements on a component")
1754 }
1755 }
1756 }
1757
1758 pub fn element_count(&self) -> u32 {
1760 match &self.kind {
1761 TypesRefKind::Module(module) => module.element_types.len() as u32,
1762 TypesRefKind::Component(_) => 0,
1763 }
1764 }
1765
1766 pub fn component_function_at(&self, index: u32) -> ComponentFuncTypeId {
1773 match &self.kind {
1774 TypesRefKind::Module(_) => panic!("not a component"),
1775 TypesRefKind::Component(component) => component.funcs[index as usize],
1776 }
1777 }
1778
1779 pub fn component_function_count(&self) -> u32 {
1781 match &self.kind {
1782 TypesRefKind::Module(_module) => 0,
1783 TypesRefKind::Component(component) => component.funcs.len() as u32,
1784 }
1785 }
1786
1787 pub fn module_at(&self, index: u32) -> ComponentCoreModuleTypeId {
1794 match &self.kind {
1795 TypesRefKind::Module(_) => panic!("not a component"),
1796 TypesRefKind::Component(component) => component.core_modules[index as usize],
1797 }
1798 }
1799
1800 pub fn module_count(&self) -> u32 {
1802 match &self.kind {
1803 TypesRefKind::Module(_module) => 0,
1804 TypesRefKind::Component(component) => component.core_modules.len() as u32,
1805 }
1806 }
1807
1808 pub fn core_instance_at(&self, index: u32) -> ComponentCoreInstanceTypeId {
1815 match &self.kind {
1816 TypesRefKind::Module(_) => panic!("not a component"),
1817 TypesRefKind::Component(component) => component.core_instances[index as usize],
1818 }
1819 }
1820
1821 pub fn core_instance_count(&self) -> u32 {
1823 match &self.kind {
1824 TypesRefKind::Module(_module) => 0,
1825 TypesRefKind::Component(component) => component.core_instances.len() as u32,
1826 }
1827 }
1828
1829 pub fn component_at(&self, index: u32) -> ComponentTypeId {
1836 match &self.kind {
1837 TypesRefKind::Module(_) => panic!("not a component"),
1838 TypesRefKind::Component(component) => component.components[index as usize],
1839 }
1840 }
1841
1842 pub fn component_count(&self) -> u32 {
1844 match &self.kind {
1845 TypesRefKind::Module(_module) => 0,
1846 TypesRefKind::Component(component) => component.components.len() as u32,
1847 }
1848 }
1849
1850 pub fn component_instance_at(&self, index: u32) -> ComponentInstanceTypeId {
1857 match &self.kind {
1858 TypesRefKind::Module(_) => panic!("not a component"),
1859 TypesRefKind::Component(component) => component.instances[index as usize],
1860 }
1861 }
1862
1863 pub fn component_instance_count(&self) -> u32 {
1865 match &self.kind {
1866 TypesRefKind::Module(_module) => 0,
1867 TypesRefKind::Component(component) => component.instances.len() as u32,
1868 }
1869 }
1870
1871 pub fn value_at(&self, index: u32) -> ComponentValType {
1878 match &self.kind {
1879 TypesRefKind::Module(_) => panic!("not a component"),
1880 TypesRefKind::Component(component) => component.values[index as usize].0,
1881 }
1882 }
1883
1884 pub fn entity_type_from_import(&self, import: &Import) -> Option<EntityType> {
1886 match &self.kind {
1887 TypesRefKind::Module(module) => Some(match import.ty {
1888 TypeRef::Func(idx) => EntityType::Func(*module.types.get(idx as usize)?),
1889 TypeRef::Table(ty) => EntityType::Table(ty),
1890 TypeRef::Memory(ty) => EntityType::Memory(ty),
1891 TypeRef::Global(ty) => EntityType::Global(ty),
1892 TypeRef::Tag(ty) => EntityType::Tag(*module.types.get(ty.func_type_idx as usize)?),
1893 }),
1894 TypesRefKind::Component(_) => None,
1895 }
1896 }
1897
1898 pub fn entity_type_from_export(&self, export: &Export) -> Option<EntityType> {
1900 match &self.kind {
1901 TypesRefKind::Module(module) => Some(match export.kind {
1902 ExternalKind::Func => EntityType::Func(
1903 module.types[*module.functions.get(export.index as usize)? as usize],
1904 ),
1905 ExternalKind::Table => {
1906 EntityType::Table(*module.tables.get(export.index as usize)?)
1907 }
1908 ExternalKind::Memory => {
1909 EntityType::Memory(*module.memories.get(export.index as usize)?)
1910 }
1911 ExternalKind::Global => {
1912 EntityType::Global(*module.globals.get(export.index as usize)?)
1913 }
1914 ExternalKind::Tag => EntityType::Tag(
1915 module.types[*module.functions.get(export.index as usize)? as usize],
1916 ),
1917 }),
1918 TypesRefKind::Component(_) => None,
1919 }
1920 }
1921
1922 pub fn component_entity_type_of_import(&self, name: &str) -> Option<ComponentEntityType> {
1924 match &self.kind {
1925 TypesRefKind::Module(_) => None,
1926 TypesRefKind::Component(component) => Some(*component.imports.get(name)?),
1927 }
1928 }
1929
1930 pub fn component_entity_type_of_export(&self, name: &str) -> Option<ComponentEntityType> {
1932 match &self.kind {
1933 TypesRefKind::Module(_) => None,
1934 TypesRefKind::Component(component) => Some(*component.exports.get(name)?),
1935 }
1936 }
1937
1938 pub fn peel_alias<T>(&self, ty: T) -> Option<T>
1942 where
1943 T: Aliasable,
1944 {
1945 self.list.peel_alias(ty)
1946 }
1947
1948 pub fn core_imports(
1952 &self,
1953 ) -> Option<impl Iterator<Item = (&'a str, &'a str, EntityType)> + 'a> {
1954 match &self.kind {
1955 TypesRefKind::Module(module) => Some(
1956 module
1957 .imports
1958 .iter()
1959 .flat_map(|((m, n), t)| t.iter().map(move |t| (m.as_str(), n.as_str(), *t))),
1960 ),
1961 TypesRefKind::Component(_) => None,
1962 }
1963 }
1964
1965 pub fn core_exports(&self) -> Option<impl Iterator<Item = (&'a str, EntityType)> + 'a> {
1969 match &self.kind {
1970 TypesRefKind::Module(module) => {
1971 Some(module.exports.iter().map(|(n, t)| (n.as_str(), *t)))
1972 }
1973 TypesRefKind::Component(_) => None,
1974 }
1975 }
1976}
1977
1978impl<T> Index<T> for TypesRef<'_>
1979where
1980 T: TypeIdentifier,
1981{
1982 type Output = T::Data;
1983
1984 fn index(&self, index: T) -> &Self::Output {
1985 &self.list[index]
1986 }
1987}
1988
1989impl Types {
1990 pub(crate) fn from_module(id: ValidatorId, types: TypeList, module: Arc<Module>) -> Self {
1991 Self {
1992 id,
1993 list: types,
1994 kind: TypesKind::Module(module),
1995 }
1996 }
1997
1998 pub(crate) fn from_component(
1999 id: ValidatorId,
2000 types: TypeList,
2001 component: ComponentState,
2002 ) -> Self {
2003 Self {
2004 id,
2005 list: types,
2006 kind: TypesKind::Component(component),
2007 }
2008 }
2009
2010 #[inline]
2012 pub fn id(&self) -> ValidatorId {
2013 self.id
2014 }
2015
2016 pub fn as_ref(&self) -> TypesRef {
2018 TypesRef {
2019 id: self.id,
2020 list: &self.list,
2021 kind: match &self.kind {
2022 TypesKind::Module(module) => TypesRefKind::Module(module),
2023 TypesKind::Component(component) => TypesRefKind::Component(component),
2024 },
2025 }
2026 }
2027
2028 pub fn get<T>(&self, id: T) -> Option<&T::Data>
2032 where
2033 T: TypeIdentifier,
2034 {
2035 self.as_ref().get(id)
2036 }
2037
2038 pub fn core_type_at(&self, index: u32) -> ComponentCoreTypeId {
2047 self.as_ref().core_type_at(index)
2048 }
2049
2050 pub fn component_any_type_at(&self, index: u32) -> ComponentAnyTypeId {
2059 self.as_ref().component_any_type_at(index)
2060 }
2061
2062 pub fn component_type_at(&self, index: u32) -> ComponentTypeId {
2068 self.as_ref().component_type_at(index)
2069 }
2070
2071 pub fn component_defined_type_at(&self, index: u32) -> ComponentDefinedTypeId {
2078 self.as_ref().component_defined_type_at(index)
2079 }
2080
2081 pub fn type_count(&self) -> usize {
2083 match &self.kind {
2084 TypesKind::Module(module) => module.types.len(),
2085 TypesKind::Component(component) => component.core_types.len(),
2086 }
2087 }
2088
2089 pub fn table_at(&self, index: u32) -> TableType {
2095 self.as_ref().table_at(index)
2096 }
2097
2098 pub fn table_count(&self) -> usize {
2100 match &self.kind {
2101 TypesKind::Module(module) => module.tables.len(),
2102 TypesKind::Component(component) => component.core_tables.len(),
2103 }
2104 }
2105
2106 pub fn memory_at(&self, index: u32) -> MemoryType {
2112 self.as_ref().memory_at(index)
2113 }
2114
2115 pub fn memory_count(&self) -> u32 {
2117 self.as_ref().memory_count()
2118 }
2119
2120 pub fn global_at(&self, index: u32) -> GlobalType {
2126 self.as_ref().global_at(index)
2127 }
2128
2129 pub fn global_count(&self) -> u32 {
2131 self.as_ref().global_count()
2132 }
2133
2134 pub fn tag_at(&self, index: u32) -> CoreTypeId {
2140 self.as_ref().tag_at(index)
2141 }
2142
2143 pub fn tag_count(&self) -> u32 {
2145 self.as_ref().tag_count()
2146 }
2147
2148 pub fn core_function_at(&self, index: u32) -> CoreTypeId {
2154 self.as_ref().core_function_at(index)
2155 }
2156
2157 pub fn core_function_count(&self) -> u32 {
2162 self.as_ref().function_count()
2163 }
2164
2165 pub fn element_at(&self, index: u32) -> RefType {
2171 self.as_ref().element_at(index)
2172 }
2173
2174 pub fn element_count(&self) -> u32 {
2176 self.as_ref().element_count()
2177 }
2178
2179 pub fn component_function_at(&self, index: u32) -> ComponentFuncTypeId {
2186 self.as_ref().component_function_at(index)
2187 }
2188
2189 pub fn component_function_count(&self) -> u32 {
2191 self.as_ref().component_function_count()
2192 }
2193
2194 pub fn module_at(&self, index: u32) -> ComponentCoreModuleTypeId {
2201 self.as_ref().module_at(index)
2202 }
2203
2204 pub fn module_count(&self) -> usize {
2206 match &self.kind {
2207 TypesKind::Module(_) => 0,
2208 TypesKind::Component(component) => component.core_modules.len(),
2209 }
2210 }
2211
2212 pub fn core_instance_at(&self, index: u32) -> ComponentCoreInstanceTypeId {
2219 self.as_ref().core_instance_at(index)
2220 }
2221
2222 pub fn core_instance_count(&self) -> usize {
2224 match &self.kind {
2225 TypesKind::Module(_) => 0,
2226 TypesKind::Component(component) => component.core_instances.len(),
2227 }
2228 }
2229
2230 pub fn component_at(&self, index: u32) -> ComponentTypeId {
2237 self.as_ref().component_at(index)
2238 }
2239
2240 pub fn component_count(&self) -> usize {
2242 match &self.kind {
2243 TypesKind::Module(_) => 0,
2244 TypesKind::Component(component) => component.components.len(),
2245 }
2246 }
2247
2248 pub fn component_instance_at(&self, index: u32) -> ComponentInstanceTypeId {
2255 self.as_ref().component_instance_at(index)
2256 }
2257
2258 pub fn component_instance_count(&self) -> usize {
2260 match &self.kind {
2261 TypesKind::Module(_) => 0,
2262 TypesKind::Component(component) => component.instances.len(),
2263 }
2264 }
2265
2266 pub fn value_at(&self, index: u32) -> ComponentValType {
2273 self.as_ref().value_at(index)
2274 }
2275
2276 pub fn value_count(&self) -> usize {
2278 match &self.kind {
2279 TypesKind::Module(_) => 0,
2280 TypesKind::Component(component) => component.values.len(),
2281 }
2282 }
2283
2284 pub fn entity_type_from_import(&self, import: &Import) -> Option<EntityType> {
2286 self.as_ref().entity_type_from_import(import)
2287 }
2288
2289 pub fn entity_type_from_export(&self, export: &Export) -> Option<EntityType> {
2291 self.as_ref().entity_type_from_export(export)
2292 }
2293
2294 pub fn component_entity_type_of_import(&self, name: &str) -> Option<ComponentEntityType> {
2296 self.as_ref().component_entity_type_of_import(name)
2297 }
2298
2299 pub fn component_entity_type_of_export(&self, name: &str) -> Option<ComponentEntityType> {
2301 self.as_ref().component_entity_type_of_export(name)
2302 }
2303
2304 pub fn peel_alias<T>(&self, ty: T) -> Option<T>
2308 where
2309 T: Aliasable,
2310 {
2311 self.list.peel_alias(ty)
2312 }
2313
2314 pub fn core_imports<'a>(&self) -> Option<impl Iterator<Item = (&str, &str, EntityType)> + '_> {
2316 self.as_ref().core_imports()
2317 }
2318
2319 pub fn core_exports(&self) -> Option<impl Iterator<Item = (&str, EntityType)> + '_> {
2321 self.as_ref().core_exports()
2322 }
2323}
2324
2325impl<T> Index<T> for Types
2326where
2327 T: TypeIdentifier,
2328{
2329 type Output = T::Data;
2330
2331 fn index(&self, id: T) -> &Self::Output {
2332 &self.list[id]
2333 }
2334}
2335
2336#[doc(hidden)]
2350#[derive(Debug)]
2351pub struct SnapshotList<T> {
2352 snapshots: Vec<Arc<Snapshot<T>>>,
2362
2363 snapshots_total: usize,
2365
2366 cur: Vec<T>,
2368}
2369
2370#[derive(Debug)]
2371struct Snapshot<T> {
2372 prior_types: usize,
2373 items: Vec<T>,
2374}
2375
2376impl<T> SnapshotList<T> {
2377 pub(crate) fn get(&self, index: usize) -> Option<&T> {
2379 if index >= self.snapshots_total {
2381 return self.cur.get(index - self.snapshots_total);
2382 }
2383 let i = match self
2387 .snapshots
2388 .binary_search_by_key(&index, |snapshot| snapshot.prior_types)
2389 {
2390 Ok(i) => i,
2391 Err(i) => i - 1,
2392 };
2393 let snapshot = &self.snapshots[i];
2394 Some(&snapshot.items[index - snapshot.prior_types])
2395 }
2396
2397 pub(crate) fn push(&mut self, val: T) {
2399 self.cur.push(val);
2400 }
2401
2402 pub(crate) fn len(&self) -> usize {
2404 self.cur.len() + self.snapshots_total
2405 }
2406
2407 pub(crate) fn truncate(&mut self, len: usize) {
2409 assert!(len >= self.snapshots_total);
2410 self.cur.truncate(len - self.snapshots_total);
2411 }
2412
2413 pub(crate) fn commit(&mut self) -> SnapshotList<T> {
2420 let len = self.cur.len();
2425 if len > 0 {
2426 self.cur.shrink_to_fit();
2427 self.snapshots.push(Arc::new(Snapshot {
2428 prior_types: self.snapshots_total,
2429 items: mem::take(&mut self.cur),
2430 }));
2431 self.snapshots_total += len;
2432 }
2433 SnapshotList {
2434 snapshots: self.snapshots.clone(),
2435 snapshots_total: self.snapshots_total,
2436 cur: Vec::new(),
2437 }
2438 }
2439}
2440
2441impl<T> Index<usize> for SnapshotList<T> {
2442 type Output = T;
2443
2444 #[inline]
2445 fn index(&self, index: usize) -> &T {
2446 self.get(index).unwrap()
2447 }
2448}
2449
2450impl<T, U> Index<U> for SnapshotList<T>
2451where
2452 U: TypeIdentifier<Data = T>,
2453{
2454 type Output = T;
2455
2456 #[inline]
2457 fn index(&self, id: U) -> &T {
2458 self.get(id.index()).unwrap()
2459 }
2460}
2461
2462impl<T> Default for SnapshotList<T> {
2463 fn default() -> SnapshotList<T> {
2464 SnapshotList {
2465 snapshots: Vec::new(),
2466 snapshots_total: 0,
2467 cur: Vec::new(),
2468 }
2469 }
2470}
2471
2472#[derive(Default, Debug)]
2480#[doc(hidden)]
2482pub struct TypeList {
2483 alias_mappings: Map<u32, u32>,
2485 alias_counter: u32,
2487 alias_snapshots: Vec<TypeListAliasSnapshot>,
2489
2490 core_types: SnapshotList<SubType>,
2494 core_type_to_rec_group: SnapshotList<RecGroupId>,
2498 core_type_to_supertype: SnapshotList<Option<CoreTypeId>>,
2502 core_type_to_depth: Option<IndexMap<CoreTypeId, u8>>,
2507 rec_group_elements: SnapshotList<Range<CoreTypeId>>,
2510 canonical_rec_groups: Option<Map<RecGroup, RecGroupId>>,
2515
2516 components: SnapshotList<ComponentType>,
2518 component_defined_types: SnapshotList<ComponentDefinedType>,
2519 component_values: SnapshotList<ComponentValType>,
2520 component_instances: SnapshotList<ComponentInstanceType>,
2521 component_funcs: SnapshotList<ComponentFuncType>,
2522 core_modules: SnapshotList<ModuleType>,
2523 core_instances: SnapshotList<InstanceType>,
2524}
2525
2526#[derive(Clone, Debug)]
2527struct TypeListAliasSnapshot {
2528 alias_counter: u32,
2530
2531 alias_mappings: Map<u32, u32>,
2533}
2534
2535struct TypeListCheckpoint {
2536 core_types: usize,
2537 components: usize,
2538 component_defined_types: usize,
2539 component_values: usize,
2540 component_instances: usize,
2541 component_funcs: usize,
2542 core_modules: usize,
2543 core_instances: usize,
2544 core_type_to_rec_group: usize,
2545 core_type_to_supertype: usize,
2546 core_type_to_depth: usize,
2547 rec_group_elements: usize,
2548 canonical_rec_groups: usize,
2549}
2550
2551impl TypeList {
2552 pub fn get<T>(&self, id: T) -> Option<&T::Data>
2553 where
2554 T: TypeIdentifier,
2555 {
2556 T::list(self).get(id.index())
2557 }
2558
2559 pub fn push<T>(&mut self, ty: T) -> T::Id
2560 where
2561 T: TypeData,
2562 {
2563 let index = u32::try_from(T::Id::list(self).len()).unwrap();
2564 let id = T::Id::from_index(index);
2565 T::Id::list_mut(self).push(ty);
2566 id
2567 }
2568
2569 pub fn intern_canonical_rec_group(&mut self, rec_group: RecGroup) -> (bool, RecGroupId) {
2573 let canonical_rec_groups = self
2574 .canonical_rec_groups
2575 .as_mut()
2576 .expect("cannot intern into a committed list");
2577 let entry = match canonical_rec_groups.entry(rec_group) {
2578 Entry::Occupied(e) => return (false, *e.get()),
2579 Entry::Vacant(e) => e,
2580 };
2581
2582 let rec_group_id = self.rec_group_elements.len();
2583 let rec_group_id = u32::try_from(rec_group_id).unwrap();
2584 let rec_group_id = RecGroupId::from_index(rec_group_id);
2585
2586 let start = self.core_types.len();
2587 let start = u32::try_from(start).unwrap();
2588 let start = CoreTypeId::from_index(start);
2589
2590 for ty in entry.key().types() {
2591 debug_assert_eq!(self.core_types.len(), self.core_type_to_supertype.len());
2592 debug_assert_eq!(self.core_types.len(), self.core_type_to_rec_group.len());
2593
2594 self.core_type_to_supertype
2595 .push(ty.supertype_idx.map(|idx| match idx.unpack() {
2596 UnpackedIndex::RecGroup(offset) => CoreTypeId::from_index(start.index + offset),
2597 UnpackedIndex::Id(id) => id,
2598 UnpackedIndex::Module(_) => unreachable!("in canonical form"),
2599 }));
2600 let mut ty = ty.clone();
2601 ty.remap_indices(&mut |index| {
2602 match index.unpack() {
2603 UnpackedIndex::Id(_) => {}
2604 UnpackedIndex::Module(_) => unreachable!(),
2605 UnpackedIndex::RecGroup(offset) => {
2606 *index = UnpackedIndex::Id(CoreTypeId::from_index(start.index + offset))
2607 .pack()
2608 .unwrap();
2609 }
2610 };
2611 Ok(())
2612 })
2613 .expect("cannot fail");
2614 self.core_types.push(ty);
2615 self.core_type_to_rec_group.push(rec_group_id);
2616 }
2617
2618 let end = self.core_types.len();
2619 let end = u32::try_from(end).unwrap();
2620 let end = CoreTypeId::from_index(end);
2621
2622 let range = start..end;
2623
2624 self.rec_group_elements.push(range.clone());
2625
2626 entry.insert(rec_group_id);
2627 return (true, rec_group_id);
2628 }
2629
2630 pub fn rec_group_local_id(
2632 &self,
2633 rec_group: RecGroupId,
2634 index: u32,
2635 offset: usize,
2636 ) -> Result<CoreTypeId> {
2637 let elems = &self[rec_group];
2638 let len = elems.end.index() - elems.start.index();
2639 let len = u32::try_from(len).unwrap();
2640 if index < len {
2641 let id = u32::try_from(elems.start.index()).unwrap() + index;
2642 let id = CoreTypeId::from_index(id);
2643 Ok(id)
2644 } else {
2645 bail!(
2646 offset,
2647 "unknown type {index}: type index out of rec group bounds"
2648 )
2649 }
2650 }
2651
2652 pub fn rec_group_id_of(&self, id: CoreTypeId) -> RecGroupId {
2654 self.core_type_to_rec_group[id.index()]
2655 }
2656
2657 pub fn supertype_of(&self, id: CoreTypeId) -> Option<CoreTypeId> {
2659 self.core_type_to_supertype[id.index()]
2660 }
2661
2662 pub fn get_subtyping_depth(&self, id: CoreTypeId) -> u8 {
2665 let depth = self
2666 .core_type_to_depth
2667 .as_ref()
2668 .expect("cannot get subtype depth from a committed list")[id.index()];
2669 debug_assert!(usize::from(depth) <= crate::limits::MAX_WASM_SUBTYPING_DEPTH);
2670 depth
2671 }
2672
2673 pub fn set_subtyping_depth(&mut self, id: CoreTypeId, depth: u8) {
2676 debug_assert!(usize::from(depth) <= crate::limits::MAX_WASM_SUBTYPING_DEPTH);
2677 let map = self
2678 .core_type_to_depth
2679 .as_mut()
2680 .expect("cannot set a subtype depth in a committed list");
2681 debug_assert!(!map.contains_key(&id));
2682 map.insert(id, depth);
2683 }
2684
2685 pub fn at_canonicalized_packed_index(
2689 &self,
2690 rec_group: RecGroupId,
2691 index: PackedIndex,
2692 offset: usize,
2693 ) -> Result<CoreTypeId> {
2694 self.at_canonicalized_unpacked_index(rec_group, index.unpack(), offset)
2695 }
2696
2697 pub fn at_canonicalized_unpacked_index(
2701 &self,
2702 rec_group: RecGroupId,
2703 index: UnpackedIndex,
2704 offset: usize,
2705 ) -> Result<CoreTypeId> {
2706 match index {
2707 UnpackedIndex::Module(_) => panic!("not canonicalized"),
2708 UnpackedIndex::Id(id) => Ok(id),
2709 UnpackedIndex::RecGroup(idx) => self.rec_group_local_id(rec_group, idx, offset),
2710 }
2711 }
2712
2713 pub fn matches(&self, a: CoreTypeId, b: CoreTypeId) -> bool {
2715 let a = WithRecGroup::new(self, a);
2716 let a = WithRecGroup::map(a, |a| &self[a]);
2717
2718 let b = WithRecGroup::new(self, b);
2719 let b = WithRecGroup::map(b, |b| &self[b]);
2720
2721 Matches::matches(self, a, b)
2722 }
2723
2724 pub fn id_is_subtype(&self, mut a: CoreTypeId, b: CoreTypeId) -> bool {
2727 loop {
2728 if a == b {
2729 return true;
2730 }
2731
2732 a = match self.supertype_of(a) {
2735 Some(a) => a,
2736 None => return false,
2737 };
2738 }
2739 }
2740
2741 pub fn reftype_is_subtype(&self, a: RefType, b: RefType) -> bool {
2745 self.reftype_is_subtype_impl(a, None, b, None)
2749 }
2750
2751 pub(crate) fn reftype_is_subtype_impl(
2757 &self,
2758 a: RefType,
2759 a_group: Option<RecGroupId>,
2760 b: RefType,
2761 b_group: Option<RecGroupId>,
2762 ) -> bool {
2763 if a == b && a_group == b_group {
2764 return true;
2765 }
2766
2767 if a.is_nullable() && !b.is_nullable() {
2768 return false;
2769 }
2770
2771 let core_type_id = |group: Option<RecGroupId>, index: UnpackedIndex| -> CoreTypeId {
2772 if let Some(id) = index.as_core_type_id() {
2773 id
2774 } else {
2775 self.at_canonicalized_unpacked_index(group.unwrap(), index, usize::MAX)
2776 .expect("type references are checked during canonicalization")
2777 }
2778 };
2779
2780 let subtype = |group, index| -> &SubType {
2781 let id = core_type_id(group, index);
2782 &self[id]
2783 };
2784
2785 use AbstractHeapType::*;
2786 use CompositeInnerType as CT;
2787 use HeapType as HT;
2788 match (a.heap_type(), b.heap_type()) {
2789 (a, b) if a == b => true,
2790
2791 (
2792 HT::Abstract {
2793 shared: a_shared,
2794 ty: a_ty,
2795 },
2796 HT::Abstract {
2797 shared: b_shared,
2798 ty: b_ty,
2799 },
2800 ) => a_shared == b_shared && a_ty.is_subtype_of(b_ty),
2801
2802 (HT::Concrete(a), HT::Abstract { shared, ty }) => {
2803 let a_ty = &subtype(a_group, a).composite_type;
2804 if a_ty.shared != shared {
2805 return false;
2806 }
2807 match ty {
2808 Any | Eq => matches!(a_ty.inner, CT::Array(_) | CT::Struct(_)),
2809 Struct => matches!(a_ty.inner, CT::Struct(_)),
2810 Array => matches!(a_ty.inner, CT::Array(_)),
2811 Func => matches!(a_ty.inner, CT::Func(_)),
2812 Extern | Exn | I31 | None | NoFunc | NoExtern | NoExn => false,
2815 }
2816 }
2817
2818 (HT::Abstract { shared, ty }, HT::Concrete(b)) => {
2819 let b_ty = &subtype(b_group, b).composite_type;
2820 if shared != b_ty.shared {
2821 return false;
2822 }
2823 match ty {
2824 None => matches!(b_ty.inner, CT::Array(_) | CT::Struct(_)),
2825 NoFunc => matches!(b_ty.inner, CT::Func(_)),
2826 Func | Extern | Exn | Any | Eq | Array | I31 | Struct | NoExtern | NoExn => {
2829 false
2830 }
2831 }
2832 }
2833
2834 (HT::Concrete(a), HT::Concrete(b)) => {
2835 self.id_is_subtype(core_type_id(a_group, a), core_type_id(b_group, b))
2836 }
2837 }
2838 }
2839
2840 pub fn valtype_is_subtype(&self, a: ValType, b: ValType) -> bool {
2844 match (a, b) {
2845 (a, b) if a == b => true,
2846 (ValType::Ref(a), ValType::Ref(b)) => self.reftype_is_subtype(a, b),
2847 (ValType::Ref(_), _)
2848 | (ValType::I32, _)
2849 | (ValType::I64, _)
2850 | (ValType::F32, _)
2851 | (ValType::F64, _)
2852 | (ValType::V128, _) => false,
2853 }
2854 }
2855
2856 pub fn valtype_is_shared(&self, ty: ValType) -> bool {
2858 match ty {
2859 ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => true,
2860 ValType::Ref(rt) => self.reftype_is_shared(rt),
2861 }
2862 }
2863
2864 pub fn reftype_is_shared(&self, ty: RefType) -> bool {
2869 match ty.heap_type() {
2870 HeapType::Abstract { shared, .. } => shared,
2871 HeapType::Concrete(index) => {
2872 self[index.as_core_type_id().unwrap()].composite_type.shared
2873 }
2874 }
2875 }
2876
2877 pub fn top_type(&self, heap_type: &HeapType) -> HeapType {
2882 use AbstractHeapType::*;
2883 match *heap_type {
2884 HeapType::Concrete(idx) => {
2885 let ty = &self[idx.as_core_type_id().unwrap()].composite_type;
2886 let shared = ty.shared;
2887 match ty.inner {
2888 CompositeInnerType::Func(_) => HeapType::Abstract { shared, ty: Func },
2889 CompositeInnerType::Array(_) | CompositeInnerType::Struct(_) => {
2890 HeapType::Abstract { shared, ty: Any }
2891 }
2892 }
2893 }
2894 HeapType::Abstract { shared, ty } => {
2895 let ty = match ty {
2896 Func | NoFunc => Func,
2897 Extern | NoExtern => Extern,
2898 Any | Eq | Struct | Array | I31 | None => Any,
2899 Exn | NoExn => Exn,
2900 };
2901 HeapType::Abstract { shared, ty }
2902 }
2903 }
2904 }
2905
2906 fn checkpoint(&self) -> TypeListCheckpoint {
2907 let TypeList {
2908 alias_mappings: _,
2909 alias_counter: _,
2910 alias_snapshots: _,
2911 core_types,
2912 components,
2913 component_defined_types,
2914 component_values,
2915 component_instances,
2916 component_funcs,
2917 core_modules,
2918 core_instances,
2919 core_type_to_rec_group,
2920 core_type_to_supertype,
2921 core_type_to_depth,
2922 rec_group_elements,
2923 canonical_rec_groups,
2924 } = self;
2925
2926 TypeListCheckpoint {
2927 core_types: core_types.len(),
2928 components: components.len(),
2929 component_defined_types: component_defined_types.len(),
2930 component_values: component_values.len(),
2931 component_instances: component_instances.len(),
2932 component_funcs: component_funcs.len(),
2933 core_modules: core_modules.len(),
2934 core_instances: core_instances.len(),
2935 core_type_to_rec_group: core_type_to_rec_group.len(),
2936 core_type_to_supertype: core_type_to_supertype.len(),
2937 core_type_to_depth: core_type_to_depth.as_ref().map(|m| m.len()).unwrap_or(0),
2938 rec_group_elements: rec_group_elements.len(),
2939 canonical_rec_groups: canonical_rec_groups.as_ref().map(|m| m.len()).unwrap_or(0),
2940 }
2941 }
2942
2943 fn reset_to_checkpoint(&mut self, checkpoint: TypeListCheckpoint) {
2944 let TypeList {
2945 alias_mappings: _,
2946 alias_counter: _,
2947 alias_snapshots: _,
2948 core_types,
2949 components,
2950 component_defined_types,
2951 component_values,
2952 component_instances,
2953 component_funcs,
2954 core_modules,
2955 core_instances,
2956 core_type_to_rec_group,
2957 core_type_to_supertype,
2958 core_type_to_depth,
2959 rec_group_elements,
2960 canonical_rec_groups,
2961 } = self;
2962
2963 core_types.truncate(checkpoint.core_types);
2964 components.truncate(checkpoint.components);
2965 component_defined_types.truncate(checkpoint.component_defined_types);
2966 component_values.truncate(checkpoint.component_values);
2967 component_instances.truncate(checkpoint.component_instances);
2968 component_funcs.truncate(checkpoint.component_funcs);
2969 core_modules.truncate(checkpoint.core_modules);
2970 core_instances.truncate(checkpoint.core_instances);
2971 core_type_to_rec_group.truncate(checkpoint.core_type_to_rec_group);
2972 core_type_to_supertype.truncate(checkpoint.core_type_to_supertype);
2973 rec_group_elements.truncate(checkpoint.rec_group_elements);
2974
2975 if let Some(core_type_to_depth) = core_type_to_depth {
2976 assert_eq!(
2977 core_type_to_depth.len(),
2978 checkpoint.core_type_to_depth,
2979 "checkpointing does not support resetting `core_type_to_depth` (it would require a \
2980 proper immutable and persistent hash map) so adding new groups is disallowed"
2981 );
2982 }
2983 if let Some(canonical_rec_groups) = canonical_rec_groups {
2984 assert_eq!(
2985 canonical_rec_groups.len(),
2986 checkpoint.canonical_rec_groups,
2987 "checkpointing does not support resetting `canonical_rec_groups` (it would require a \
2988 proper immutable and persistent hash map) so adding new groups is disallowed"
2989 );
2990 }
2991 }
2992
2993 pub fn commit(&mut self) -> TypeList {
2994 let alias_counter = self.alias_counter;
2998 self.alias_counter += 1;
2999
3000 self.alias_snapshots.push(TypeListAliasSnapshot {
3001 alias_counter,
3002 alias_mappings: mem::take(&mut self.alias_mappings),
3003 });
3004
3005 TypeList {
3006 alias_mappings: Map::default(),
3007 alias_counter: self.alias_counter,
3008 alias_snapshots: self.alias_snapshots.clone(),
3009 core_types: self.core_types.commit(),
3010 components: self.components.commit(),
3011 component_defined_types: self.component_defined_types.commit(),
3012 component_values: self.component_values.commit(),
3013 component_instances: self.component_instances.commit(),
3014 component_funcs: self.component_funcs.commit(),
3015 core_modules: self.core_modules.commit(),
3016 core_instances: self.core_instances.commit(),
3017 core_type_to_rec_group: self.core_type_to_rec_group.commit(),
3018 core_type_to_supertype: self.core_type_to_supertype.commit(),
3019 core_type_to_depth: None,
3020 rec_group_elements: self.rec_group_elements.commit(),
3021 canonical_rec_groups: None,
3022 }
3023 }
3024
3025 pub fn with_unique<T>(&mut self, mut ty: T) -> T
3027 where
3028 T: Aliasable,
3029 {
3030 self.alias_mappings
3031 .insert(self.alias_counter, ty.alias_id());
3032 ty.set_alias_id(self.alias_counter);
3033 self.alias_counter += 1;
3034 ty
3035 }
3036
3037 pub fn peel_alias<T>(&self, mut ty: T) -> Option<T>
3041 where
3042 T: Aliasable,
3043 {
3044 let alias_id = ty.alias_id();
3045
3046 let i = match self
3053 .alias_snapshots
3054 .binary_search_by_key(&alias_id, |snapshot| snapshot.alias_counter)
3055 {
3056 Ok(_) => unreachable!(),
3057 Err(i) => i,
3058 };
3059
3060 ty.set_alias_id(match self.alias_snapshots.get(i) {
3064 Some(snapshot) => *snapshot.alias_mappings.get(&alias_id)?,
3065 None => *self.alias_mappings.get(&alias_id)?,
3066 });
3067 Some(ty)
3068 }
3069}
3070
3071impl<T> Index<T> for TypeList
3072where
3073 T: TypeIdentifier,
3074{
3075 type Output = T::Data;
3076
3077 fn index(&self, id: T) -> &Self::Output {
3078 let arena = T::list(self);
3079 &arena[id.index()]
3080 }
3081}
3082
3083pub(crate) struct TypeAlloc {
3086 list: TypeList,
3087
3088 globally_unique_id: usize,
3091
3092 next_resource_id: u32,
3095}
3096
3097impl Default for TypeAlloc {
3098 fn default() -> TypeAlloc {
3099 static NEXT_GLOBAL_ID: AtomicUsize = AtomicUsize::new(0);
3100 let mut ret = TypeAlloc {
3101 list: TypeList::default(),
3102 globally_unique_id: {
3103 let id = NEXT_GLOBAL_ID.fetch_add(1, Ordering::Relaxed);
3104 if id > usize::MAX - 10_000 {
3105 NEXT_GLOBAL_ID.store(usize::MAX - 10_000, Ordering::Relaxed);
3106 panic!("overflow on the global id counter");
3107 }
3108 id
3109 },
3110 next_resource_id: 0,
3111 };
3112 ret.list.core_type_to_depth = Some(Default::default());
3113 ret.list.canonical_rec_groups = Some(Default::default());
3114 ret
3115 }
3116}
3117
3118impl Deref for TypeAlloc {
3119 type Target = TypeList;
3120 fn deref(&self) -> &TypeList {
3121 &self.list
3122 }
3123}
3124
3125impl DerefMut for TypeAlloc {
3126 fn deref_mut(&mut self) -> &mut TypeList {
3127 &mut self.list
3128 }
3129}
3130
3131impl TypeAlloc {
3132 pub fn push_ty<T>(&mut self, ty: T) -> T::Id
3138 where
3139 T: TypeData,
3140 {
3141 self.list.push(ty)
3142 }
3143
3144 pub fn alloc_resource_id(&mut self) -> AliasableResourceId {
3148 let contextually_unique_id = self.next_resource_id;
3149 self.next_resource_id = self.next_resource_id.checked_add(1).unwrap();
3150 AliasableResourceId {
3151 id: ResourceId {
3152 globally_unique_id: self.globally_unique_id,
3153 contextually_unique_id,
3154 },
3155 alias_id: NO_ALIAS,
3156 }
3157 }
3158
3159 pub fn free_variables_any_type_id(
3166 &self,
3167 id: ComponentAnyTypeId,
3168 set: &mut IndexSet<ResourceId>,
3169 ) {
3170 match id {
3171 ComponentAnyTypeId::Resource(r) => {
3172 set.insert(r.resource());
3173 }
3174 ComponentAnyTypeId::Defined(id) => {
3175 self.free_variables_component_defined_type_id(id, set)
3176 }
3177 ComponentAnyTypeId::Func(id) => self.free_variables_component_func_type_id(id, set),
3178 ComponentAnyTypeId::Instance(id) => {
3179 self.free_variables_component_instance_type_id(id, set)
3180 }
3181 ComponentAnyTypeId::Component(id) => self.free_variables_component_type_id(id, set),
3182 }
3183 }
3184
3185 pub fn free_variables_component_defined_type_id(
3186 &self,
3187 id: ComponentDefinedTypeId,
3188 set: &mut IndexSet<ResourceId>,
3189 ) {
3190 match &self[id] {
3191 ComponentDefinedType::Primitive(_)
3192 | ComponentDefinedType::Flags(_)
3193 | ComponentDefinedType::Enum(_) => {}
3194 ComponentDefinedType::Record(r) => {
3195 for ty in r.fields.values() {
3196 self.free_variables_valtype(ty, set);
3197 }
3198 }
3199 ComponentDefinedType::Tuple(r) => {
3200 for ty in r.types.iter() {
3201 self.free_variables_valtype(ty, set);
3202 }
3203 }
3204 ComponentDefinedType::Variant(r) => {
3205 for ty in r.cases.values() {
3206 if let Some(ty) = &ty.ty {
3207 self.free_variables_valtype(ty, set);
3208 }
3209 }
3210 }
3211 ComponentDefinedType::List(ty) | ComponentDefinedType::Option(ty) => {
3212 self.free_variables_valtype(ty, set);
3213 }
3214 ComponentDefinedType::Result { ok, err } => {
3215 if let Some(ok) = ok {
3216 self.free_variables_valtype(ok, set);
3217 }
3218 if let Some(err) = err {
3219 self.free_variables_valtype(err, set);
3220 }
3221 }
3222 ComponentDefinedType::Own(id) | ComponentDefinedType::Borrow(id) => {
3223 set.insert(id.resource());
3224 }
3225 }
3226 }
3227
3228 pub fn free_variables_component_type_id(
3229 &self,
3230 id: ComponentTypeId,
3231 set: &mut IndexSet<ResourceId>,
3232 ) {
3233 let i = &self[id];
3234 for ty in i.imports.values().chain(i.exports.values()) {
3245 self.free_variables_component_entity(ty, set);
3246 }
3247 for (id, _path) in i.imported_resources.iter().chain(&i.defined_resources) {
3248 set.swap_remove(id);
3249 }
3250 }
3251
3252 pub fn free_variables_component_instance_type_id(
3253 &self,
3254 id: ComponentInstanceTypeId,
3255 set: &mut IndexSet<ResourceId>,
3256 ) {
3257 let i = &self[id];
3258 for ty in i.exports.values() {
3262 self.free_variables_component_entity(ty, set);
3263 }
3264 for id in i.defined_resources.iter() {
3265 set.swap_remove(id);
3266 }
3267 }
3268
3269 pub fn free_variables_component_func_type_id(
3270 &self,
3271 id: ComponentFuncTypeId,
3272 set: &mut IndexSet<ResourceId>,
3273 ) {
3274 let i = &self[id];
3275 for ty in i
3276 .params
3277 .iter()
3278 .map(|(_, ty)| ty)
3279 .chain(i.results.iter().map(|(_, ty)| ty))
3280 {
3281 self.free_variables_valtype(ty, set);
3282 }
3283 }
3284
3285 pub fn free_variables_component_entity(
3287 &self,
3288 ty: &ComponentEntityType,
3289 set: &mut IndexSet<ResourceId>,
3290 ) {
3291 match ty {
3292 ComponentEntityType::Module(_) => {}
3293 ComponentEntityType::Func(id) => self.free_variables_component_func_type_id(*id, set),
3294 ComponentEntityType::Instance(id) => {
3295 self.free_variables_component_instance_type_id(*id, set)
3296 }
3297 ComponentEntityType::Component(id) => self.free_variables_component_type_id(*id, set),
3298 ComponentEntityType::Type { created, .. } => {
3299 self.free_variables_any_type_id(*created, set);
3300 }
3301 ComponentEntityType::Value(ty) => self.free_variables_valtype(ty, set),
3302 }
3303 }
3304
3305 fn free_variables_valtype(&self, ty: &ComponentValType, set: &mut IndexSet<ResourceId>) {
3307 match ty {
3308 ComponentValType::Primitive(_) => {}
3309 ComponentValType::Type(id) => self.free_variables_component_defined_type_id(*id, set),
3310 }
3311 }
3312
3313 pub(crate) fn type_named_type_id(
3318 &self,
3319 id: ComponentDefinedTypeId,
3320 set: &Set<ComponentAnyTypeId>,
3321 ) -> bool {
3322 let ty = &self[id];
3323 match ty {
3324 ComponentDefinedType::Primitive(_) => true,
3326
3327 ComponentDefinedType::Flags(_)
3330 | ComponentDefinedType::Enum(_)
3331 | ComponentDefinedType::Record(_)
3332 | ComponentDefinedType::Variant(_) => set.contains(&ComponentAnyTypeId::from(id)),
3333
3334 ComponentDefinedType::Tuple(r) => {
3337 r.types.iter().all(|t| self.type_named_valtype(t, set))
3338 }
3339 ComponentDefinedType::Result { ok, err } => {
3340 ok.as_ref()
3341 .map(|t| self.type_named_valtype(t, set))
3342 .unwrap_or(true)
3343 && err
3344 .as_ref()
3345 .map(|t| self.type_named_valtype(t, set))
3346 .unwrap_or(true)
3347 }
3348 ComponentDefinedType::List(ty) | ComponentDefinedType::Option(ty) => {
3349 self.type_named_valtype(ty, set)
3350 }
3351
3352 ComponentDefinedType::Own(id) | ComponentDefinedType::Borrow(id) => {
3355 set.contains(&ComponentAnyTypeId::from(*id))
3356 }
3357 }
3358 }
3359
3360 pub(crate) fn type_named_valtype(
3361 &self,
3362 ty: &ComponentValType,
3363 set: &Set<ComponentAnyTypeId>,
3364 ) -> bool {
3365 match ty {
3366 ComponentValType::Primitive(_) => true,
3367 ComponentValType::Type(id) => self.type_named_type_id(*id, set),
3368 }
3369 }
3370}
3371
3372pub trait Remap
3378where
3379 Self: Index<ComponentTypeId, Output = ComponentType>,
3380 Self: Index<ComponentDefinedTypeId, Output = ComponentDefinedType>,
3381 Self: Index<ComponentInstanceTypeId, Output = ComponentInstanceType>,
3382 Self: Index<ComponentFuncTypeId, Output = ComponentFuncType>,
3383{
3384 fn push_ty<T>(&mut self, ty: T) -> T::Id
3387 where
3388 T: TypeData;
3389
3390 fn map_map(
3393 tmp: &mut IndexMap<ResourceId, Vec<usize>>,
3394 any_changed: &mut bool,
3395 map: &Remapping,
3396 ) {
3397 for (id, path) in mem::take(tmp) {
3398 let id = match map.resources.get(&id) {
3399 Some(id) => {
3400 *any_changed = true;
3401 *id
3402 }
3403 None => id,
3404 };
3405 tmp.insert(id, path);
3406 }
3407 }
3408
3409 fn insert_if_any_changed<T>(
3413 &mut self,
3414 map: &mut Remapping,
3415 any_changed: bool,
3416 id: &mut T::Id,
3417 ty: T,
3418 ) -> bool
3419 where
3420 T: TypeData,
3421 T::Id: Into<ComponentAnyTypeId>,
3422 {
3423 let new = if any_changed { self.push_ty(ty) } else { *id };
3424 map.types.insert((*id).into(), new.into());
3425 let changed = *id != new;
3426 *id = new;
3427 changed
3428 }
3429
3430 fn remap_component_any_type_id(
3434 &mut self,
3435 id: &mut ComponentAnyTypeId,
3436 map: &mut Remapping,
3437 ) -> bool {
3438 match id {
3439 ComponentAnyTypeId::Resource(id) => self.remap_resource_id(id, map),
3440 ComponentAnyTypeId::Defined(id) => self.remap_component_defined_type_id(id, map),
3441 ComponentAnyTypeId::Func(id) => self.remap_component_func_type_id(id, map),
3442 ComponentAnyTypeId::Instance(id) => self.remap_component_instance_type_id(id, map),
3443 ComponentAnyTypeId::Component(id) => self.remap_component_type_id(id, map),
3444 }
3445 }
3446
3447 fn remap_resource_id(&mut self, id: &mut AliasableResourceId, map: &Remapping) -> bool {
3450 if let Some(changed) = map.remap_id(id) {
3451 return changed;
3452 }
3453
3454 match map.resources.get(&id.resource()) {
3455 None => false,
3456 Some(new_id) => {
3457 *id.resource_mut() = *new_id;
3458 true
3459 }
3460 }
3461 }
3462
3463 fn remap_component_type_id(&mut self, id: &mut ComponentTypeId, map: &mut Remapping) -> bool {
3467 if let Some(changed) = map.remap_id(id) {
3468 return changed;
3469 }
3470
3471 let mut any_changed = false;
3472 let mut ty = self[*id].clone();
3473 for ty in ty.imports.values_mut().chain(ty.exports.values_mut()) {
3474 any_changed |= self.remap_component_entity(ty, map);
3475 }
3476 for (id, _) in ty
3477 .imported_resources
3478 .iter_mut()
3479 .chain(&mut ty.defined_resources)
3480 {
3481 if let Some(new) = map.resources.get(id) {
3482 *id = *new;
3483 any_changed = true;
3484 }
3485 }
3486 Self::map_map(&mut ty.explicit_resources, &mut any_changed, map);
3487 self.insert_if_any_changed(map, any_changed, id, ty)
3488 }
3489
3490 fn remap_component_defined_type_id(
3494 &mut self,
3495 id: &mut ComponentDefinedTypeId,
3496 map: &mut Remapping,
3497 ) -> bool {
3498 if let Some(changed) = map.remap_id(id) {
3499 return changed;
3500 }
3501
3502 let mut any_changed = false;
3503 let mut tmp = self[*id].clone();
3504 match &mut tmp {
3505 ComponentDefinedType::Primitive(_)
3506 | ComponentDefinedType::Flags(_)
3507 | ComponentDefinedType::Enum(_) => {}
3508 ComponentDefinedType::Record(r) => {
3509 for ty in r.fields.values_mut() {
3510 any_changed |= self.remap_valtype(ty, map);
3511 }
3512 }
3513 ComponentDefinedType::Tuple(r) => {
3514 for ty in r.types.iter_mut() {
3515 any_changed |= self.remap_valtype(ty, map);
3516 }
3517 }
3518 ComponentDefinedType::Variant(r) => {
3519 for ty in r.cases.values_mut() {
3520 if let Some(ty) = &mut ty.ty {
3521 any_changed |= self.remap_valtype(ty, map);
3522 }
3523 }
3524 }
3525 ComponentDefinedType::List(ty) | ComponentDefinedType::Option(ty) => {
3526 any_changed |= self.remap_valtype(ty, map);
3527 }
3528 ComponentDefinedType::Result { ok, err } => {
3529 if let Some(ok) = ok {
3530 any_changed |= self.remap_valtype(ok, map);
3531 }
3532 if let Some(err) = err {
3533 any_changed |= self.remap_valtype(err, map);
3534 }
3535 }
3536 ComponentDefinedType::Own(id) | ComponentDefinedType::Borrow(id) => {
3537 any_changed |= self.remap_resource_id(id, map);
3538 }
3539 }
3540 self.insert_if_any_changed(map, any_changed, id, tmp)
3541 }
3542
3543 fn remap_component_instance_type_id(
3547 &mut self,
3548 id: &mut ComponentInstanceTypeId,
3549 map: &mut Remapping,
3550 ) -> bool {
3551 if let Some(changed) = map.remap_id(id) {
3552 return changed;
3553 }
3554
3555 let mut any_changed = false;
3556 let mut tmp = self[*id].clone();
3557 for ty in tmp.exports.values_mut() {
3558 any_changed |= self.remap_component_entity(ty, map);
3559 }
3560 for id in tmp.defined_resources.iter_mut() {
3561 if let Some(new) = map.resources.get(id) {
3562 *id = *new;
3563 any_changed = true;
3564 }
3565 }
3566 Self::map_map(&mut tmp.explicit_resources, &mut any_changed, map);
3567 self.insert_if_any_changed(map, any_changed, id, tmp)
3568 }
3569
3570 fn remap_component_func_type_id(
3574 &mut self,
3575 id: &mut ComponentFuncTypeId,
3576 map: &mut Remapping,
3577 ) -> bool {
3578 if let Some(changed) = map.remap_id(id) {
3579 return changed;
3580 }
3581
3582 let mut any_changed = false;
3583 let mut tmp = self[*id].clone();
3584 for ty in tmp
3585 .params
3586 .iter_mut()
3587 .map(|(_, ty)| ty)
3588 .chain(tmp.results.iter_mut().map(|(_, ty)| ty))
3589 {
3590 any_changed |= self.remap_valtype(ty, map);
3591 }
3592 self.insert_if_any_changed(map, any_changed, id, tmp)
3593 }
3594
3595 fn remap_component_entity(
3597 &mut self,
3598 ty: &mut ComponentEntityType,
3599 map: &mut Remapping,
3600 ) -> bool {
3601 match ty {
3602 ComponentEntityType::Module(_) => {
3603 false
3605 }
3606 ComponentEntityType::Func(id) => self.remap_component_func_type_id(id, map),
3607 ComponentEntityType::Instance(id) => self.remap_component_instance_type_id(id, map),
3608 ComponentEntityType::Component(id) => self.remap_component_type_id(id, map),
3609 ComponentEntityType::Type {
3610 referenced,
3611 created,
3612 } => {
3613 let mut changed = self.remap_component_any_type_id(referenced, map);
3614 if *referenced == *created {
3615 *created = *referenced;
3616 } else {
3617 changed |= self.remap_component_any_type_id(created, map);
3618 }
3619 changed
3620 }
3621 ComponentEntityType::Value(ty) => self.remap_valtype(ty, map),
3622 }
3623 }
3624
3625 fn remap_valtype(&mut self, ty: &mut ComponentValType, map: &mut Remapping) -> bool {
3627 match ty {
3628 ComponentValType::Primitive(_) => false,
3629 ComponentValType::Type(id) => self.remap_component_defined_type_id(id, map),
3630 }
3631 }
3632}
3633
3634#[derive(Debug, Default)]
3637pub struct Remapping {
3638 pub(crate) resources: Map<ResourceId, ResourceId>,
3640
3641 types: Map<ComponentAnyTypeId, ComponentAnyTypeId>,
3645}
3646
3647impl Remap for TypeAlloc {
3648 fn push_ty<T>(&mut self, ty: T) -> T::Id
3649 where
3650 T: TypeData,
3651 {
3652 <TypeList>::push(self, ty)
3653 }
3654}
3655
3656impl<T> Index<T> for TypeAlloc
3657where
3658 T: TypeIdentifier,
3659{
3660 type Output = T::Data;
3661
3662 #[inline]
3663 fn index(&self, id: T) -> &T::Data {
3664 &self.list[id]
3665 }
3666}
3667
3668impl Remapping {
3669 pub fn add(&mut self, old: ResourceId, new: ResourceId) {
3671 self.resources.insert(old, new);
3672 }
3673
3674 pub fn reset_type_cache(&mut self) {
3676 self.types.clear()
3677 }
3678
3679 fn remap_id<T>(&self, id: &mut T) -> Option<bool>
3680 where
3681 T: Copy + Into<ComponentAnyTypeId> + TryFrom<ComponentAnyTypeId>,
3682 T::Error: core::fmt::Debug,
3683 {
3684 let old: ComponentAnyTypeId = (*id).into();
3685 let new = self.types.get(&old)?;
3686 if *new == old {
3687 Some(false)
3688 } else {
3689 *id = T::try_from(*new).expect("should never remap across different kinds");
3690 Some(true)
3691 }
3692 }
3693}
3694
3695pub struct SubtypeCx<'a> {
3714 pub a: SubtypeArena<'a>,
3716 pub b: SubtypeArena<'a>,
3718}
3719
3720impl<'a> SubtypeCx<'a> {
3721 pub fn new_with_refs(a: TypesRef<'a>, b: TypesRef<'a>) -> SubtypeCx<'a> {
3723 Self::new(a.list, b.list)
3724 }
3725
3726 pub(crate) fn new(a: &'a TypeList, b: &'a TypeList) -> SubtypeCx<'a> {
3727 SubtypeCx {
3728 a: SubtypeArena::new(a),
3729 b: SubtypeArena::new(b),
3730 }
3731 }
3732
3733 pub fn swap(&mut self) {
3735 mem::swap(&mut self.a, &mut self.b);
3736 }
3737
3738 fn with_checkpoint<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
3744 let a = self.a.list.checkpoint();
3745 let b = self.b.list.checkpoint();
3746 let result = f(self);
3747 self.a.list.reset_to_checkpoint(a);
3748 self.b.list.reset_to_checkpoint(b);
3749 result
3750 }
3751
3752 pub fn component_entity_type(
3756 &mut self,
3757 a: &ComponentEntityType,
3758 b: &ComponentEntityType,
3759 offset: usize,
3760 ) -> Result<()> {
3761 use ComponentEntityType::*;
3762
3763 match (a, b) {
3764 (Module(a), Module(b)) => self.module_type(*a, *b, offset),
3765 (Module(_), b) => bail!(offset, "expected {}, found module", b.desc()),
3766
3767 (Func(a), Func(b)) => self.component_func_type(*a, *b, offset),
3768 (Func(_), b) => bail!(offset, "expected {}, found func", b.desc()),
3769
3770 (Value(a), Value(b)) => self.component_val_type(a, b, offset),
3771 (Value(_), b) => bail!(offset, "expected {}, found value", b.desc()),
3772
3773 (Type { referenced: a, .. }, Type { referenced: b, .. }) => {
3774 self.component_any_type_id(*a, *b, offset)
3775 }
3776 (Type { .. }, b) => bail!(offset, "expected {}, found type", b.desc()),
3777
3778 (Instance(a), Instance(b)) => self.component_instance_type(*a, *b, offset),
3779 (Instance(_), b) => bail!(offset, "expected {}, found instance", b.desc()),
3780
3781 (Component(a), Component(b)) => self.component_type(*a, *b, offset),
3782 (Component(_), b) => bail!(offset, "expected {}, found component", b.desc()),
3783 }
3784 }
3785
3786 pub fn component_type(
3790 &mut self,
3791 a: ComponentTypeId,
3792 b: ComponentTypeId,
3793 offset: usize,
3794 ) -> Result<()> {
3795 let b_imports = self.b[b]
3849 .imports
3850 .iter()
3851 .map(|(name, ty)| (name.clone(), *ty))
3852 .collect();
3853 self.swap();
3854 let mut import_mapping =
3855 self.open_instance_type(&b_imports, a, ExternKind::Import, offset)?;
3856 self.swap();
3857 self.with_checkpoint(|this| {
3858 let mut a_exports = this.a[a]
3859 .exports
3860 .iter()
3861 .map(|(name, ty)| (name.clone(), *ty))
3862 .collect::<IndexMap<_, _>>();
3863 for ty in a_exports.values_mut() {
3864 this.a.remap_component_entity(ty, &mut import_mapping);
3865 }
3866 this.open_instance_type(&a_exports, b, ExternKind::Export, offset)?;
3867 Ok(())
3868 })
3869 }
3870
3871 pub fn component_instance_type(
3875 &mut self,
3876 a_id: ComponentInstanceTypeId,
3877 b_id: ComponentInstanceTypeId,
3878 offset: usize,
3879 ) -> Result<()> {
3880 let a = &self.a[a_id];
3885 let b = &self.b[b_id];
3886
3887 let mut exports = Vec::with_capacity(b.exports.len());
3888 for (k, b) in b.exports.iter() {
3889 match a.exports.get(k) {
3890 Some(a) => exports.push((*a, *b)),
3891 None => bail!(offset, "missing expected export `{k}`"),
3892 }
3893 }
3894 for (i, (a, b)) in exports.iter().enumerate() {
3895 let err = match self.component_entity_type(a, b, offset) {
3896 Ok(()) => continue,
3897 Err(e) => e,
3898 };
3899 let (name, _) = self.b[b_id].exports.get_index(i).unwrap();
3902 return Err(err.with_context(|| format!("type mismatch in instance export `{name}`")));
3903 }
3904 Ok(())
3905 }
3906
3907 pub fn component_func_type(
3911 &mut self,
3912 a: ComponentFuncTypeId,
3913 b: ComponentFuncTypeId,
3914 offset: usize,
3915 ) -> Result<()> {
3916 let a = &self.a[a];
3917 let b = &self.b[b];
3918
3919 if a.params.len() != b.params.len() {
3950 bail!(
3951 offset,
3952 "expected {} parameters, found {}",
3953 b.params.len(),
3954 a.params.len(),
3955 );
3956 }
3957 if a.results.len() != b.results.len() {
3958 bail!(
3959 offset,
3960 "expected {} results, found {}",
3961 b.results.len(),
3962 a.results.len(),
3963 );
3964 }
3965 for ((an, a), (bn, b)) in a.params.iter().zip(b.params.iter()) {
3966 if an != bn {
3967 bail!(offset, "expected parameter named `{bn}`, found `{an}`");
3968 }
3969 self.component_val_type(a, b, offset)
3970 .with_context(|| format!("type mismatch in function parameter `{an}`"))?;
3971 }
3972 for ((an, a), (bn, b)) in a.results.iter().zip(b.results.iter()) {
3973 if an != bn {
3974 bail!(offset, "mismatched result names");
3975 }
3976 self.component_val_type(a, b, offset)
3977 .with_context(|| "type mismatch with result type")?;
3978 }
3979 Ok(())
3980 }
3981
3982 pub fn module_type(
3986 &mut self,
3987 a: ComponentCoreModuleTypeId,
3988 b: ComponentCoreModuleTypeId,
3989 offset: usize,
3990 ) -> Result<()> {
3991 self.swap();
3997 let a_imports = &self.b[a].imports;
3998 let b_imports = &self.a[b].imports;
3999 for (k, a) in a_imports {
4000 match b_imports.get(k) {
4001 Some(b) => self
4002 .entity_type(b, a, offset)
4003 .with_context(|| format!("type mismatch in import `{}::{}`", k.0, k.1))?,
4004 None => bail!(offset, "missing expected import `{}::{}`", k.0, k.1),
4005 }
4006 }
4007 self.swap();
4008 let a = &self.a[a];
4009 let b = &self.b[b];
4010 for (k, b) in b.exports.iter() {
4011 match a.exports.get(k) {
4012 Some(a) => self
4013 .entity_type(a, b, offset)
4014 .with_context(|| format!("type mismatch in export `{k}`"))?,
4015 None => bail!(offset, "missing expected export `{k}`"),
4016 }
4017 }
4018 Ok(())
4019 }
4020
4021 pub fn component_any_type_id(
4025 &mut self,
4026 a: ComponentAnyTypeId,
4027 b: ComponentAnyTypeId,
4028 offset: usize,
4029 ) -> Result<()> {
4030 match (a, b) {
4031 (ComponentAnyTypeId::Resource(a), ComponentAnyTypeId::Resource(b)) => {
4032 if a.resource() == b.resource() {
4033 Ok(())
4034 } else {
4035 bail!(
4036 offset,
4037 "resource types are not the same ({:?} vs. {:?})",
4038 a.resource(),
4039 b.resource()
4040 )
4041 }
4042 }
4043 (ComponentAnyTypeId::Resource(_), b) => {
4044 bail!(offset, "expected {}, found resource", b.desc())
4045 }
4046 (ComponentAnyTypeId::Defined(a), ComponentAnyTypeId::Defined(b)) => {
4047 self.component_defined_type(a, b, offset)
4048 }
4049 (ComponentAnyTypeId::Defined(_), b) => {
4050 bail!(offset, "expected {}, found defined type", b.desc())
4051 }
4052
4053 (ComponentAnyTypeId::Func(a), ComponentAnyTypeId::Func(b)) => {
4054 self.component_func_type(a, b, offset)
4055 }
4056 (ComponentAnyTypeId::Func(_), b) => {
4057 bail!(offset, "expected {}, found func type", b.desc())
4058 }
4059
4060 (ComponentAnyTypeId::Instance(a), ComponentAnyTypeId::Instance(b)) => {
4061 self.component_instance_type(a, b, offset)
4062 }
4063 (ComponentAnyTypeId::Instance(_), b) => {
4064 bail!(offset, "expected {}, found instance type", b.desc())
4065 }
4066
4067 (ComponentAnyTypeId::Component(a), ComponentAnyTypeId::Component(b)) => {
4068 self.component_type(a, b, offset)
4069 }
4070 (ComponentAnyTypeId::Component(_), b) => {
4071 bail!(offset, "expected {}, found component type", b.desc())
4072 }
4073 }
4074 }
4075
4076 pub fn open_instance_type(
4100 &mut self,
4101 a: &IndexMap<String, ComponentEntityType>,
4102 b: ComponentTypeId,
4103 kind: ExternKind,
4104 offset: usize,
4105 ) -> Result<Remapping> {
4106 let component_type = &self.b[b];
4136 let entities = match kind {
4137 ExternKind::Import => &component_type.imports,
4138 ExternKind::Export => &component_type.exports,
4139 };
4140 let resources = match kind {
4141 ExternKind::Import => &component_type.imported_resources,
4142 ExternKind::Export => &component_type.defined_resources,
4143 };
4144 let mut mapping = Remapping::default();
4145 'outer: for (resource, path) in resources.iter() {
4146 let (name, ty) = entities.get_index(path[0]).unwrap();
4149 let mut ty = *ty;
4150 let mut arg = a.get(name);
4151
4152 for i in path.iter().skip(1).copied() {
4156 let id = match ty {
4157 ComponentEntityType::Instance(id) => id,
4158 _ => unreachable!(),
4159 };
4160 let (name, next_ty) = self.b[id].exports.get_index(i).unwrap();
4161 ty = *next_ty;
4162 arg = match arg {
4163 Some(ComponentEntityType::Instance(id)) => self.a[*id].exports.get(name),
4164 _ => continue 'outer,
4165 };
4166 }
4167
4168 if cfg!(debug_assertions) {
4171 let id = match ty {
4172 ComponentEntityType::Type { created, .. } => match created {
4173 ComponentAnyTypeId::Resource(id) => id.resource(),
4174 _ => unreachable!(),
4175 },
4176 _ => unreachable!(),
4177 };
4178 assert_eq!(id, *resource);
4179 }
4180
4181 if let Some(ComponentEntityType::Type { created, .. }) = arg {
4185 if let ComponentAnyTypeId::Resource(r) = created {
4186 mapping.resources.insert(*resource, r.resource());
4187 }
4188 }
4189 }
4190
4191 let mut to_typecheck = Vec::new();
4203 for (name, expected) in entities.iter() {
4204 match a.get(name) {
4205 Some(arg) => to_typecheck.push((*arg, *expected)),
4206 None => bail!(offset, "missing {} named `{name}`", kind.desc()),
4207 }
4208 }
4209 let mut type_map = Map::default();
4210 for (i, (actual, expected)) in to_typecheck.into_iter().enumerate() {
4211 let result = self.with_checkpoint(|this| {
4212 let mut expected = expected;
4213 this.b.remap_component_entity(&mut expected, &mut mapping);
4214 mapping.types.clear();
4215 this.component_entity_type(&actual, &expected, offset)
4216 });
4217 let err = match result {
4218 Ok(()) => {
4219 self.register_type_renamings(actual, expected, &mut type_map);
4225 continue;
4226 }
4227 Err(e) => e,
4228 };
4229
4230 let component_type = &self.b[b];
4233 let entities = match kind {
4234 ExternKind::Import => &component_type.imports,
4235 ExternKind::Export => &component_type.exports,
4236 };
4237 let (name, _) = entities.get_index(i).unwrap();
4238 return Err(err.with_context(|| format!("type mismatch for {} `{name}`", kind.desc())));
4239 }
4240 mapping.types = type_map;
4241 Ok(mapping)
4242 }
4243
4244 pub(crate) fn entity_type(&self, a: &EntityType, b: &EntityType, offset: usize) -> Result<()> {
4245 macro_rules! limits_match {
4246 ($a:expr, $b:expr) => {{
4247 let a = $a;
4248 let b = $b;
4249 a.initial >= b.initial
4250 && match b.maximum {
4251 Some(b_max) => match a.maximum {
4252 Some(a_max) => a_max <= b_max,
4253 None => false,
4254 },
4255 None => true,
4256 }
4257 }};
4258 }
4259
4260 match (a, b) {
4261 (EntityType::Func(a), EntityType::Func(b)) => {
4262 self.core_func_type(self.a[*a].unwrap_func(), self.b[*b].unwrap_func(), offset)
4263 }
4264 (EntityType::Func(_), b) => bail!(offset, "expected {}, found func", b.desc()),
4265 (EntityType::Table(a), EntityType::Table(b)) => {
4266 if a.element_type != b.element_type {
4267 bail!(
4268 offset,
4269 "expected table element type {}, found {}",
4270 b.element_type,
4271 a.element_type,
4272 )
4273 }
4274 if limits_match!(a, b) {
4275 Ok(())
4276 } else {
4277 bail!(offset, "mismatch in table limits")
4278 }
4279 }
4280 (EntityType::Table(_), b) => bail!(offset, "expected {}, found table", b.desc()),
4281 (EntityType::Memory(a), EntityType::Memory(b)) => {
4282 if a.shared != b.shared {
4283 bail!(offset, "mismatch in the shared flag for memories")
4284 }
4285 if a.memory64 != b.memory64 {
4286 bail!(offset, "mismatch in index type used for memories")
4287 }
4288 if limits_match!(a, b) {
4289 Ok(())
4290 } else {
4291 bail!(offset, "mismatch in memory limits")
4292 }
4293 }
4294 (EntityType::Memory(_), b) => bail!(offset, "expected {}, found memory", b.desc()),
4295 (EntityType::Global(a), EntityType::Global(b)) => {
4296 if a.mutable != b.mutable {
4297 bail!(offset, "global types differ in mutability")
4298 }
4299 if a.content_type == b.content_type {
4300 Ok(())
4301 } else {
4302 bail!(
4303 offset,
4304 "expected global type {}, found {}",
4305 b.content_type,
4306 a.content_type,
4307 )
4308 }
4309 }
4310 (EntityType::Global(_), b) => bail!(offset, "expected {}, found global", b.desc()),
4311 (EntityType::Tag(a), EntityType::Tag(b)) => {
4312 self.core_func_type(self.a[*a].unwrap_func(), self.b[*b].unwrap_func(), offset)
4313 }
4314 (EntityType::Tag(_), b) => bail!(offset, "expected {}, found tag", b.desc()),
4315 }
4316 }
4317
4318 fn core_func_type(&self, a: &FuncType, b: &FuncType, offset: usize) -> Result<()> {
4319 if a == b {
4320 Ok(())
4321 } else {
4322 bail!(
4323 offset,
4324 "expected: {}\n\
4325 found: {}",
4326 b.desc(),
4327 a.desc(),
4328 )
4329 }
4330 }
4331
4332 pub(crate) fn component_val_type(
4333 &self,
4334 a: &ComponentValType,
4335 b: &ComponentValType,
4336 offset: usize,
4337 ) -> Result<()> {
4338 match (a, b) {
4339 (ComponentValType::Primitive(a), ComponentValType::Primitive(b)) => {
4340 self.primitive_val_type(*a, *b, offset)
4341 }
4342 (ComponentValType::Type(a), ComponentValType::Type(b)) => {
4343 self.component_defined_type(*a, *b, offset)
4344 }
4345 (ComponentValType::Primitive(a), ComponentValType::Type(b)) => match &self.b[*b] {
4346 ComponentDefinedType::Primitive(b) => self.primitive_val_type(*a, *b, offset),
4347 b => bail!(offset, "expected {}, found {a}", b.desc()),
4348 },
4349 (ComponentValType::Type(a), ComponentValType::Primitive(b)) => match &self.a[*a] {
4350 ComponentDefinedType::Primitive(a) => self.primitive_val_type(*a, *b, offset),
4351 a => bail!(offset, "expected {b}, found {}", a.desc()),
4352 },
4353 }
4354 }
4355
4356 fn component_defined_type(
4357 &self,
4358 a: ComponentDefinedTypeId,
4359 b: ComponentDefinedTypeId,
4360 offset: usize,
4361 ) -> Result<()> {
4362 use ComponentDefinedType::*;
4363
4364 match (&self.a[a], &self.b[b]) {
4368 (Primitive(a), Primitive(b)) => self.primitive_val_type(*a, *b, offset),
4369 (Primitive(a), b) => bail!(offset, "expected {}, found {a}", b.desc()),
4370 (Record(a), Record(b)) => {
4371 if a.fields.len() != b.fields.len() {
4372 bail!(
4373 offset,
4374 "expected {} fields, found {}",
4375 b.fields.len(),
4376 a.fields.len(),
4377 );
4378 }
4379
4380 for ((aname, a), (bname, b)) in a.fields.iter().zip(b.fields.iter()) {
4381 if aname != bname {
4382 bail!(offset, "expected field name `{bname}`, found `{aname}`");
4383 }
4384 self.component_val_type(a, b, offset)
4385 .with_context(|| format!("type mismatch in record field `{aname}`"))?;
4386 }
4387 Ok(())
4388 }
4389 (Record(_), b) => bail!(offset, "expected {}, found record", b.desc()),
4390 (Variant(a), Variant(b)) => {
4391 if a.cases.len() != b.cases.len() {
4392 bail!(
4393 offset,
4394 "expected {} cases, found {}",
4395 b.cases.len(),
4396 a.cases.len(),
4397 );
4398 }
4399 for ((aname, a), (bname, b)) in a.cases.iter().zip(b.cases.iter()) {
4400 if aname != bname {
4401 bail!(offset, "expected case named `{bname}`, found `{aname}`");
4402 }
4403 match (&a.ty, &b.ty) {
4404 (Some(a), Some(b)) => self
4405 .component_val_type(a, b, offset)
4406 .with_context(|| format!("type mismatch in variant case `{aname}`"))?,
4407 (None, None) => {}
4408 (None, Some(_)) => {
4409 bail!(offset, "expected case `{aname}` to have a type, found none")
4410 }
4411 (Some(_), None) => bail!(offset, "expected case `{aname}` to have no type"),
4412 }
4413 }
4414 Ok(())
4415 }
4416 (Variant(_), b) => bail!(offset, "expected {}, found variant", b.desc()),
4417 (List(a), List(b)) | (Option(a), Option(b)) => self.component_val_type(a, b, offset),
4418 (List(_), b) => bail!(offset, "expected {}, found list", b.desc()),
4419 (Option(_), b) => bail!(offset, "expected {}, found option", b.desc()),
4420 (Tuple(a), Tuple(b)) => {
4421 if a.types.len() != b.types.len() {
4422 bail!(
4423 offset,
4424 "expected {} types, found {}",
4425 b.types.len(),
4426 a.types.len(),
4427 );
4428 }
4429 for (i, (a, b)) in a.types.iter().zip(b.types.iter()).enumerate() {
4430 self.component_val_type(a, b, offset)
4431 .with_context(|| format!("type mismatch in tuple field {i}"))?;
4432 }
4433 Ok(())
4434 }
4435 (Tuple(_), b) => bail!(offset, "expected {}, found tuple", b.desc()),
4436 (at @ Flags(a), Flags(b)) | (at @ Enum(a), Enum(b)) => {
4437 let desc = match at {
4438 Flags(_) => "flags",
4439 _ => "enum",
4440 };
4441 if a.len() == b.len() && a.iter().eq(b.iter()) {
4442 Ok(())
4443 } else {
4444 bail!(offset, "mismatch in {desc} elements")
4445 }
4446 }
4447 (Flags(_), b) => bail!(offset, "expected {}, found flags", b.desc()),
4448 (Enum(_), b) => bail!(offset, "expected {}, found enum", b.desc()),
4449 (Result { ok: ao, err: ae }, Result { ok: bo, err: be }) => {
4450 match (ao, bo) {
4451 (None, None) => {}
4452 (Some(a), Some(b)) => self
4453 .component_val_type(a, b, offset)
4454 .with_context(|| "type mismatch in ok variant")?,
4455 (None, Some(_)) => bail!(offset, "expected ok type, but found none"),
4456 (Some(_), None) => bail!(offset, "expected ok type to not be present"),
4457 }
4458 match (ae, be) {
4459 (None, None) => {}
4460 (Some(a), Some(b)) => self
4461 .component_val_type(a, b, offset)
4462 .with_context(|| "type mismatch in err variant")?,
4463 (None, Some(_)) => bail!(offset, "expected err type, but found none"),
4464 (Some(_), None) => bail!(offset, "expected err type to not be present"),
4465 }
4466 Ok(())
4467 }
4468 (Result { .. }, b) => bail!(offset, "expected {}, found result", b.desc()),
4469 (Own(a), Own(b)) | (Borrow(a), Borrow(b)) => {
4470 if a.resource() == b.resource() {
4471 Ok(())
4472 } else {
4473 bail!(offset, "resource types are not the same")
4474 }
4475 }
4476 (Own(_), b) => bail!(offset, "expected {}, found own", b.desc()),
4477 (Borrow(_), b) => bail!(offset, "expected {}, found borrow", b.desc()),
4478 }
4479 }
4480
4481 fn primitive_val_type(
4482 &self,
4483 a: PrimitiveValType,
4484 b: PrimitiveValType,
4485 offset: usize,
4486 ) -> Result<()> {
4487 if a == b {
4494 Ok(())
4495 } else {
4496 bail!(offset, "expected primitive `{b}` found primitive `{a}`")
4497 }
4498 }
4499
4500 fn register_type_renamings(
4501 &self,
4502 actual: ComponentEntityType,
4503 expected: ComponentEntityType,
4504 type_map: &mut Map<ComponentAnyTypeId, ComponentAnyTypeId>,
4505 ) {
4506 match (expected, actual) {
4507 (
4508 ComponentEntityType::Type {
4509 created: expected, ..
4510 },
4511 ComponentEntityType::Type {
4512 created: actual, ..
4513 },
4514 ) => {
4515 let prev = type_map.insert(expected, actual);
4516 assert!(prev.is_none());
4517 }
4518 (ComponentEntityType::Instance(expected), ComponentEntityType::Instance(actual)) => {
4519 let actual = &self.a[actual];
4520 for (name, expected) in self.b[expected].exports.iter() {
4521 let actual = actual.exports[name];
4522 self.register_type_renamings(actual, *expected, type_map);
4523 }
4524 }
4525 _ => {}
4526 }
4527 }
4528}
4529
4530pub struct SubtypeArena<'a> {
4540 types: &'a TypeList,
4541 list: TypeList,
4542}
4543
4544impl<'a> SubtypeArena<'a> {
4545 fn new(types: &'a TypeList) -> SubtypeArena<'a> {
4546 SubtypeArena {
4547 types,
4548 list: TypeList::default(),
4549 }
4550 }
4551}
4552
4553impl<T> Index<T> for SubtypeArena<'_>
4554where
4555 T: TypeIdentifier,
4556{
4557 type Output = T::Data;
4558
4559 fn index(&self, id: T) -> &T::Data {
4560 let index = id.index();
4561 if index < T::list(self.types).len() {
4562 &self.types[id]
4563 } else {
4564 let temp_index = index - T::list(self.types).len();
4565 let temp_index = u32::try_from(temp_index).unwrap();
4566 let temp_id = T::from_index(temp_index);
4567 &self.list[temp_id]
4568 }
4569 }
4570}
4571
4572impl Remap for SubtypeArena<'_> {
4573 fn push_ty<T>(&mut self, ty: T) -> T::Id
4574 where
4575 T: TypeData,
4576 {
4577 let index = T::Id::list(&self.list).len() + T::Id::list(self.types).len();
4578 let index = u32::try_from(index).unwrap();
4579 self.list.push(ty);
4580 T::Id::from_index(index)
4581 }
4582}
4583
4584pub(crate) trait Context {
4587 fn with_context<S>(self, context: impl FnOnce() -> S) -> Self
4588 where
4589 S: Into<String>;
4590}
4591
4592impl<T> Context for Result<T> {
4593 fn with_context<S>(self, context: impl FnOnce() -> S) -> Self
4594 where
4595 S: Into<String>,
4596 {
4597 match self {
4598 Ok(val) => Ok(val),
4599 Err(e) => Err(e.with_context(context)),
4600 }
4601 }
4602}
4603
4604impl Context for BinaryReaderError {
4605 fn with_context<S>(mut self, context: impl FnOnce() -> S) -> Self
4606 where
4607 S: Into<String>,
4608 {
4609 self.add_context(context().into());
4610 self
4611 }
4612}