1#[cfg(feature = "parser")]
16use crate::component::parser::parse_component;
17use crate::core::{
18 Custom, Data, Export, FuncIdx, FuncType, Import, MemIdx, Module, RetainsCustomSection,
19 RetainsInstructions, TryFromExprSource, TypeRef, ValType,
20};
21#[cfg(feature = "metadata")]
22use crate::metadata;
23use crate::{
24 new_component_section_cache, AstCustomization, IndexSpace, Section, SectionCache, SectionIndex,
25 SectionType, Sections,
26};
27use mappable_rc::Mrc;
28use std::fmt::{Debug, Formatter};
29
30#[cfg(feature = "parser")]
31pub mod parser;
32#[cfg(feature = "writer")]
33pub mod writer;
34
35#[allow(clippy::large_enum_variant)]
39#[derive(Debug, Clone, PartialEq)]
40pub enum ComponentSection<Ast: AstCustomization + 'static> {
41 Module(Module<Ast>),
42 CoreInstance(Instance),
43 CoreType(CoreType),
44 Component(Component<Ast>),
45 Instance(ComponentInstance),
46 Alias(Alias),
47 Type(ComponentType),
48 Canon(Canon),
49 Start(ComponentStart),
50 Import(ComponentImport),
51 Export(ComponentExport),
52 Custom(Ast::Custom),
53}
54
55#[allow(unused)]
56impl<Ast: AstCustomization> ComponentSection<Ast> {
57 pub fn as_module(&self) -> &Module<Ast> {
58 match self {
59 ComponentSection::Module(module) => module,
60 _ => panic!("Expected module section, got {}", self.type_name()),
61 }
62 }
63
64 pub fn as_core_instance(&self) -> &Instance {
65 match self {
66 ComponentSection::CoreInstance(instance) => instance,
67 _ => panic!("Expected core instance section, got {}", self.type_name()),
68 }
69 }
70
71 pub fn as_core_type(&self) -> &CoreType {
72 match self {
73 ComponentSection::CoreType(core_type) => core_type,
74 _ => panic!("Expected core type section, got {}", self.type_name()),
75 }
76 }
77
78 pub fn as_component(&self) -> &Component<Ast> {
79 match self {
80 ComponentSection::Component(component) => component,
81 _ => panic!("Expected component section, got {}", self.type_name()),
82 }
83 }
84
85 pub fn as_instance(&self) -> &ComponentInstance {
86 match self {
87 ComponentSection::Instance(component_instance) => component_instance,
88 _ => panic!(
89 "Expected component instance section, got {}",
90 self.type_name()
91 ),
92 }
93 }
94
95 pub fn as_alias(&self) -> &Alias {
96 match self {
97 ComponentSection::Alias(alias) => alias,
98 _ => panic!("Expected alias section, got {}", self.type_name()),
99 }
100 }
101
102 pub fn as_type(&self) -> &ComponentType {
103 match self {
104 ComponentSection::Type(component_type) => component_type,
105 _ => panic!("Expected type section, got {}", self.type_name()),
106 }
107 }
108
109 pub fn as_canon(&self) -> &Canon {
110 match self {
111 ComponentSection::Canon(canon) => canon,
112 _ => panic!("Expected canon section, got {}", self.type_name()),
113 }
114 }
115
116 pub fn as_start(&self) -> &ComponentStart {
117 match self {
118 ComponentSection::Start(start) => start,
119 _ => panic!("Expected start section, got {}", self.type_name()),
120 }
121 }
122
123 pub fn as_import(&self) -> &ComponentImport {
124 match self {
125 ComponentSection::Import(import) => import,
126 _ => panic!("Expected import section, got {}", self.type_name()),
127 }
128 }
129
130 pub fn as_export(&self) -> &ComponentExport {
131 match self {
132 ComponentSection::Export(export) => export,
133 _ => panic!("Expected export section, got {}", self.type_name()),
134 }
135 }
136
137 pub fn as_custom(&self) -> &Ast::Custom {
138 match self {
139 ComponentSection::Custom(custom) => custom,
140 _ => panic!("Expected custom section, got {}", self.type_name()),
141 }
142 }
143
144 pub fn type_name(&self) -> &'static str {
145 match self {
146 ComponentSection::Module(_) => "module",
147 ComponentSection::CoreInstance(_) => "core instance",
148 ComponentSection::CoreType(_) => "core type",
149 ComponentSection::Component(_) => "component",
150 ComponentSection::Instance(_) => "instance",
151 ComponentSection::Alias(_) => "alias",
152 ComponentSection::Type(_) => "type",
153 ComponentSection::Canon(_) => "canonical function",
154 ComponentSection::Start(_) => "start",
155 ComponentSection::Import(_) => "import",
156 ComponentSection::Export(_) => "export",
157 ComponentSection::Custom(_) => "custom",
158 }
159 }
160}
161
162impl<Ast: AstCustomization> Section<ComponentIndexSpace, ComponentSectionType>
163 for ComponentSection<Ast>
164{
165 fn index_space(&self) -> ComponentIndexSpace {
166 match self {
167 ComponentSection::Module(module) => module.index_space(),
168 ComponentSection::CoreInstance(core_instance) => core_instance.index_space(),
169 ComponentSection::CoreType(core_type) => core_type.index_space(),
170 ComponentSection::Component(component) => component.index_space(),
171 ComponentSection::Instance(component_instance) => component_instance.index_space(),
172 ComponentSection::Alias(alias) => alias.index_space(),
173 ComponentSection::Type(component_type) => component_type.index_space(),
174 ComponentSection::Canon(canon) => canon.index_space(),
175 ComponentSection::Start(start) => start.index_space(),
176 ComponentSection::Import(import) => import.index_space(),
177 ComponentSection::Export(export) => export.index_space(),
178 ComponentSection::Custom(custom) => custom.index_space(),
179 }
180 }
181
182 fn section_type(&self) -> ComponentSectionType {
183 match self {
184 ComponentSection::Module(module) => module.section_type(),
185 ComponentSection::CoreInstance(core_instance) => core_instance.section_type(),
186 ComponentSection::CoreType(core_type) => core_type.section_type(),
187 ComponentSection::Component(component) => component.section_type(),
188 ComponentSection::Instance(component_instance) => component_instance.section_type(),
189 ComponentSection::Alias(alias) => alias.section_type(),
190 ComponentSection::Type(component_type) => component_type.section_type(),
191 ComponentSection::Canon(canon) => canon.section_type(),
192 ComponentSection::Start(start) => start.section_type(),
193 ComponentSection::Import(import) => import.section_type(),
194 ComponentSection::Export(export) => export.section_type(),
195 ComponentSection::Custom(custom) => custom.section_type(),
196 }
197 }
198}
199
200#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
204pub enum ComponentSectionType {
205 Module,
206 CoreInstance,
207 CoreType,
208 Component,
209 Instance,
210 Alias,
211 Type,
212 Canon,
213 Start,
214 Import,
215 Export,
216 Custom,
217}
218
219impl SectionType for ComponentSectionType {
220 fn allow_grouping(&self) -> bool {
221 !matches!(
222 self,
223 ComponentSectionType::Module
224 | ComponentSectionType::Component
225 | ComponentSectionType::Start
226 | ComponentSectionType::Custom
227 )
228 }
229}
230
231#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
235pub enum ComponentIndexSpace {
236 Func,
237 CoreType,
238 Type,
239 Module,
240 Component,
241 CoreInstance,
242 Instance,
243 Value,
244 CoreTable,
245 CoreFunc,
246 CoreGlobal,
247 CoreMem,
248 Start,
249 Custom,
250}
251
252impl IndexSpace for ComponentIndexSpace {
253 type Index = u32;
254}
255
256pub type ComponentFuncIdx = u32;
257pub type ComponentTypeIdx = u32;
258pub type ModuleIdx = u32;
259pub type ComponentIdx = u32;
260
261#[allow(unused)]
262pub type CoreInstanceIdx = u32;
263pub type InstanceIdx = u32;
264pub type ValueIdx = u32;
265
266#[allow(unused)]
267pub type StartIdx = u32;
268
269#[derive(Debug, Clone, PartialEq, Eq)]
270pub enum InstantiationArgRef {
271 Instance(InstanceIdx),
272}
273
274#[derive(Debug, Clone, PartialEq, Eq)]
275pub struct InstantiationArg {
276 pub name: String,
277 pub arg_ref: InstantiationArgRef,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq)]
281pub enum Instance {
282 Instantiate {
283 module_idx: ModuleIdx,
284 args: Vec<InstantiationArg>,
285 },
286 FromExports {
287 exports: Vec<Export>,
288 },
289}
290
291impl Section<ComponentIndexSpace, ComponentSectionType> for Instance {
292 fn index_space(&self) -> ComponentIndexSpace {
293 ComponentIndexSpace::CoreInstance
294 }
295
296 fn section_type(&self) -> ComponentSectionType {
297 ComponentSectionType::CoreInstance
298 }
299}
300
301#[derive(Debug, Clone, PartialEq, Eq)]
302#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
303#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
304#[cfg_attr(feature = "poem_openapi", derive(poem_openapi::Enum))]
305pub enum ComponentExternalKind {
306 Module,
307 Func,
308 Value,
309 Type,
310 Instance,
311 Component,
312}
313
314#[derive(Debug, Clone, PartialEq, Eq)]
315pub enum OuterAliasKind {
316 CoreModule,
317 CoreType,
318 Type,
319 Component,
320}
321
322#[derive(Debug, Clone, PartialEq, Eq)]
323pub enum ExportKind {
324 Func,
325 Table,
326 Mem,
327 Global,
328}
329
330#[derive(Debug, Clone, PartialEq, Eq)]
331pub struct ComponentInstantiationArg {
332 pub name: String,
333 pub kind: ComponentExternalKind,
334 pub idx: u32,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub enum ComponentInstance {
339 Instantiate {
340 component_idx: ComponentIdx,
341 args: Vec<ComponentInstantiationArg>,
342 },
343 FromExports {
344 exports: Vec<ComponentExport>,
345 },
346}
347
348impl Section<ComponentIndexSpace, ComponentSectionType> for ComponentInstance {
349 fn index_space(&self) -> ComponentIndexSpace {
350 ComponentIndexSpace::Instance
351 }
352
353 fn section_type(&self) -> ComponentSectionType {
354 ComponentSectionType::Instance
355 }
356}
357
358#[derive(Debug, Clone, PartialEq, Eq)]
359pub enum ComponentExternName {
360 Name(String),
361}
362
363impl ComponentExternName {
364 pub fn as_string(&self) -> String {
365 let str: &str = self.into();
366 str.to_string()
367 }
368}
369
370impl<'a> From<&'a ComponentExternName> for &'a str {
371 fn from(value: &'a ComponentExternName) -> Self {
372 match value {
373 ComponentExternName::Name(name) => name,
374 }
375 }
376}
377
378impl PartialEq<String> for ComponentExternName {
379 fn eq(&self, other: &String) -> bool {
380 match self {
381 ComponentExternName::Name(name) => name == other,
382 }
383 }
384}
385
386#[derive(Debug, Clone, PartialEq, Eq)]
387pub enum PrimitiveValueType {
388 Bool,
389 S8,
390 U8,
391 S16,
392 U16,
393 S32,
394 U32,
395 S64,
396 U64,
397 F32,
398 F64,
399 Chr,
400 Str,
401 ErrorContext,
402}
403
404#[derive(Debug, Clone, PartialEq, Eq)]
405pub enum ComponentValType {
406 Primitive(PrimitiveValueType),
407 Defined(ComponentTypeIdx),
408}
409
410#[derive(Debug, Clone, PartialEq, Eq)]
411pub enum TypeBounds {
412 Eq(ComponentTypeIdx),
413 SubResource,
414}
415
416#[derive(Debug, Clone, PartialEq, Eq)]
417pub enum ComponentTypeRef {
418 Module(ComponentTypeIdx),
419 Func(ComponentTypeIdx),
420 Val(ComponentValType),
421 Type(TypeBounds),
422 Instance(ComponentTypeIdx),
423 Component(ComponentTypeIdx),
424}
425
426#[derive(Debug, Clone, PartialEq, Eq)]
427pub struct ComponentExport {
428 pub name: ComponentExternName,
429 pub kind: ComponentExternalKind,
430 pub idx: u32,
431 pub desc: Option<ComponentTypeRef>,
432}
433
434impl Section<ComponentIndexSpace, ComponentSectionType> for ComponentExport {
435 fn index_space(&self) -> ComponentIndexSpace {
436 match self.kind {
437 ComponentExternalKind::Module => ComponentIndexSpace::Module,
438 ComponentExternalKind::Func => ComponentIndexSpace::Func,
439 ComponentExternalKind::Value => ComponentIndexSpace::Value,
440 ComponentExternalKind::Type => ComponentIndexSpace::Type,
441 ComponentExternalKind::Instance => ComponentIndexSpace::Instance,
442 ComponentExternalKind::Component => ComponentIndexSpace::Component,
443 }
444 }
445
446 fn section_type(&self) -> ComponentSectionType {
447 ComponentSectionType::Export
448 }
449}
450
451#[derive(Debug, Clone, PartialEq, Eq)]
452pub struct AliasTarget {
453 pub count: u32,
454 pub index: u32,
455}
456
457#[derive(Debug, Clone, PartialEq, Eq)]
458pub enum Alias {
459 InstanceExport {
460 kind: ComponentExternalKind,
461 instance_idx: InstanceIdx,
462 name: String,
463 },
464 CoreInstanceExport {
465 kind: ExportKind,
466 instance_idx: InstanceIdx,
467 name: String,
468 },
469 Outer {
470 kind: OuterAliasKind,
471 target: AliasTarget,
472 },
473}
474
475impl Section<ComponentIndexSpace, ComponentSectionType> for Alias {
476 fn index_space(&self) -> ComponentIndexSpace {
477 match self {
478 Alias::InstanceExport {
479 kind: ComponentExternalKind::Component,
480 ..
481 } => ComponentIndexSpace::Component,
482 Alias::InstanceExport {
483 kind: ComponentExternalKind::Func,
484 ..
485 } => ComponentIndexSpace::Func,
486 Alias::InstanceExport {
487 kind: ComponentExternalKind::Instance,
488 ..
489 } => ComponentIndexSpace::Instance,
490 Alias::InstanceExport {
491 kind: ComponentExternalKind::Module,
492 ..
493 } => ComponentIndexSpace::Module,
494 Alias::InstanceExport {
495 kind: ComponentExternalKind::Type,
496 ..
497 } => ComponentIndexSpace::Type,
498 Alias::InstanceExport {
499 kind: ComponentExternalKind::Value,
500 ..
501 } => ComponentIndexSpace::Value,
502 Alias::CoreInstanceExport {
503 kind: ExportKind::Func,
504 ..
505 } => ComponentIndexSpace::CoreFunc,
506 Alias::CoreInstanceExport {
507 kind: ExportKind::Global,
508 ..
509 } => ComponentIndexSpace::CoreGlobal,
510 Alias::CoreInstanceExport {
511 kind: ExportKind::Mem,
512 ..
513 } => ComponentIndexSpace::CoreMem,
514 Alias::CoreInstanceExport {
515 kind: ExportKind::Table,
516 ..
517 } => ComponentIndexSpace::CoreTable,
518 Alias::Outer {
519 kind: OuterAliasKind::Component,
520 ..
521 } => ComponentIndexSpace::Component,
522 Alias::Outer {
523 kind: OuterAliasKind::CoreType,
524 ..
525 } => ComponentIndexSpace::CoreType,
526 Alias::Outer {
527 kind: OuterAliasKind::Type,
528 ..
529 } => ComponentIndexSpace::Type,
530 Alias::Outer {
531 kind: OuterAliasKind::CoreModule,
532 ..
533 } => ComponentIndexSpace::Module,
534 }
535 }
536
537 fn section_type(&self) -> ComponentSectionType {
538 ComponentSectionType::Alias
539 }
540}
541
542#[derive(Debug, Clone, PartialEq, Eq)]
543pub enum CanonicalOption {
544 Utf8,
545 Utf16,
546 CompactUtf16,
547 Memory(MemIdx),
548 Realloc(FuncIdx),
549 PostReturn(FuncIdx),
550 Async,
551 Callback(FuncIdx),
552}
553
554#[derive(Debug, Clone, PartialEq, Eq)]
555pub enum Canon {
556 Lift {
557 func_idx: FuncIdx,
558 opts: Vec<CanonicalOption>,
559 function_type: ComponentTypeIdx,
560 },
561 Lower {
562 func_idx: ComponentFuncIdx,
563 opts: Vec<CanonicalOption>,
564 },
565 ResourceNew {
566 type_idx: ComponentTypeIdx,
567 },
568 ResourceDrop {
569 type_idx: ComponentTypeIdx,
570 },
571 ResourceRep {
572 type_idx: ComponentTypeIdx,
573 },
574}
575
576impl Section<ComponentIndexSpace, ComponentSectionType> for Canon {
577 fn index_space(&self) -> ComponentIndexSpace {
578 match self {
579 Canon::Lift { .. } => ComponentIndexSpace::Func,
580 Canon::Lower { .. } => ComponentIndexSpace::CoreFunc,
581 Canon::ResourceNew { .. } => ComponentIndexSpace::CoreFunc,
582 Canon::ResourceDrop { .. } => ComponentIndexSpace::CoreFunc,
583 Canon::ResourceRep { .. } => ComponentIndexSpace::CoreFunc,
584 }
585 }
586
587 fn section_type(&self) -> ComponentSectionType {
588 ComponentSectionType::Canon
589 }
590}
591
592#[derive(Debug, Clone, PartialEq, Eq)]
593pub struct ComponentStart {
594 func_idx: ComponentFuncIdx,
595 args: Vec<ValueIdx>,
596 results: u32,
597}
598
599impl Section<ComponentIndexSpace, ComponentSectionType> for ComponentStart {
600 fn index_space(&self) -> ComponentIndexSpace {
601 ComponentIndexSpace::Start
602 }
603
604 fn section_type(&self) -> ComponentSectionType {
605 ComponentSectionType::Start
606 }
607}
608
609#[derive(Debug, Clone, PartialEq, Eq)]
610pub struct ComponentImport {
611 pub name: ComponentExternName,
612 pub desc: ComponentTypeRef,
613}
614
615impl Section<ComponentIndexSpace, ComponentSectionType> for ComponentImport {
616 fn index_space(&self) -> ComponentIndexSpace {
617 match self.desc {
618 ComponentTypeRef::Module(_) => ComponentIndexSpace::Module,
619 ComponentTypeRef::Func(_) => ComponentIndexSpace::Func,
620 ComponentTypeRef::Val(_) => ComponentIndexSpace::Value,
621 ComponentTypeRef::Type(_) => ComponentIndexSpace::Type,
622 ComponentTypeRef::Instance(_) => ComponentIndexSpace::Instance,
623 ComponentTypeRef::Component(_) => ComponentIndexSpace::Component,
624 }
625 }
626
627 fn section_type(&self) -> ComponentSectionType {
628 ComponentSectionType::Import
629 }
630}
631
632#[derive(Debug, Clone, PartialEq, Eq)]
633pub enum ModuleDeclaration {
634 Type {
635 typ: FuncType,
636 },
637 Export {
638 name: String,
639 desc: TypeRef,
640 },
641 OuterAlias {
642 kind: OuterAliasKind,
643 target: AliasTarget,
644 },
645 Import {
646 import: Import,
647 },
648}
649
650#[derive(Debug, Clone, PartialEq, Eq)]
651pub enum CoreType {
652 Function(FuncType),
653 Module(Vec<ModuleDeclaration>),
654}
655
656impl Section<ComponentIndexSpace, ComponentSectionType> for CoreType {
657 fn index_space(&self) -> ComponentIndexSpace {
658 ComponentIndexSpace::CoreType
659 }
660
661 fn section_type(&self) -> ComponentSectionType {
662 ComponentSectionType::CoreType
663 }
664}
665
666#[derive(Debug, Clone, PartialEq, Eq)]
667pub struct VariantCase {
668 pub name: String,
669 pub typ: Option<ComponentValType>,
670 pub refines: Option<u32>,
672}
673
674#[derive(Debug, Clone, PartialEq, Eq)]
675pub enum ComponentDefinedType {
676 Primitive {
677 typ: PrimitiveValueType,
678 },
679 Record {
680 fields: Vec<(String, ComponentValType)>,
681 },
682 Variant {
683 cases: Vec<VariantCase>,
684 },
685 List {
686 elem: ComponentValType,
687 },
688 Tuple {
689 elems: Vec<ComponentValType>,
690 },
691 Flags {
692 names: Vec<String>,
693 },
694 Enum {
695 names: Vec<String>,
696 },
697 Option {
698 typ: ComponentValType,
699 },
700 Result {
701 ok: Option<ComponentValType>,
702 err: Option<ComponentValType>,
703 },
704 Owned {
705 type_idx: ComponentTypeIdx,
706 },
707 Borrowed {
708 type_idx: ComponentTypeIdx,
709 },
710 Future {
711 inner: Option<ComponentValType>,
712 },
713 Stream {
714 inner: Option<ComponentValType>,
715 },
716}
717
718#[derive(Debug, Clone, PartialEq, Eq)]
719pub struct ComponentFuncType {
720 pub params: Vec<(String, ComponentValType)>,
721 pub result: Option<ComponentValType>,
722}
723
724#[derive(Debug, Clone, PartialEq, Eq)]
725pub enum ComponentTypeDeclaration {
726 Core(CoreType),
727 Type(ComponentType),
728 Alias(Alias),
729 Import(ComponentImport),
730 Export {
731 name: ComponentExternName,
732 desc: ComponentTypeRef,
733 },
734}
735
736#[derive(Debug, Clone, PartialEq, Eq)]
737pub struct ComponentTypeDeclarations(Vec<ComponentTypeDeclaration>);
738
739impl ComponentTypeDeclarations {}
740
741#[derive(Debug, Clone, PartialEq, Eq)]
742pub enum InstanceTypeDeclaration {
743 Core(CoreType),
744 Type(ComponentType),
745 Alias(Alias),
746 Export {
747 name: ComponentExternName,
748 desc: ComponentTypeRef,
749 },
750}
751
752#[derive(Debug, Clone, PartialEq, Eq)]
753pub struct InstanceTypeDeclarations(Vec<InstanceTypeDeclaration>);
754
755impl InstanceTypeDeclarations {
756 pub fn find_export(&self, name: &str) -> Option<&ComponentTypeRef> {
757 self.0.iter().find_map(|decl| match decl {
758 InstanceTypeDeclaration::Export {
759 name: ComponentExternName::Name(n),
760 desc,
761 } if n == name => Some(desc),
762 _ => None,
763 })
764 }
765
766 pub fn get_component_type(
767 &self,
768 component_type_idx: ComponentTypeIdx,
769 ) -> Option<&InstanceTypeDeclaration> {
770 let mut idx = 0;
771 let mut result = None;
772 for decl in &self.0 {
773 match decl {
774 InstanceTypeDeclaration::Type(_)
775 | InstanceTypeDeclaration::Alias(Alias::Outer {
776 kind: OuterAliasKind::Type,
777 ..
778 })
779 | InstanceTypeDeclaration::Alias(Alias::InstanceExport {
780 kind: ComponentExternalKind::Type,
781 ..
782 })
783 | InstanceTypeDeclaration::Export {
784 desc: ComponentTypeRef::Type(_),
785 ..
786 } => {
787 if component_type_idx == idx {
788 result = Some(decl);
789 break;
790 } else {
791 idx += 1;
792 }
793 }
794 _ => {}
795 }
796 }
797 result
798 }
799}
800
801#[derive(Debug, Clone, PartialEq, Eq)]
802pub enum ComponentType {
803 Defined(ComponentDefinedType),
804 Func(ComponentFuncType),
805 Component(ComponentTypeDeclarations),
806 Instance(InstanceTypeDeclarations),
807 Resource {
808 representation: ValType,
809 destructor: Option<ComponentFuncIdx>,
810 },
811}
812
813impl Section<ComponentIndexSpace, ComponentSectionType> for ComponentType {
814 fn index_space(&self) -> ComponentIndexSpace {
815 ComponentIndexSpace::Type
816 }
817
818 fn section_type(&self) -> ComponentSectionType {
819 ComponentSectionType::Type
820 }
821}
822
823impl Section<ComponentIndexSpace, ComponentSectionType> for Custom {
824 fn index_space(&self) -> ComponentIndexSpace {
825 ComponentIndexSpace::Custom
826 }
827
828 fn section_type(&self) -> ComponentSectionType {
829 ComponentSectionType::Custom
830 }
831}
832
833type ComponentSectionCache<T, Ast> =
834 SectionCache<T, ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>;
835
836type ComponentSectionIndex<Ast> =
837 SectionIndex<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>;
838
839pub struct Component<Ast: AstCustomization + 'static> {
841 sections: Sections<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>,
842
843 imports: ComponentSectionCache<ComponentImport, Ast>,
844 exports: ComponentSectionCache<ComponentExport, Ast>,
845 core_instances: ComponentSectionCache<Instance, Ast>,
846 instances: ComponentSectionCache<ComponentInstance, Ast>,
847 component_types: ComponentSectionCache<ComponentType, Ast>,
848 core_types: ComponentSectionCache<CoreType, Ast>,
849 canons: ComponentSectionCache<Canon, Ast>,
850 aliases: ComponentSectionCache<Alias, Ast>,
851 components: ComponentSectionCache<Component<Ast>, Ast>,
852 modules: ComponentSectionCache<Module<Ast>, Ast>,
853 customs: ComponentSectionCache<Ast::Custom, Ast>,
854
855 core_instance_index: ComponentSectionIndex<Ast>,
856 instance_index: ComponentSectionIndex<Ast>,
857 component_type_index: ComponentSectionIndex<Ast>,
858 core_func_index: ComponentSectionIndex<Ast>,
859 component_index: ComponentSectionIndex<Ast>,
860 component_func_index: ComponentSectionIndex<Ast>,
861 value_index: ComponentSectionIndex<Ast>,
862 module_index: ComponentSectionIndex<Ast>,
863}
864
865#[cfg(feature = "parser")]
866impl<Ast> Component<Ast>
867where
868 Ast: AstCustomization,
869 Ast::Expr: TryFromExprSource,
870 Ast::Data: From<Data<Ast::Expr>>,
871 Ast::Custom: From<Custom>,
872{
873 pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
875 let parser = wasmparser::Parser::new(0);
876 let (component, _) = parse_component(parser, bytes)?;
877 Ok(component)
878 }
879}
880
881#[cfg(feature = "writer")]
882impl<Ast> Component<Ast>
883where
884 Ast: AstCustomization,
885 Ast::Expr: RetainsInstructions,
886 Ast::Data: Into<Data<Ast::Expr>>,
887 Ast::Custom: Into<Custom>,
888{
889 pub fn into_bytes(self) -> Result<Vec<u8>, String> {
891 let encoder: wasm_encoder::Component = self.try_into()?;
892 Ok(encoder.finish())
893 }
894}
895
896impl<Ast: AstCustomization> Component<Ast> {
897 pub fn empty() -> Self {
899 Self::new(Sections::new())
900 }
901
902 pub(crate) fn new(
903 sections: Sections<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>,
904 ) -> Self {
905 Self {
906 sections,
907
908 imports: new_component_section_cache!(Import),
909 exports: new_component_section_cache!(Export),
910 core_instances: new_component_section_cache!(CoreInstance),
911 instances: new_component_section_cache!(Instance),
912 component_types: new_component_section_cache!(Type),
913 core_types: new_component_section_cache!(CoreType),
914 canons: new_component_section_cache!(Canon),
915 aliases: new_component_section_cache!(Alias),
916 components: new_component_section_cache!(Component),
917 modules: new_component_section_cache!(Module),
918 customs: new_component_section_cache!(Custom),
919 core_instance_index: SectionIndex::new(ComponentIndexSpace::CoreInstance),
920 instance_index: SectionIndex::new(ComponentIndexSpace::Instance),
921 component_type_index: SectionIndex::new(ComponentIndexSpace::Type),
922 core_func_index: SectionIndex::new(ComponentIndexSpace::CoreFunc),
923 component_index: SectionIndex::new(ComponentIndexSpace::Component),
924 component_func_index: SectionIndex::new(ComponentIndexSpace::Func),
925 value_index: SectionIndex::new(ComponentIndexSpace::Value),
926 module_index: SectionIndex::new(ComponentIndexSpace::Module),
927 }
928 }
929
930 pub fn imports(&self) -> Vec<Mrc<ComponentImport>> {
932 self.imports.populate(&self.sections);
933 self.imports.all()
934 }
935
936 pub fn exports(&self) -> Vec<Mrc<ComponentExport>> {
938 self.exports.populate(&self.sections);
939 self.exports.all()
940 }
941
942 pub fn core_instances(&self) -> Vec<Mrc<Instance>> {
944 self.core_instances.populate(&self.sections);
945 self.core_instances.all()
946 }
947
948 pub fn instances(&self) -> Vec<Mrc<ComponentInstance>> {
950 self.instances.populate(&self.sections);
951 self.instances.all()
952 }
953
954 pub fn component_types(&self) -> Vec<Mrc<ComponentType>> {
956 self.component_types.populate(&self.sections);
957 self.component_types.all()
958 }
959
960 pub fn core_types(&self) -> Vec<Mrc<CoreType>> {
962 self.core_types.populate(&self.sections);
963 self.core_types.all()
964 }
965
966 pub fn canons(&self) -> Vec<Mrc<Canon>> {
968 self.canons.populate(&self.sections);
969 self.canons.all()
970 }
971
972 pub fn aliases(&self) -> Vec<Mrc<Alias>> {
974 self.aliases.populate(&self.sections);
975 self.aliases.all()
976 }
977
978 pub fn components(&self) -> Vec<Mrc<Component<Ast>>> {
980 self.components.populate(&self.sections);
981 self.components.all()
982 }
983
984 pub fn modules(&self) -> Vec<Mrc<Module<Ast>>> {
986 self.modules.populate(&self.sections);
987 self.modules.all()
988 }
989
990 pub fn customs(&self) -> Vec<Mrc<Ast::Custom>> {
992 self.customs.populate(&self.sections);
993 self.customs.all()
994 }
995
996 pub fn get_core_instance(&self, core_instance_idx: CoreInstanceIdx) -> Option<Mrc<Instance>> {
998 self.core_instance_index.populate(&self.sections);
999 match self.core_instance_index.get(&core_instance_idx) {
1000 Some(section) => match &*section {
1001 ComponentSection::CoreInstance(_) => {
1002 Some(Mrc::map(section, |section| section.as_core_instance()))
1003 }
1004 _ => None,
1005 },
1006 _ => None,
1007 }
1008 }
1009
1010 pub fn get_instance_wrapped(
1012 &self,
1013 instance_idx: InstanceIdx,
1014 ) -> Option<Mrc<ComponentSection<Ast>>> {
1015 self.instance_index.populate(&self.sections);
1016 self.instance_index.get(&instance_idx)
1017 }
1018
1019 pub fn get_instance(&self, instance_idx: InstanceIdx) -> Option<Mrc<ComponentInstance>> {
1021 match self.get_instance_wrapped(instance_idx) {
1022 Some(section) => match &*section {
1023 ComponentSection::Instance(_) => {
1024 Some(Mrc::map(section, |section| section.as_instance()))
1025 }
1026 _ => None,
1027 },
1028 _ => None,
1029 }
1030 }
1031
1032 pub fn get_component_type(
1040 &self,
1041 component_type_idx: ComponentTypeIdx,
1042 ) -> Option<Mrc<ComponentSection<Ast>>> {
1043 self.component_type_index.populate(&self.sections);
1044 self.component_type_index.get(&component_type_idx)
1045 }
1046
1047 pub fn get_core_func(&self, core_func_idx: FuncIdx) -> Option<Mrc<ComponentSection<Ast>>> {
1053 self.core_func_index.populate(&self.sections);
1054 self.core_func_index.get(&core_func_idx)
1055 }
1056
1057 pub fn get_component(&self, component_idx: ComponentIdx) -> Option<Mrc<ComponentSection<Ast>>> {
1065 self.component_index.populate(&self.sections);
1066 self.component_index.get(&component_idx)
1067 }
1068
1069 pub fn get_component_func(
1077 &self,
1078 component_func_idx: ComponentFuncIdx,
1079 ) -> Option<Mrc<ComponentSection<Ast>>> {
1080 self.component_func_index.populate(&self.sections);
1081 self.component_func_index.get(&component_func_idx)
1082 }
1083
1084 pub fn get_value(&self, value_idx: ValueIdx) -> Option<Mrc<ComponentSection<Ast>>> {
1091 self.value_index.populate(&self.sections);
1092 self.value_index.get(&value_idx)
1093 }
1094
1095 pub fn get_module(&self, module_idx: ModuleIdx) -> Option<Mrc<ComponentSection<Ast>>> {
1103 self.module_index.populate(&self.sections);
1104 self.module_index.get(&module_idx)
1105 }
1106
1107 pub fn into_sections(mut self) -> Vec<Mrc<ComponentSection<Ast>>> {
1109 self.sections.take_all()
1110 }
1111
1112 pub fn into_grouped(self) -> Vec<(ComponentSectionType, Vec<Mrc<ComponentSection<Ast>>>)> {
1114 self.sections.into_grouped()
1115 }
1116}
1117
1118impl<Ast> Component<Ast>
1119where
1120 Ast: AstCustomization,
1121 Ast::Custom: RetainsCustomSection,
1122{
1123 #[cfg(feature = "metadata")]
1124 pub fn get_metadata(&self) -> Option<metadata::Metadata> {
1125 let mut producers = None;
1126 let mut name = None;
1127
1128 for custom in self.customs() {
1129 if custom.name() == "producers" {
1130 producers = wasm_metadata::Producers::from_bytes(custom.data(), 0).ok();
1131 } else if custom.name() == "name" {
1132 name = wasm_metadata::ModuleNames::from_bytes(custom.data(), 0)
1133 .ok()
1134 .and_then(|n| n.get_name().cloned());
1135 } else if custom.name() == "component-name" {
1136 name = wasm_metadata::ModuleNames::from_bytes(custom.data(), 0)
1137 .ok()
1138 .and_then(|n| n.get_name().cloned());
1139 }
1140 }
1141
1142 if producers.is_some() || name.is_some() {
1143 Some(metadata::Metadata {
1144 name,
1145 producers: producers.map(|p| p.into()),
1146 })
1147 } else {
1148 None
1149 }
1150 }
1151
1152 #[cfg(feature = "metadata")]
1154 pub fn get_all_producers(&self) -> Vec<metadata::Producers> {
1155 let mut result = Vec::new();
1156 if let Some(producers) = self.get_metadata().and_then(|m| m.producers) {
1157 result.push(producers);
1158 }
1159 for module in self.modules() {
1160 if let Some(producers) = module.get_metadata().and_then(|m| m.producers) {
1161 result.push(producers);
1162 }
1163 }
1164 for component in self.components() {
1165 result.append(&mut component.get_all_producers());
1166 }
1167 result
1168 }
1169}
1170
1171impl<Ast: AstCustomization>
1172 From<Sections<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>>
1173 for Component<Ast>
1174{
1175 fn from(
1176 value: Sections<ComponentIndexSpace, ComponentSectionType, ComponentSection<Ast>>,
1177 ) -> Self {
1178 Component::new(value)
1179 }
1180}
1181
1182impl<Ast: AstCustomization> PartialEq for Component<Ast> {
1183 fn eq(&self, other: &Self) -> bool {
1184 self.sections.eq(&other.sections)
1185 }
1186}
1187
1188impl<Ast: AstCustomization> Debug for Component<Ast> {
1189 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1190 self.sections.fmt(f)
1191 }
1192}
1193
1194impl<Ast: AstCustomization> Clone for Component<Ast> {
1195 fn clone(&self) -> Self {
1196 Component::new(self.sections.clone())
1197 }
1198}
1199
1200impl<Ast: AstCustomization> Section<ComponentIndexSpace, ComponentSectionType> for Component<Ast> {
1201 fn index_space(&self) -> ComponentIndexSpace {
1202 ComponentIndexSpace::Component
1203 }
1204
1205 fn section_type(&self) -> ComponentSectionType {
1206 ComponentSectionType::Component
1207 }
1208}