1use super::{component::ComponentState, core::Module};
4use crate::{
5 Export, ExternalKind, FuncType, GlobalType, Import, MemoryType, PrimitiveValType, RefType,
6 TableType, TypeRef, ValType,
7};
8use indexmap::{IndexMap, IndexSet};
9use std::collections::HashMap;
10use std::{
11 borrow::Borrow,
12 fmt,
13 hash::{Hash, Hasher},
14 mem,
15 ops::{Deref, DerefMut},
16 sync::Arc,
17};
18use url::Url;
19
20const MAX_FLAT_FUNC_PARAMS: usize = 16;
25const MAX_FLAT_FUNC_RESULTS: usize = 1;
30
31const MAX_LOWERED_TYPES: usize = MAX_FLAT_FUNC_PARAMS + 1;
33
34#[derive(Debug, Eq)]
43#[repr(transparent)]
44pub struct KebabStr(str);
45
46impl KebabStr {
47 pub fn new<'a>(s: impl AsRef<str> + 'a) -> Option<&'a Self> {
51 let s = Self::new_unchecked(s);
52 if s.is_kebab_case() {
53 Some(s)
54 } else {
55 None
56 }
57 }
58
59 pub(crate) fn new_unchecked<'a>(s: impl AsRef<str> + 'a) -> &'a Self {
60 unsafe { std::mem::transmute::<_, &Self>(s.as_ref()) }
63 }
64
65 pub fn as_str(&self) -> &str {
67 &self.0
68 }
69
70 pub fn to_kebab_string(&self) -> KebabString {
72 KebabString(self.to_string())
73 }
74
75 fn is_kebab_case(&self) -> bool {
76 let mut lower = false;
77 let mut upper = false;
78 for c in self.chars() {
79 match c {
80 'a'..='z' if !lower && !upper => lower = true,
81 'A'..='Z' if !lower && !upper => upper = true,
82 'a'..='z' if lower => {}
83 'A'..='Z' if upper => {}
84 '0'..='9' if lower || upper => {}
85 '-' if lower || upper => {
86 lower = false;
87 upper = false;
88 }
89 _ => return false,
90 }
91 }
92
93 !self.is_empty() && !self.ends_with('-')
94 }
95}
96
97impl Deref for KebabStr {
98 type Target = str;
99
100 fn deref(&self) -> &str {
101 self.as_str()
102 }
103}
104
105impl PartialEq for KebabStr {
106 fn eq(&self, other: &Self) -> bool {
107 if self.len() != other.len() {
108 return false;
109 }
110
111 self.chars()
112 .zip(other.chars())
113 .all(|(a, b)| a.to_ascii_lowercase() == b.to_ascii_lowercase())
114 }
115}
116
117impl PartialEq<KebabString> for KebabStr {
118 fn eq(&self, other: &KebabString) -> bool {
119 self.eq(other.as_kebab_str())
120 }
121}
122
123impl Hash for KebabStr {
124 fn hash<H: Hasher>(&self, state: &mut H) {
125 self.len().hash(state);
126
127 for b in self.chars() {
128 b.to_ascii_lowercase().hash(state);
129 }
130 }
131}
132
133impl fmt::Display for KebabStr {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 (self as &str).fmt(f)
136 }
137}
138
139impl ToOwned for KebabStr {
140 type Owned = KebabString;
141
142 fn to_owned(&self) -> Self::Owned {
143 self.to_kebab_string()
144 }
145}
146
147#[derive(Debug, Clone, Eq)]
156pub struct KebabString(String);
157
158impl KebabString {
159 pub fn new(s: impl Into<String>) -> Option<Self> {
163 let s = s.into();
164 if KebabStr::new(&s).is_some() {
165 Some(Self(s))
166 } else {
167 None
168 }
169 }
170
171 pub fn as_str(&self) -> &str {
173 self.0.as_str()
174 }
175
176 pub fn as_kebab_str(&self) -> &KebabStr {
178 KebabStr::new_unchecked(self.as_str())
180 }
181}
182
183impl Deref for KebabString {
184 type Target = KebabStr;
185
186 fn deref(&self) -> &Self::Target {
187 self.as_kebab_str()
188 }
189}
190
191impl Borrow<KebabStr> for KebabString {
192 fn borrow(&self) -> &KebabStr {
193 self.as_kebab_str()
194 }
195}
196
197impl PartialEq for KebabString {
198 fn eq(&self, other: &Self) -> bool {
199 self.as_kebab_str().eq(other.as_kebab_str())
200 }
201}
202
203impl PartialEq<KebabStr> for KebabString {
204 fn eq(&self, other: &KebabStr) -> bool {
205 self.as_kebab_str().eq(other)
206 }
207}
208
209impl Hash for KebabString {
210 fn hash<H: Hasher>(&self, state: &mut H) {
211 self.as_kebab_str().hash(state)
212 }
213}
214
215impl fmt::Display for KebabString {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 self.as_kebab_str().fmt(f)
218 }
219}
220
221impl From<KebabString> for String {
222 fn from(s: KebabString) -> String {
223 s.0
224 }
225}
226
227pub(crate) struct LoweredTypes {
229 types: [ValType; MAX_LOWERED_TYPES],
230 len: usize,
231 max: usize,
232}
233
234impl LoweredTypes {
235 fn new(max: usize) -> Self {
236 assert!(max <= MAX_LOWERED_TYPES);
237 Self {
238 types: [ValType::I32; MAX_LOWERED_TYPES],
239 len: 0,
240 max,
241 }
242 }
243
244 fn len(&self) -> usize {
245 self.len
246 }
247
248 fn maxed(&self) -> bool {
249 self.len == self.max
250 }
251
252 fn get_mut(&mut self, index: usize) -> Option<&mut ValType> {
253 if index < self.len {
254 Some(&mut self.types[index])
255 } else {
256 None
257 }
258 }
259
260 fn push(&mut self, ty: ValType) -> bool {
261 if self.maxed() {
262 return false;
263 }
264
265 self.types[self.len] = ty;
266 self.len += 1;
267 true
268 }
269
270 fn clear(&mut self) {
271 self.len = 0;
272 }
273
274 pub fn as_slice(&self) -> &[ValType] {
275 &self.types[..self.len]
276 }
277
278 pub fn iter(&self) -> impl Iterator<Item = ValType> + '_ {
279 self.as_slice().iter().copied()
280 }
281}
282
283pub(crate) struct LoweringInfo {
285 pub(crate) params: LoweredTypes,
286 pub(crate) results: LoweredTypes,
287 pub(crate) requires_memory: bool,
288 pub(crate) requires_realloc: bool,
289}
290
291impl LoweringInfo {
292 pub(crate) fn into_func_type(self) -> FuncType {
293 FuncType::new(
294 self.params.as_slice().iter().copied(),
295 self.results.as_slice().iter().copied(),
296 )
297 }
298}
299
300impl Default for LoweringInfo {
301 fn default() -> Self {
302 Self {
303 params: LoweredTypes::new(MAX_FLAT_FUNC_PARAMS),
304 results: LoweredTypes::new(MAX_FLAT_FUNC_RESULTS),
305 requires_memory: false,
306 requires_realloc: false,
307 }
308 }
309}
310
311fn push_primitive_wasm_types(ty: &PrimitiveValType, lowered_types: &mut LoweredTypes) -> bool {
312 match ty {
313 PrimitiveValType::Bool
314 | PrimitiveValType::S8
315 | PrimitiveValType::U8
316 | PrimitiveValType::S16
317 | PrimitiveValType::U16
318 | PrimitiveValType::S32
319 | PrimitiveValType::U32
320 | PrimitiveValType::Char => lowered_types.push(ValType::I32),
321 PrimitiveValType::S64 | PrimitiveValType::U64 => lowered_types.push(ValType::I64),
322 PrimitiveValType::Float32 => lowered_types.push(ValType::F32),
323 PrimitiveValType::Float64 => lowered_types.push(ValType::F64),
324 PrimitiveValType::String => {
325 lowered_types.push(ValType::I32) && lowered_types.push(ValType::I32)
326 }
327 }
328}
329
330#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
332pub struct TypeId {
333 pub(crate) index: usize,
335 pub(crate) type_size: u32,
340 unique_id: u32,
347}
348
349const _: () = {
352 assert!(std::mem::size_of::<TypeId>() <= 16);
353};
354
355#[derive(Debug)]
357pub enum Type {
358 Func(FuncType),
360 Module(ModuleType),
364 Instance(InstanceType),
368 Component(ComponentType),
372 ComponentInstance(ComponentInstanceType),
376 ComponentFunc(ComponentFuncType),
380 Defined(ComponentDefinedType),
384}
385
386impl Type {
387 pub fn as_func_type(&self) -> Option<&FuncType> {
389 match self {
390 Self::Func(ty) => Some(ty),
391 _ => None,
392 }
393 }
394
395 pub fn as_module_type(&self) -> Option<&ModuleType> {
397 match self {
398 Self::Module(ty) => Some(ty),
399 _ => None,
400 }
401 }
402
403 pub fn as_instance_type(&self) -> Option<&InstanceType> {
405 match self {
406 Self::Instance(ty) => Some(ty),
407 _ => None,
408 }
409 }
410
411 pub fn as_component_type(&self) -> Option<&ComponentType> {
413 match self {
414 Self::Component(ty) => Some(ty),
415 _ => None,
416 }
417 }
418
419 pub fn as_component_instance_type(&self) -> Option<&ComponentInstanceType> {
421 match self {
422 Self::ComponentInstance(ty) => Some(ty),
423 _ => None,
424 }
425 }
426
427 pub fn as_component_func_type(&self) -> Option<&ComponentFuncType> {
429 match self {
430 Self::ComponentFunc(ty) => Some(ty),
431 _ => None,
432 }
433 }
434
435 pub fn as_defined_type(&self) -> Option<&ComponentDefinedType> {
437 match self {
438 Self::Defined(ty) => Some(ty),
439 _ => None,
440 }
441 }
442
443 pub(crate) fn type_size(&self) -> u32 {
444 match self {
445 Self::Func(ty) => 1 + (ty.params().len() + ty.results().len()) as u32,
446 Self::Module(ty) => ty.type_size,
447 Self::Instance(ty) => ty.type_size,
448 Self::Component(ty) => ty.type_size,
449 Self::ComponentInstance(ty) => ty.type_size,
450 Self::ComponentFunc(ty) => ty.type_size,
451 Self::Defined(ty) => ty.type_size(),
452 }
453 }
454}
455
456#[derive(Debug, Clone, Copy)]
458pub enum ComponentValType {
459 Primitive(PrimitiveValType),
461 Type(TypeId),
463}
464
465impl ComponentValType {
466 pub(crate) fn requires_realloc(&self, types: &TypeList) -> bool {
467 match self {
468 ComponentValType::Primitive(ty) => ty.requires_realloc(),
469 ComponentValType::Type(ty) => types[*ty]
470 .as_defined_type()
471 .unwrap()
472 .requires_realloc(types),
473 }
474 }
475
476 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
478 Self::internal_is_subtype_of(a, at.list, b, bt.list)
479 }
480
481 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
482 match (a, b) {
483 (ComponentValType::Primitive(a), ComponentValType::Primitive(b)) => {
484 PrimitiveValType::is_subtype_of(*a, *b)
485 }
486 (ComponentValType::Type(a), ComponentValType::Type(b)) => {
487 ComponentDefinedType::internal_is_subtype_of(
488 at[*a].as_defined_type().unwrap(),
489 at,
490 bt[*b].as_defined_type().unwrap(),
491 bt,
492 )
493 }
494 (ComponentValType::Primitive(a), ComponentValType::Type(b)) => {
495 match bt[*b].as_defined_type().unwrap() {
496 ComponentDefinedType::Primitive(b) => PrimitiveValType::is_subtype_of(*a, *b),
497 _ => false,
498 }
499 }
500 (ComponentValType::Type(a), ComponentValType::Primitive(b)) => {
501 match at[*a].as_defined_type().unwrap() {
502 ComponentDefinedType::Primitive(a) => PrimitiveValType::is_subtype_of(*a, *b),
503 _ => false,
504 }
505 }
506 }
507 }
508
509 fn push_wasm_types(&self, types: &TypeList, lowered_types: &mut LoweredTypes) -> bool {
510 match self {
511 Self::Primitive(ty) => push_primitive_wasm_types(ty, lowered_types),
512 Self::Type(id) => types[*id]
513 .as_defined_type()
514 .unwrap()
515 .push_wasm_types(types, lowered_types),
516 }
517 }
518
519 pub(crate) fn type_size(&self) -> u32 {
520 match self {
521 Self::Primitive(_) => 1,
522 Self::Type(id) => id.type_size,
523 }
524 }
525}
526
527#[derive(Debug, Clone, Copy)]
529pub enum EntityType {
530 Func(TypeId),
532 Table(TableType),
534 Memory(MemoryType),
536 Global(GlobalType),
538 Tag(TypeId),
540}
541
542impl EntityType {
543 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
545 Self::internal_is_subtype_of(a, at.list, b, bt.list)
546 }
547
548 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
549 macro_rules! limits_match {
550 ($a:expr, $b:expr) => {{
551 let a = $a;
552 let b = $b;
553 a.initial >= b.initial
554 && match b.maximum {
555 Some(b_max) => match a.maximum {
556 Some(a_max) => a_max <= b_max,
557 None => false,
558 },
559 None => true,
560 }
561 }};
562 }
563
564 match (a, b) {
565 (EntityType::Func(a), EntityType::Func(b)) => {
566 at[*a].as_func_type().unwrap() == bt[*b].as_func_type().unwrap()
567 }
568 (EntityType::Table(a), EntityType::Table(b)) => {
569 a.element_type == b.element_type && limits_match!(a, b)
570 }
571 (EntityType::Memory(a), EntityType::Memory(b)) => {
572 a.shared == b.shared && a.memory64 == b.memory64 && limits_match!(a, b)
573 }
574 (EntityType::Global(a), EntityType::Global(b)) => a == b,
575 (EntityType::Tag(a), EntityType::Tag(b)) => {
576 at[*a].as_func_type().unwrap() == bt[*b].as_func_type().unwrap()
577 }
578 _ => false,
579 }
580 }
581
582 pub(crate) fn desc(&self) -> &'static str {
583 match self {
584 Self::Func(_) => "function",
585 Self::Table(_) => "table",
586 Self::Memory(_) => "memory",
587 Self::Global(_) => "global",
588 Self::Tag(_) => "tag",
589 }
590 }
591
592 pub(crate) fn type_size(&self) -> u32 {
593 match self {
594 Self::Func(id) | Self::Tag(id) => id.type_size,
595 Self::Table(_) | Self::Memory(_) | Self::Global(_) => 1,
596 }
597 }
598}
599
600trait ModuleImportKey {
601 fn module(&self) -> &str;
602 fn name(&self) -> &str;
603}
604
605impl<'a> Borrow<dyn ModuleImportKey + 'a> for (String, String) {
606 fn borrow(&self) -> &(dyn ModuleImportKey + 'a) {
607 self
608 }
609}
610
611impl Hash for (dyn ModuleImportKey + '_) {
612 fn hash<H: Hasher>(&self, state: &mut H) {
613 self.module().hash(state);
614 self.name().hash(state);
615 }
616}
617
618impl PartialEq for (dyn ModuleImportKey + '_) {
619 fn eq(&self, other: &Self) -> bool {
620 self.module() == other.module() && self.name() == other.name()
621 }
622}
623
624impl Eq for (dyn ModuleImportKey + '_) {}
625
626impl ModuleImportKey for (String, String) {
627 fn module(&self) -> &str {
628 &self.0
629 }
630
631 fn name(&self) -> &str {
632 &self.1
633 }
634}
635
636impl ModuleImportKey for (&str, &str) {
637 fn module(&self) -> &str {
638 self.0
639 }
640
641 fn name(&self) -> &str {
642 self.1
643 }
644}
645
646#[derive(Debug, Clone)]
648pub struct ModuleType {
649 pub(crate) type_size: u32,
651 pub imports: IndexMap<(String, String), EntityType>,
653 pub exports: IndexMap<String, EntityType>,
655}
656
657impl ModuleType {
658 pub fn lookup_import(&self, module: &str, name: &str) -> Option<&EntityType> {
662 self.imports.get(&(module, name) as &dyn ModuleImportKey)
663 }
664
665 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
667 Self::internal_is_subtype_of(a, at.list, b, bt.list)
668 }
669
670 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
671 a.imports.iter().all(|(k, a)| match b.imports.get(k) {
677 Some(b) => EntityType::internal_is_subtype_of(b, bt, a, at),
678 None => false,
679 }) && b.exports.iter().all(|(k, b)| match a.exports.get(k) {
680 Some(a) => EntityType::internal_is_subtype_of(a, at, b, bt),
681 None => false,
682 })
683 }
684}
685
686#[derive(Debug, Clone)]
688pub enum InstanceTypeKind {
689 Instantiated(TypeId),
691 Exports(IndexMap<String, EntityType>),
693}
694
695#[derive(Debug, Clone)]
697pub struct InstanceType {
698 pub(crate) type_size: u32,
700 pub kind: InstanceTypeKind,
702}
703
704impl InstanceType {
705 pub fn exports<'a>(&'a self, types: TypesRef<'a>) -> &'a IndexMap<String, EntityType> {
707 self.internal_exports(types.list)
708 }
709
710 pub(crate) fn internal_exports<'a>(
711 &'a self,
712 types: &'a TypeList,
713 ) -> &'a IndexMap<String, EntityType> {
714 match &self.kind {
715 InstanceTypeKind::Instantiated(id) => &types[*id].as_module_type().unwrap().exports,
716 InstanceTypeKind::Exports(exports) => exports,
717 }
718 }
719}
720
721#[derive(Debug, Clone, Copy)]
723pub enum ComponentEntityType {
724 Module(TypeId),
726 Func(TypeId),
728 Value(ComponentValType),
730 Type {
732 referenced: TypeId,
735 created: TypeId,
742 },
743 Instance(TypeId),
745 Component(TypeId),
747}
748
749impl ComponentEntityType {
750 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
752 Self::internal_is_subtype_of(a, at.list, b, bt.list)
753 }
754
755 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
756 match (a, b) {
757 (Self::Module(a), Self::Module(b)) => ModuleType::internal_is_subtype_of(
758 at[*a].as_module_type().unwrap(),
759 at,
760 bt[*b].as_module_type().unwrap(),
761 bt,
762 ),
763 (Self::Func(a), Self::Func(b)) => ComponentFuncType::internal_is_subtype_of(
764 at[*a].as_component_func_type().unwrap(),
765 at,
766 bt[*b].as_component_func_type().unwrap(),
767 bt,
768 ),
769 (Self::Value(a), Self::Value(b)) => {
770 ComponentValType::internal_is_subtype_of(a, at, b, bt)
771 }
772 (Self::Type { referenced: a, .. }, Self::Type { referenced: b, .. }) => {
773 ComponentDefinedType::internal_is_subtype_of(
774 at[*a].as_defined_type().unwrap(),
775 at,
776 bt[*b].as_defined_type().unwrap(),
777 bt,
778 )
779 }
780 (Self::Instance(a), Self::Instance(b)) => {
781 ComponentInstanceType::internal_is_subtype_of(
782 at[*a].as_component_instance_type().unwrap(),
783 at,
784 bt[*b].as_component_instance_type().unwrap(),
785 bt,
786 )
787 }
788 (Self::Component(a), Self::Component(b)) => ComponentType::internal_is_subtype_of(
789 at[*a].as_component_type().unwrap(),
790 at,
791 bt[*b].as_component_type().unwrap(),
792 bt,
793 ),
794 _ => false,
795 }
796 }
797
798 pub(crate) fn desc(&self) -> &'static str {
799 match self {
800 Self::Module(_) => "module",
801 Self::Func(_) => "function",
802 Self::Value(_) => "value",
803 Self::Type { .. } => "type",
804 Self::Instance(_) => "instance",
805 Self::Component(_) => "component",
806 }
807 }
808
809 pub(crate) fn type_size(&self) -> u32 {
810 match self {
811 Self::Module(ty)
812 | Self::Func(ty)
813 | Self::Type { referenced: ty, .. }
814 | Self::Instance(ty)
815 | Self::Component(ty) => ty.type_size,
816 Self::Value(ty) => ty.type_size(),
817 }
818 }
819}
820
821#[derive(Debug, Clone)]
823pub struct ComponentType {
824 pub(crate) type_size: u32,
826 pub imports: IndexMap<KebabString, (Option<Url>, ComponentEntityType)>,
828 pub exports: IndexMap<KebabString, (Option<Url>, ComponentEntityType)>,
830}
831
832impl ComponentType {
833 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
835 Self::internal_is_subtype_of(a, at.list, b, bt.list)
836 }
837
838 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
839 a.imports.iter().all(|(k, (_, a))| match b.imports.get(k) {
845 Some((_, b)) => ComponentEntityType::internal_is_subtype_of(b, bt, a, at),
846 None => false,
847 }) && b.exports.iter().all(|(k, (_, b))| match a.exports.get(k) {
848 Some((_, a)) => ComponentEntityType::internal_is_subtype_of(a, at, b, bt),
849 None => false,
850 })
851 }
852}
853
854#[derive(Debug, Clone)]
856pub enum ComponentInstanceTypeKind {
857 Defined(IndexMap<KebabString, (Option<Url>, ComponentEntityType)>),
859 Instantiated(TypeId),
861 Exports(IndexMap<KebabString, (Option<Url>, ComponentEntityType)>),
863}
864
865#[derive(Debug, Clone)]
867pub struct ComponentInstanceType {
868 pub(crate) type_size: u32,
870 pub kind: ComponentInstanceTypeKind,
872}
873
874impl ComponentInstanceType {
875 pub fn exports<'a>(
877 &'a self,
878 types: TypesRef<'a>,
879 ) -> impl ExactSizeIterator<Item = (&'a KebabStr, &'a Option<Url>, ComponentEntityType)> + Clone
880 {
881 self.internal_exports(types.list)
882 .iter()
883 .map(|(n, (u, t))| (n.as_kebab_str(), u, *t))
884 }
885
886 pub(crate) fn internal_exports<'a>(
887 &'a self,
888 types: &'a TypeList,
889 ) -> &'a IndexMap<KebabString, (Option<Url>, ComponentEntityType)> {
890 match &self.kind {
891 ComponentInstanceTypeKind::Defined(exports)
892 | ComponentInstanceTypeKind::Exports(exports) => exports,
893 ComponentInstanceTypeKind::Instantiated(id) => {
894 &types[*id].as_component_type().unwrap().exports
895 }
896 }
897 }
898
899 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
901 Self::internal_is_subtype_of(a, at.list, b, bt.list)
902 }
903
904 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
905 let exports = a.internal_exports(at);
906
907 b.internal_exports(bt)
911 .iter()
912 .all(|(k, (_, b))| match exports.get(k) {
913 Some((_, a)) => ComponentEntityType::internal_is_subtype_of(a, at, b, bt),
914 None => false,
915 })
916 }
917}
918
919#[derive(Debug, Clone)]
921pub struct ComponentFuncType {
922 pub(crate) type_size: u32,
924 pub params: Box<[(KebabString, ComponentValType)]>,
926 pub results: Box<[(Option<KebabString>, ComponentValType)]>,
928}
929
930impl ComponentFuncType {
931 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
933 Self::internal_is_subtype_of(a, at.list, b, bt.list)
934 }
935
936 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
937 a.params.len() == b.params.len()
964 && a.results.len() == b.results.len()
965 && a.params
966 .iter()
967 .zip(b.params.iter())
968 .all(|((an, a), (bn, b))| {
969 an == bn && ComponentValType::internal_is_subtype_of(a, at, b, bt)
970 })
971 && a.results
972 .iter()
973 .zip(b.results.iter())
974 .all(|((an, a), (bn, b))| {
975 an == bn && ComponentValType::internal_is_subtype_of(a, at, b, bt)
976 })
977 }
978
979 pub(crate) fn lower(&self, types: &TypeList, import: bool) -> LoweringInfo {
982 let mut info = LoweringInfo::default();
983
984 for (_, ty) in self.params.iter() {
985 if !import && !info.requires_realloc {
988 info.requires_realloc = ty.requires_realloc(types);
989 }
990
991 if !ty.push_wasm_types(types, &mut info.params) {
992 info.params.clear();
996 assert!(info.params.push(ValType::I32));
997 info.requires_memory = true;
998
999 if !import {
1001 info.requires_realloc = true;
1002 }
1003 break;
1004 }
1005 }
1006
1007 for (_, ty) in self.results.iter() {
1008 if import && !info.requires_realloc {
1011 info.requires_realloc = ty.requires_realloc(types);
1012 }
1013
1014 if !ty.push_wasm_types(types, &mut info.results) {
1015 info.results.clear();
1018 if import {
1019 info.params.max = MAX_LOWERED_TYPES;
1020 assert!(info.params.push(ValType::I32));
1021 } else {
1022 assert!(info.results.push(ValType::I32));
1023 }
1024 info.requires_memory = true;
1025 break;
1026 }
1027 }
1028
1029 info.requires_memory |= info.requires_realloc;
1031
1032 info
1033 }
1034}
1035
1036#[derive(Debug, Clone)]
1038pub struct VariantCase {
1039 pub ty: Option<ComponentValType>,
1041 pub refines: Option<KebabString>,
1043}
1044
1045#[derive(Debug, Clone)]
1047pub struct RecordType {
1048 pub(crate) type_size: u32,
1050 pub fields: IndexMap<KebabString, ComponentValType>,
1052}
1053
1054#[derive(Debug, Clone)]
1056pub struct VariantType {
1057 pub(crate) type_size: u32,
1059 pub cases: IndexMap<KebabString, VariantCase>,
1061}
1062
1063#[derive(Debug, Clone)]
1065pub struct TupleType {
1066 pub(crate) type_size: u32,
1068 pub types: Box<[ComponentValType]>,
1070}
1071
1072#[derive(Debug, Clone)]
1074pub struct UnionType {
1075 pub(crate) type_size: u32,
1077 pub types: Box<[ComponentValType]>,
1079}
1080
1081#[derive(Debug, Clone)]
1083pub enum ComponentDefinedType {
1084 Primitive(PrimitiveValType),
1086 Record(RecordType),
1088 Variant(VariantType),
1090 List(ComponentValType),
1092 Tuple(TupleType),
1094 Flags(IndexSet<KebabString>),
1096 Enum(IndexSet<KebabString>),
1098 Union(UnionType),
1100 Option(ComponentValType),
1102 Result {
1104 ok: Option<ComponentValType>,
1106 err: Option<ComponentValType>,
1108 },
1109}
1110
1111impl ComponentDefinedType {
1112 pub(crate) fn requires_realloc(&self, types: &TypeList) -> bool {
1113 match self {
1114 Self::Primitive(ty) => ty.requires_realloc(),
1115 Self::Record(r) => r.fields.values().any(|ty| ty.requires_realloc(types)),
1116 Self::Variant(v) => v.cases.values().any(|case| {
1117 case.ty
1118 .map(|ty| ty.requires_realloc(types))
1119 .unwrap_or(false)
1120 }),
1121 Self::List(_) => true,
1122 Self::Tuple(t) => t.types.iter().any(|ty| ty.requires_realloc(types)),
1123 Self::Union(u) => u.types.iter().any(|ty| ty.requires_realloc(types)),
1124 Self::Flags(_) | Self::Enum(_) => false,
1125 Self::Option(ty) => ty.requires_realloc(types),
1126 Self::Result { ok, err } => {
1127 ok.map(|ty| ty.requires_realloc(types)).unwrap_or(false)
1128 || err.map(|ty| ty.requires_realloc(types)).unwrap_or(false)
1129 }
1130 }
1131 }
1132
1133 pub fn is_subtype_of(a: &Self, at: TypesRef, b: &Self, bt: TypesRef) -> bool {
1135 Self::internal_is_subtype_of(a, at.list, b, bt.list)
1136 }
1137
1138 pub(crate) fn internal_is_subtype_of(a: &Self, at: &TypeList, b: &Self, bt: &TypeList) -> bool {
1139 match (a, b) {
1143 (Self::Primitive(a), Self::Primitive(b)) => PrimitiveValType::is_subtype_of(*a, *b),
1144 (Self::Record(a), Self::Record(b)) => {
1145 a.fields.len() == b.fields.len()
1146 && a.fields
1147 .iter()
1148 .zip(b.fields.iter())
1149 .all(|((aname, a), (bname, b))| {
1150 aname == bname && ComponentValType::internal_is_subtype_of(a, at, b, bt)
1151 })
1152 }
1153 (Self::Variant(a), Self::Variant(b)) => {
1154 a.cases.len() == b.cases.len()
1155 && a.cases
1156 .iter()
1157 .zip(b.cases.iter())
1158 .all(|((aname, a), (bname, b))| {
1159 aname == bname
1160 && match (&a.ty, &b.ty) {
1161 (Some(a), Some(b)) => {
1162 ComponentValType::internal_is_subtype_of(a, at, b, bt)
1163 }
1164 (None, None) => true,
1165 _ => false,
1166 }
1167 })
1168 }
1169 (Self::List(a), Self::List(b)) | (Self::Option(a), Self::Option(b)) => {
1170 ComponentValType::internal_is_subtype_of(a, at, b, bt)
1171 }
1172 (Self::Tuple(a), Self::Tuple(b)) => {
1173 if a.types.len() != b.types.len() {
1174 return false;
1175 }
1176 a.types
1177 .iter()
1178 .zip(b.types.iter())
1179 .all(|(a, b)| ComponentValType::internal_is_subtype_of(a, at, b, bt))
1180 }
1181 (Self::Union(a), Self::Union(b)) => {
1182 if a.types.len() != b.types.len() {
1183 return false;
1184 }
1185 a.types
1186 .iter()
1187 .zip(b.types.iter())
1188 .all(|(a, b)| ComponentValType::internal_is_subtype_of(a, at, b, bt))
1189 }
1190 (Self::Flags(a), Self::Flags(b)) | (Self::Enum(a), Self::Enum(b)) => {
1191 a.len() == b.len() && a.iter().eq(b.iter())
1192 }
1193 (Self::Result { ok: ao, err: ae }, Self::Result { ok: bo, err: be }) => {
1194 Self::is_optional_subtype_of(*ao, at, *bo, bt)
1195 && Self::is_optional_subtype_of(*ae, at, *be, bt)
1196 }
1197 _ => false,
1198 }
1199 }
1200
1201 pub(crate) fn type_size(&self) -> u32 {
1202 match self {
1203 Self::Primitive(_) => 1,
1204 Self::Flags(_) | Self::Enum(_) => 1,
1205 Self::Record(r) => r.type_size,
1206 Self::Variant(v) => v.type_size,
1207 Self::Tuple(t) => t.type_size,
1208 Self::Union(u) => u.type_size,
1209 Self::List(ty) | Self::Option(ty) => ty.type_size(),
1210 Self::Result { ok, err } => {
1211 ok.map(|ty| ty.type_size()).unwrap_or(1) + err.map(|ty| ty.type_size()).unwrap_or(1)
1212 }
1213 }
1214 }
1215
1216 fn is_optional_subtype_of(
1217 a: Option<ComponentValType>,
1218 at: &TypeList,
1219 b: Option<ComponentValType>,
1220 bt: &TypeList,
1221 ) -> bool {
1222 match (a, b) {
1223 (None, None) => true,
1224 (Some(a), Some(b)) => ComponentValType::internal_is_subtype_of(&a, at, &b, bt),
1225 _ => false,
1226 }
1227 }
1228 fn push_wasm_types(&self, types: &TypeList, lowered_types: &mut LoweredTypes) -> bool {
1229 match self {
1230 Self::Primitive(ty) => push_primitive_wasm_types(ty, lowered_types),
1231 Self::Record(r) => r
1232 .fields
1233 .iter()
1234 .all(|(_, ty)| ty.push_wasm_types(types, lowered_types)),
1235 Self::Variant(v) => Self::push_variant_wasm_types(
1236 v.cases.iter().filter_map(|(_, case)| case.ty.as_ref()),
1237 types,
1238 lowered_types,
1239 ),
1240 Self::List(_) => lowered_types.push(ValType::I32) && lowered_types.push(ValType::I32),
1241 Self::Tuple(t) => t
1242 .types
1243 .iter()
1244 .all(|ty| ty.push_wasm_types(types, lowered_types)),
1245 Self::Flags(names) => {
1246 (0..(names.len() + 31) / 32).all(|_| lowered_types.push(ValType::I32))
1247 }
1248 Self::Enum(_) => lowered_types.push(ValType::I32),
1249 Self::Union(u) => Self::push_variant_wasm_types(u.types.iter(), types, lowered_types),
1250 Self::Option(ty) => {
1251 Self::push_variant_wasm_types([ty].into_iter(), types, lowered_types)
1252 }
1253 Self::Result { ok, err } => {
1254 Self::push_variant_wasm_types(ok.iter().chain(err.iter()), types, lowered_types)
1255 }
1256 }
1257 }
1258
1259 fn push_variant_wasm_types<'a>(
1260 cases: impl Iterator<Item = &'a ComponentValType>,
1261 types: &TypeList,
1262 lowered_types: &mut LoweredTypes,
1263 ) -> bool {
1264 if !lowered_types.push(ValType::I32) {
1266 return false;
1267 }
1268
1269 let start = lowered_types.len();
1270
1271 for ty in cases {
1272 let mut temp = LoweredTypes::new(lowered_types.max);
1273
1274 if !ty.push_wasm_types(types, &mut temp) {
1275 return false;
1276 }
1277
1278 for (i, ty) in temp.iter().enumerate() {
1279 match lowered_types.get_mut(start + i) {
1280 Some(prev) => *prev = Self::join_types(*prev, ty),
1281 None => {
1282 if !lowered_types.push(ty) {
1283 return false;
1284 }
1285 }
1286 }
1287 }
1288 }
1289
1290 true
1291 }
1292
1293 fn join_types(a: ValType, b: ValType) -> ValType {
1294 use ValType::*;
1295
1296 match (a, b) {
1297 (I32, I32) | (I64, I64) | (F32, F32) | (F64, F64) => a,
1298 (I32, F32) | (F32, I32) => I32,
1299 (_, I64 | F64) | (I64 | F64, _) => I64,
1300 _ => panic!("unexpected wasm type for canonical ABI"),
1301 }
1302 }
1303}
1304
1305#[allow(clippy::large_enum_variant)]
1306enum TypesKind {
1307 Module(Arc<Module>),
1308 Component(ComponentState),
1309}
1310
1311pub struct Types {
1315 list: TypeList,
1316 kind: TypesKind,
1317}
1318
1319#[derive(Clone, Copy)]
1320enum TypesRefKind<'a> {
1321 Module(&'a Module),
1322 Component(&'a ComponentState),
1323}
1324
1325#[derive(Clone, Copy)]
1329pub struct TypesRef<'a> {
1330 list: &'a TypeList,
1331 kind: TypesRefKind<'a>,
1332}
1333
1334impl<'a> TypesRef<'a> {
1335 pub(crate) fn from_module(types: &'a TypeList, module: &'a Module) -> Self {
1336 Self {
1337 list: types,
1338 kind: TypesRefKind::Module(module),
1339 }
1340 }
1341
1342 pub(crate) fn from_component(types: &'a TypeList, component: &'a ComponentState) -> Self {
1343 Self {
1344 list: types,
1345 kind: TypesRefKind::Component(component),
1346 }
1347 }
1348
1349 fn types(&self, core: bool) -> Option<&'a [TypeId]> {
1350 Some(match &self.kind {
1351 TypesRefKind::Module(module) => {
1352 if core {
1353 &module.types
1354 } else {
1355 return None;
1356 }
1357 }
1358 TypesRefKind::Component(component) => {
1359 if core {
1360 &component.core_types
1361 } else {
1362 &component.types
1363 }
1364 }
1365 })
1366 }
1367
1368 pub fn type_from_id(&self, id: TypeId) -> Option<&'a Type> {
1372 self.list.get(id.index)
1373 }
1374
1375 pub fn id_from_type_index(&self, index: u32, core: bool) -> Option<TypeId> {
1380 self.types(core)?.get(index as usize).copied()
1381 }
1382
1383 pub fn type_at(&self, index: u32, core: bool) -> Option<&'a Type> {
1388 self.type_from_id(*self.types(core)?.get(index as usize)?)
1389 }
1390
1391 pub fn func_type_at(&self, index: u32) -> Option<&'a FuncType> {
1396 match self.type_at(index, true)? {
1397 Type::Func(ty) => Some(ty),
1398 _ => None,
1399 }
1400 }
1401
1402 pub fn table_at(&self, index: u32) -> Option<TableType> {
1407 let tables = match &self.kind {
1408 TypesRefKind::Module(module) => &module.tables,
1409 TypesRefKind::Component(component) => &component.core_tables,
1410 };
1411
1412 tables.get(index as usize).copied()
1413 }
1414
1415 pub fn memory_at(&self, index: u32) -> Option<MemoryType> {
1420 let memories = match &self.kind {
1421 TypesRefKind::Module(module) => &module.memories,
1422 TypesRefKind::Component(component) => &component.core_memories,
1423 };
1424
1425 memories.get(index as usize).copied()
1426 }
1427
1428 pub fn global_at(&self, index: u32) -> Option<GlobalType> {
1433 let globals = match &self.kind {
1434 TypesRefKind::Module(module) => &module.globals,
1435 TypesRefKind::Component(component) => &component.core_globals,
1436 };
1437
1438 globals.get(index as usize).copied()
1439 }
1440
1441 pub fn tag_at(&self, index: u32) -> Option<&'a FuncType> {
1446 let tags = match &self.kind {
1447 TypesRefKind::Module(module) => &module.tags,
1448 TypesRefKind::Component(component) => &component.core_tags,
1449 };
1450
1451 Some(
1452 self.list[*tags.get(index as usize)?]
1453 .as_func_type()
1454 .unwrap(),
1455 )
1456 }
1457
1458 pub fn function_at(&self, index: u32) -> Option<&'a FuncType> {
1463 let id = match &self.kind {
1464 TypesRefKind::Module(module) => {
1465 &module.types[*module.functions.get(index as usize)? as usize]
1466 }
1467 TypesRefKind::Component(component) => component.core_funcs.get(index as usize)?,
1468 };
1469
1470 match &self.list[*id] {
1471 Type::Func(ty) => Some(ty),
1472 _ => None,
1473 }
1474 }
1475
1476 pub fn element_at(&self, index: u32) -> Option<RefType> {
1481 match &self.kind {
1482 TypesRefKind::Module(module) => module.element_types.get(index as usize).copied(),
1483 TypesRefKind::Component(_) => None,
1484 }
1485 }
1486
1487 pub fn component_function_at(&self, index: u32) -> Option<&'a ComponentFuncType> {
1492 match &self.kind {
1493 TypesRefKind::Module(_) => None,
1494 TypesRefKind::Component(component) => Some(
1495 self.list[*component.funcs.get(index as usize)?]
1496 .as_component_func_type()
1497 .unwrap(),
1498 ),
1499 }
1500 }
1501
1502 pub fn module_at(&self, index: u32) -> Option<&'a ModuleType> {
1507 match &self.kind {
1508 TypesRefKind::Module(_) => None,
1509 TypesRefKind::Component(component) => Some(
1510 self.list[*component.core_modules.get(index as usize)?]
1511 .as_module_type()
1512 .unwrap(),
1513 ),
1514 }
1515 }
1516
1517 pub fn instance_at(&self, index: u32) -> Option<&'a InstanceType> {
1522 match &self.kind {
1523 TypesRefKind::Module(_) => None,
1524 TypesRefKind::Component(component) => {
1525 let id = component.core_instances.get(index as usize)?;
1526 match &self.list[*id] {
1527 Type::Instance(ty) => Some(ty),
1528 _ => None,
1529 }
1530 }
1531 }
1532 }
1533
1534 pub fn component_at(&self, index: u32) -> Option<&'a ComponentType> {
1539 match &self.kind {
1540 TypesRefKind::Module(_) => None,
1541 TypesRefKind::Component(component) => Some(
1542 self.list[*component.components.get(index as usize)?]
1543 .as_component_type()
1544 .unwrap(),
1545 ),
1546 }
1547 }
1548
1549 pub fn component_instance_at(&self, index: u32) -> Option<&'a ComponentInstanceType> {
1554 match &self.kind {
1555 TypesRefKind::Module(_) => None,
1556 TypesRefKind::Component(component) => {
1557 let id = component.instances.get(index as usize)?;
1558 match &self.list[*id] {
1559 Type::ComponentInstance(ty) => Some(ty),
1560 _ => None,
1561 }
1562 }
1563 }
1564 }
1565
1566 pub fn value_at(&self, index: u32) -> Option<ComponentValType> {
1571 match &self.kind {
1572 TypesRefKind::Module(_) => None,
1573 TypesRefKind::Component(component) => {
1574 component.values.get(index as usize).map(|(r, _)| *r)
1575 }
1576 }
1577 }
1578
1579 pub fn entity_type_from_import(&self, import: &Import) -> Option<EntityType> {
1581 match &self.kind {
1582 TypesRefKind::Module(module) => Some(match import.ty {
1583 TypeRef::Func(idx) => EntityType::Func(*module.types.get(idx as usize)?),
1584 TypeRef::Table(ty) => EntityType::Table(ty),
1585 TypeRef::Memory(ty) => EntityType::Memory(ty),
1586 TypeRef::Global(ty) => EntityType::Global(ty),
1587 TypeRef::Tag(ty) => EntityType::Tag(*module.types.get(ty.func_type_idx as usize)?),
1588 }),
1589 TypesRefKind::Component(_) => None,
1590 }
1591 }
1592
1593 pub fn entity_type_from_export(&self, export: &Export) -> Option<EntityType> {
1595 match &self.kind {
1596 TypesRefKind::Module(module) => Some(match export.kind {
1597 ExternalKind::Func => EntityType::Func(
1598 module.types[*module.functions.get(export.index as usize)? as usize],
1599 ),
1600 ExternalKind::Table => {
1601 EntityType::Table(*module.tables.get(export.index as usize)?)
1602 }
1603 ExternalKind::Memory => {
1604 EntityType::Memory(*module.memories.get(export.index as usize)?)
1605 }
1606 ExternalKind::Global => {
1607 EntityType::Global(*module.globals.get(export.index as usize)?)
1608 }
1609 ExternalKind::Tag => EntityType::Tag(
1610 module.types[*module.functions.get(export.index as usize)? as usize],
1611 ),
1612 }),
1613 TypesRefKind::Component(_) => None,
1614 }
1615 }
1616
1617 pub fn component_entity_type_of_extern(&self, name: &str) -> Option<ComponentEntityType> {
1619 match &self.kind {
1620 TypesRefKind::Module(_) => None,
1621 TypesRefKind::Component(component) => {
1622 let key = KebabStr::new(name)?;
1623 Some(component.externs.get(key)?.1)
1624 }
1625 }
1626 }
1627}
1628
1629impl Types {
1630 pub(crate) fn from_module(types: TypeList, module: Arc<Module>) -> Self {
1631 Self {
1632 list: types,
1633 kind: TypesKind::Module(module),
1634 }
1635 }
1636
1637 pub(crate) fn from_component(types: TypeList, component: ComponentState) -> Self {
1638 Self {
1639 list: types,
1640 kind: TypesKind::Component(component),
1641 }
1642 }
1643
1644 pub fn as_ref(&self) -> TypesRef {
1646 TypesRef {
1647 list: &self.list,
1648 kind: match &self.kind {
1649 TypesKind::Module(module) => TypesRefKind::Module(module),
1650 TypesKind::Component(component) => TypesRefKind::Component(component),
1651 },
1652 }
1653 }
1654
1655 pub fn type_from_id(&self, id: TypeId) -> Option<&Type> {
1659 self.as_ref().type_from_id(id)
1660 }
1661
1662 pub fn id_from_type_index(&self, index: u32, core: bool) -> Option<TypeId> {
1666 self.as_ref().id_from_type_index(index, core)
1667 }
1668
1669 pub fn type_at(&self, index: u32, core: bool) -> Option<&Type> {
1673 self.as_ref().type_at(index, core)
1674 }
1675
1676 pub fn func_type_at(&self, index: u32) -> Option<&FuncType> {
1680 self.as_ref().func_type_at(index)
1681 }
1682
1683 pub fn type_count(&self) -> usize {
1685 match &self.kind {
1686 TypesKind::Module(module) => module.types.len(),
1687 TypesKind::Component(component) => component.core_types.len(),
1688 }
1689 }
1690
1691 pub fn table_at(&self, index: u32) -> Option<TableType> {
1695 self.as_ref().table_at(index)
1696 }
1697
1698 pub fn table_count(&self) -> usize {
1700 match &self.kind {
1701 TypesKind::Module(module) => module.tables.len(),
1702 TypesKind::Component(component) => component.core_tables.len(),
1703 }
1704 }
1705
1706 pub fn memory_at(&self, index: u32) -> Option<MemoryType> {
1710 self.as_ref().memory_at(index)
1711 }
1712
1713 pub fn memory_count(&self) -> usize {
1715 match &self.kind {
1716 TypesKind::Module(module) => module.memories.len(),
1717 TypesKind::Component(component) => component.core_memories.len(),
1718 }
1719 }
1720
1721 pub fn global_at(&self, index: u32) -> Option<GlobalType> {
1725 self.as_ref().global_at(index)
1726 }
1727
1728 pub fn global_count(&self) -> usize {
1730 match &self.kind {
1731 TypesKind::Module(module) => module.globals.len(),
1732 TypesKind::Component(component) => component.core_globals.len(),
1733 }
1734 }
1735
1736 pub fn tag_at(&self, index: u32) -> Option<&FuncType> {
1740 self.as_ref().tag_at(index)
1741 }
1742
1743 pub fn tag_count(&self) -> usize {
1745 match &self.kind {
1746 TypesKind::Module(module) => module.tags.len(),
1747 TypesKind::Component(component) => component.core_tags.len(),
1748 }
1749 }
1750
1751 pub fn function_at(&self, index: u32) -> Option<&FuncType> {
1755 self.as_ref().function_at(index)
1756 }
1757
1758 pub fn function_count(&self) -> usize {
1762 match &self.kind {
1763 TypesKind::Module(module) => module.functions.len(),
1764 TypesKind::Component(component) => component.core_funcs.len(),
1765 }
1766 }
1767
1768 pub fn element_at(&self, index: u32) -> Option<RefType> {
1772 match &self.kind {
1773 TypesKind::Module(module) => module.element_types.get(index as usize).copied(),
1774 TypesKind::Component(_) => None,
1775 }
1776 }
1777
1778 pub fn element_count(&self) -> usize {
1780 match &self.kind {
1781 TypesKind::Module(module) => module.element_types.len(),
1782 TypesKind::Component(_) => 0,
1783 }
1784 }
1785
1786 pub fn component_function_at(&self, index: u32) -> Option<&ComponentFuncType> {
1790 self.as_ref().component_function_at(index)
1791 }
1792
1793 pub fn component_function_count(&self) -> usize {
1795 match &self.kind {
1796 TypesKind::Module(_) => 0,
1797 TypesKind::Component(component) => component.funcs.len(),
1798 }
1799 }
1800
1801 pub fn module_at(&self, index: u32) -> Option<&ModuleType> {
1805 self.as_ref().module_at(index)
1806 }
1807
1808 pub fn module_count(&self) -> usize {
1810 match &self.kind {
1811 TypesKind::Module(_) => 0,
1812 TypesKind::Component(component) => component.core_modules.len(),
1813 }
1814 }
1815
1816 pub fn instance_at(&self, index: u32) -> Option<&InstanceType> {
1820 self.as_ref().instance_at(index)
1821 }
1822
1823 pub fn instance_count(&self) -> usize {
1825 match &self.kind {
1826 TypesKind::Module(_) => 0,
1827 TypesKind::Component(component) => component.core_instances.len(),
1828 }
1829 }
1830
1831 pub fn component_at(&self, index: u32) -> Option<&ComponentType> {
1835 self.as_ref().component_at(index)
1836 }
1837
1838 pub fn component_count(&self) -> usize {
1840 match &self.kind {
1841 TypesKind::Module(_) => 0,
1842 TypesKind::Component(component) => component.components.len(),
1843 }
1844 }
1845
1846 pub fn component_instance_at(&self, index: u32) -> Option<&ComponentInstanceType> {
1850 self.as_ref().component_instance_at(index)
1851 }
1852
1853 pub fn component_instance_count(&self) -> usize {
1855 match &self.kind {
1856 TypesKind::Module(_) => 0,
1857 TypesKind::Component(component) => component.instances.len(),
1858 }
1859 }
1860
1861 pub fn value_at(&self, index: u32) -> Option<ComponentValType> {
1865 self.as_ref().value_at(index)
1866 }
1867
1868 pub fn value_count(&self) -> usize {
1870 match &self.kind {
1871 TypesKind::Module(_) => 0,
1872 TypesKind::Component(component) => component.values.len(),
1873 }
1874 }
1875
1876 pub fn entity_type_from_import(&self, import: &Import) -> Option<EntityType> {
1878 self.as_ref().entity_type_from_import(import)
1879 }
1880
1881 pub fn entity_type_from_export(&self, export: &Export) -> Option<EntityType> {
1883 self.as_ref().entity_type_from_export(export)
1884 }
1885
1886 pub fn component_entity_type_of_extern(&self, name: &str) -> Option<ComponentEntityType> {
1889 self.as_ref().component_entity_type_of_extern(name)
1890 }
1891
1892 pub fn peel_alias(&self, ty: TypeId) -> Option<TypeId> {
1896 self.list.peel_alias(ty)
1897 }
1898}
1899
1900pub(crate) struct SnapshotList<T> {
1912 snapshots: Vec<Arc<Snapshot<T>>>,
1922
1923 snapshots_total: usize,
1925
1926 cur: Vec<T>,
1928
1929 unique_mappings: HashMap<u32, u32>,
1930 unique_counter: u32,
1931}
1932
1933struct Snapshot<T> {
1934 prior_types: usize,
1935 unique_counter: u32,
1936 unique_mappings: HashMap<u32, u32>,
1937 items: Vec<T>,
1938}
1939
1940impl<T> SnapshotList<T> {
1941 pub(crate) fn get(&self, index: usize) -> Option<&T> {
1943 if index >= self.snapshots_total {
1945 return self.cur.get(index - self.snapshots_total);
1946 }
1947 let i = match self
1951 .snapshots
1952 .binary_search_by_key(&index, |snapshot| snapshot.prior_types)
1953 {
1954 Ok(i) => i,
1955 Err(i) => i - 1,
1956 };
1957 let snapshot = &self.snapshots[i];
1958 Some(&snapshot.items[index - snapshot.prior_types])
1959 }
1960
1961 pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut T> {
1971 if index >= self.snapshots_total {
1972 return self.cur.get_mut(index - self.snapshots_total);
1973 }
1974 panic!("cannot get a mutable reference in snapshotted part of list")
1975 }
1976
1977 pub(crate) fn push(&mut self, val: T) {
1979 self.cur.push(val);
1980 }
1981
1982 pub(crate) fn len(&self) -> usize {
1984 self.cur.len() + self.snapshots_total
1985 }
1986
1987 pub(crate) fn reserve(&mut self, additional: usize) {
1989 self.cur.reserve(additional);
1990 }
1991
1992 pub(crate) fn commit(&mut self) -> SnapshotList<T> {
1999 let len = self.cur.len();
2007 if len > 0 {
2008 self.unique_counter += 1;
2009 self.cur.shrink_to_fit();
2010 self.snapshots.push(Arc::new(Snapshot {
2011 prior_types: self.snapshots_total,
2012 unique_counter: self.unique_counter - 1,
2013 unique_mappings: mem::take(&mut self.unique_mappings),
2014 items: mem::take(&mut self.cur),
2015 }));
2016 self.snapshots_total += len;
2017 }
2018 SnapshotList {
2019 snapshots: self.snapshots.clone(),
2020 snapshots_total: self.snapshots_total,
2021 unique_mappings: HashMap::new(),
2022 unique_counter: self.unique_counter,
2023 cur: Vec::new(),
2024 }
2025 }
2026
2027 pub fn with_unique(&mut self, mut ty: TypeId) -> TypeId {
2033 self.unique_mappings
2034 .insert(self.unique_counter, ty.unique_id);
2035 ty.unique_id = self.unique_counter;
2036 self.unique_counter += 1;
2037 ty
2038 }
2039
2040 pub fn peel_alias(&self, ty: TypeId) -> Option<TypeId> {
2044 let i = match self
2051 .snapshots
2052 .binary_search_by_key(&ty.unique_id, |snapshot| snapshot.unique_counter)
2053 {
2054 Ok(_) => unreachable!(),
2055 Err(i) => i,
2056 };
2057
2058 let unique_id = match self.snapshots.get(i) {
2062 Some(snapshot) => *snapshot.unique_mappings.get(&ty.unique_id)?,
2063 None => *self.unique_mappings.get(&ty.unique_id)?,
2064 };
2065 Some(TypeId { unique_id, ..ty })
2066 }
2067}
2068
2069impl<T> std::ops::Index<usize> for SnapshotList<T> {
2070 type Output = T;
2071
2072 #[inline]
2073 fn index(&self, index: usize) -> &T {
2074 self.get(index).unwrap()
2075 }
2076}
2077
2078impl<T> std::ops::IndexMut<usize> for SnapshotList<T> {
2079 #[inline]
2080 fn index_mut(&mut self, index: usize) -> &mut T {
2081 self.get_mut(index).unwrap()
2082 }
2083}
2084
2085impl<T> std::ops::Index<TypeId> for SnapshotList<T> {
2086 type Output = T;
2087
2088 #[inline]
2089 fn index(&self, id: TypeId) -> &T {
2090 self.get(id.index).unwrap()
2091 }
2092}
2093
2094impl<T> std::ops::IndexMut<TypeId> for SnapshotList<T> {
2095 #[inline]
2096 fn index_mut(&mut self, id: TypeId) -> &mut T {
2097 self.get_mut(id.index).unwrap()
2098 }
2099}
2100
2101impl<T> Default for SnapshotList<T> {
2102 fn default() -> SnapshotList<T> {
2103 SnapshotList {
2104 snapshots: Vec::new(),
2105 snapshots_total: 0,
2106 cur: Vec::new(),
2107 unique_counter: 1,
2108 unique_mappings: HashMap::new(),
2109 }
2110 }
2111}
2112
2113pub(crate) type TypeList = SnapshotList<Type>;
2115
2116pub(crate) struct TypeAlloc {
2119 list: TypeList,
2120}
2121
2122impl Deref for TypeAlloc {
2123 type Target = TypeList;
2124 fn deref(&self) -> &TypeList {
2125 &self.list
2126 }
2127}
2128
2129impl DerefMut for TypeAlloc {
2130 fn deref_mut(&mut self) -> &mut TypeList {
2131 &mut self.list
2132 }
2133}
2134
2135impl TypeAlloc {
2136 pub fn push_anon(&mut self, ty: Type) -> TypeId {
2139 let index = self.list.len();
2140 let type_size = ty.type_size();
2141 self.list.push(ty);
2142 TypeId {
2143 index,
2144 type_size,
2145 unique_id: 0,
2146 }
2147 }
2148
2149 pub fn push_defined(&mut self, ty: Type) -> TypeId {
2155 let id = self.push_anon(ty);
2156 self.with_unique(id)
2157 }
2158}
2159
2160impl Default for TypeAlloc {
2161 fn default() -> TypeAlloc {
2162 TypeAlloc {
2163 list: Default::default(),
2164 }
2165 }
2166}