1use crate::graph::{
2 CompositionGraph, EncodeOptions, ExportIndex, ImportIndex, InstanceId, type_desc,
3};
4use anyhow::{Result, anyhow, bail};
5use indexmap::{IndexMap, IndexSet};
6use petgraph::EdgeDirection;
7use smallvec::SmallVec;
8use std::collections::{HashMap, hash_map::Entry};
9use std::mem;
10use wasm_encoder::*;
11use wasmparser::{
12 ComponentExternalKind,
13 component_types::{
14 self as ct, AnyTypeId, ComponentAnyTypeId, ComponentCoreModuleTypeId, ComponentCoreTypeId,
15 ComponentDefinedType, ComponentDefinedTypeId, ComponentEntityType, ComponentFuncTypeId,
16 ComponentInstanceTypeId, ComponentTypeId, RecordType, Remap, Remapping, ResourceId,
17 SubtypeCx, TupleType, VariantType,
18 },
19 names::KebabString,
20 types,
21};
22
23fn type_ref_to_export_kind(ty: wasmparser::ComponentTypeRef) -> ComponentExportKind {
24 match ty {
25 wasmparser::ComponentTypeRef::Module(_) => ComponentExportKind::Module,
26 wasmparser::ComponentTypeRef::Func(_) => ComponentExportKind::Func,
27 wasmparser::ComponentTypeRef::Value(_) => ComponentExportKind::Value,
28 wasmparser::ComponentTypeRef::Type { .. } => ComponentExportKind::Type,
29 wasmparser::ComponentTypeRef::Instance(_) => ComponentExportKind::Instance,
30 wasmparser::ComponentTypeRef::Component(_) => ComponentExportKind::Component,
31 }
32}
33
34enum Encodable {
35 Component(ComponentType),
36 Instance(InstanceType),
37 Builder(ComponentBuilder),
38}
39
40impl Encodable {
41 fn type_count(&self) -> u32 {
42 match self {
43 Encodable::Component(t) => t.type_count(),
44 Encodable::Instance(t) => t.type_count(),
45 Encodable::Builder(t) => t.type_count(),
46 }
47 }
48
49 fn instance_count(&self) -> u32 {
50 match self {
51 Encodable::Component(t) => t.instance_count(),
52 Encodable::Instance(t) => t.instance_count(),
53 Encodable::Builder(t) => t.instance_count(),
54 }
55 }
56
57 fn core_type_count(&self) -> u32 {
58 match self {
59 Encodable::Component(t) => t.core_type_count(),
60 Encodable::Instance(t) => t.core_type_count(),
61 Encodable::Builder(t) => t.core_type_count(),
62 }
63 }
64
65 fn ty(&mut self) -> ComponentTypeEncoder<'_> {
66 match self {
67 Encodable::Component(t) => t.ty(),
68 Encodable::Instance(t) => t.ty(),
69 Encodable::Builder(t) => t.ty(None).1,
70 }
71 }
72
73 fn core_type(&mut self) -> ComponentCoreTypeEncoder<'_> {
74 match self {
75 Encodable::Component(t) => t.core_type(),
76 Encodable::Instance(t) => t.core_type(),
77 Encodable::Builder(t) => t.core_type(None).1,
78 }
79 }
80
81 fn alias(&mut self, alias: Alias<'_>) {
82 match self {
83 Encodable::Component(t) => {
84 t.alias(alias);
85 }
86 Encodable::Instance(t) => {
87 t.alias(alias);
88 }
89 Encodable::Builder(t) => {
90 t.alias(None, alias);
91 }
92 }
93 }
94}
95
96pub(crate) struct TypeState<'a> {
105 scopes: Vec<TypeScope<'a>>,
108
109 cur: TypeScope<'a>,
111
112 remapping: HashMap<ResourceId, (&'a crate::graph::Component<'a>, ResourceId)>,
113}
114
115type TypeKey<'a> = (PtrKey<'a, crate::graph::Component<'a>>, AnyTypeId);
121
122struct TypeScope<'a> {
128 type_defs: HashMap<TypeKey<'a>, u32>,
132
133 type_exports: HashMap<TypeKey<'a>, &'a str>,
138
139 type_exports_rev: HashMap<&'a str, Vec<TypeKey<'a>>>,
150
151 instance_exports: HashMap<TypeKey<'a>, (u32, &'a str)>,
157
158 encodable: Encodable,
160}
161
162impl<'a> TypeState<'a> {
163 fn new() -> TypeState<'a> {
164 Self::new_with_remapping(HashMap::new())
165 }
166
167 fn new_with_remapping(
168 remapping: HashMap<ResourceId, (&'a crate::graph::Component<'a>, ResourceId)>,
169 ) -> TypeState<'a> {
170 TypeState {
171 scopes: Vec::new(),
172 cur: TypeScope {
173 type_exports: HashMap::new(),
174 type_exports_rev: HashMap::new(),
175 instance_exports: HashMap::new(),
176 type_defs: HashMap::new(),
177 encodable: Encodable::Builder(Default::default()),
178 },
179 remapping,
180 }
181 }
182
183 fn push(&mut self, encodable: Encodable) {
185 let prev = mem::replace(
186 &mut self.cur,
187 TypeScope {
188 type_exports: HashMap::new(),
189 type_exports_rev: HashMap::new(),
190 instance_exports: HashMap::new(),
191 type_defs: HashMap::new(),
192 encodable,
193 },
194 );
195 self.scopes.push(prev);
196 }
197
198 fn pop(&mut self) -> Encodable {
200 let prev = mem::replace(&mut self.cur, self.scopes.pop().unwrap());
201
202 if let Encodable::Instance(_) = &prev.encodable {
209 let idx = self.cur.encodable.instance_count();
210 for (id, name) in prev.type_exports {
211 let prev = self.cur.instance_exports.insert(id, (idx, name));
212 assert!(prev.is_none());
213 }
214 }
215
216 prev.encodable
217 }
218}
219
220impl Default for TypeState<'_> {
221 fn default() -> Self {
222 Self::new()
223 }
224}
225
226impl<'a> TypeScope<'a> {
227 fn add_type_export(&mut self, ty: TypeKey<'a>, name: &'a str) {
230 let prev = self.type_exports.insert(ty, name);
231 assert!(prev.is_none());
232 self.type_exports_rev.entry(name).or_default().push(ty);
233 }
234}
235
236pub struct PtrKey<'a, T>(&'a T);
237
238impl<T> PartialEq for PtrKey<'_, T> {
239 fn eq(&self, other: &Self) -> bool {
240 std::ptr::eq(self.0, other.0)
241 }
242}
243
244impl<T> Eq for PtrKey<'_, T> {}
245
246impl<T> Copy for PtrKey<'_, T> {}
247
248impl<T> Clone for PtrKey<'_, T> {
249 fn clone(&self) -> Self {
250 *self
251 }
252}
253
254impl<T> std::hash::Hash for PtrKey<'_, T> {
255 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
256 std::ptr::hash(self.0, state);
257 }
258}
259
260pub(crate) struct TypeEncoder<'a>(&'a crate::graph::Component<'a>);
261
262impl<'a> TypeEncoder<'a> {
263 pub fn new(component: &'a crate::graph::Component) -> Self {
264 Self(component)
265 }
266
267 pub fn component<I, E>(
268 &self,
269 state: &mut TypeState<'a>,
270 imports: I,
271 exports: E,
272 ) -> ComponentType
273 where
274 I: IntoIterator<Item = (&'a str, ComponentEntityType)>,
275 E: IntoIterator<Item = (&'a str, ComponentEntityType)>,
276 {
277 state.push(Encodable::Component(ComponentType::new()));
278
279 for (name, ty) in imports {
280 let ty = self.component_entity_type(state, ty);
281 let c = match &mut state.cur.encodable {
282 Encodable::Component(c) => c,
283 _ => unreachable!(),
284 };
285 c.import(name, ty);
286 }
287
288 for (name, ty) in exports {
289 let export = self.export(name, ty, state);
290 let c = match &mut state.cur.encodable {
291 Encodable::Component(c) => c,
292 _ => unreachable!(),
293 };
294 c.export(name, export);
295 }
296
297 match state.pop() {
298 Encodable::Component(c) => c,
299 _ => unreachable!(),
300 }
301 }
302
303 pub fn instance<E>(&self, state: &mut TypeState<'a>, exports: E) -> InstanceType
304 where
305 E: IntoIterator<Item = (&'a str, ComponentEntityType)>,
306 {
307 state.push(Encodable::Instance(InstanceType::new()));
308
309 for (name, ty) in exports {
310 let export = self.export(name, ty, state);
311 let c = match &mut state.cur.encodable {
312 Encodable::Instance(c) => c,
313 _ => unreachable!(),
314 };
315 c.export(name, export);
316 }
317
318 match state.pop() {
319 Encodable::Instance(c) => c,
320 _ => unreachable!(),
321 }
322 }
323
324 pub fn module<I, E>(&self, imports: I, exports: E) -> ModuleType
325 where
326 I: IntoIterator<Item = (&'a str, &'a str, wasmparser::types::EntityType)>,
327 E: IntoIterator<Item = (&'a str, wasmparser::types::EntityType)>,
328 {
329 let mut encoded = ModuleType::new();
330 let mut types = HashMap::default();
331
332 for (module, name, ty) in imports {
333 let ty = self.entity_type(&mut encoded, &mut types, ty);
334 encoded.import(module, name, ty);
335 }
336
337 for (name, ty) in exports {
338 let ty = self.entity_type(&mut encoded, &mut types, ty);
339 encoded.export(name, ty);
340 }
341
342 encoded
343 }
344
345 fn entity_type(
346 &self,
347 encodable: &mut ModuleType,
348 types: &mut HashMap<AnyTypeId, u32>,
349 ty: wasmparser::types::EntityType,
350 ) -> EntityType {
351 match ty {
352 wasmparser::types::EntityType::Func(id) => {
353 let ty = &self.0.types[id].unwrap_func();
354 let idx = match types.entry(ComponentCoreTypeId::Sub(id).into()) {
355 Entry::Occupied(e) => *e.get(),
356 Entry::Vacant(e) => {
357 let index = encodable.type_count();
358 encodable.ty().function(
359 ty.params().iter().copied().map(Self::val_type),
360 ty.results().iter().copied().map(Self::val_type),
361 );
362 *e.insert(index)
363 }
364 };
365 EntityType::Function(idx)
366 }
367 wasmparser::types::EntityType::Table(ty) => EntityType::Table(ty.try_into().unwrap()),
368 wasmparser::types::EntityType::Memory(ty) => EntityType::Memory(ty.into()),
369 wasmparser::types::EntityType::Global(ty) => EntityType::Global(ty.try_into().unwrap()),
370 wasmparser::types::EntityType::Tag(id) => {
371 let ty = &self.0.types[id];
372 let idx = match types.entry(ComponentCoreTypeId::Sub(id).into()) {
373 Entry::Occupied(e) => *e.get(),
374 Entry::Vacant(e) => {
375 let ty = ty.unwrap_func();
376 let index = encodable.type_count();
377 encodable.ty().function(
378 ty.params().iter().copied().map(Self::val_type),
379 ty.results().iter().copied().map(Self::val_type),
380 );
381 *e.insert(index)
382 }
383 };
384 EntityType::Tag(TagType {
385 kind: TagKind::Exception,
386 func_type_idx: idx,
387 })
388 }
389 }
390 }
391
392 fn component_entity_type(
393 &self,
394 state: &mut TypeState<'a>,
395 ty: ComponentEntityType,
396 ) -> ComponentTypeRef {
397 match ty {
398 ComponentEntityType::Module(id) => ComponentTypeRef::Module(self.ty(state, id.into())),
399 ComponentEntityType::Func(id) => ComponentTypeRef::Func(self.ty(state, id.into())),
400 ComponentEntityType::Value(ty) => {
401 ComponentTypeRef::Value(self.component_val_type(state, ty))
402 }
403 ComponentEntityType::Type {
404 created: created @ ComponentAnyTypeId::Resource(_),
405 referenced,
406 } => {
407 if created == referenced {
408 log::trace!("creation of a new resource");
409 ComponentTypeRef::Type(TypeBounds::SubResource)
410 } else {
411 log::trace!("alias of an existing resource");
412 ComponentTypeRef::Type(TypeBounds::Eq(self.ty(state, referenced.into())))
413 }
414 }
415 ComponentEntityType::Type { referenced, .. } => {
416 ComponentTypeRef::Type(TypeBounds::Eq(self.ty(state, referenced.into())))
417 }
418 ComponentEntityType::Instance(id) => {
419 ComponentTypeRef::Instance(self.ty(state, id.into()))
420 }
421 ComponentEntityType::Component(id) => {
422 ComponentTypeRef::Component(self.ty(state, id.into()))
423 }
424 }
425 }
426
427 fn val_type(ty: wasmparser::ValType) -> ValType {
428 ty.try_into().unwrap()
429 }
430
431 fn module_type(&self, state: &mut TypeState<'a>, id: ComponentCoreModuleTypeId) -> u32 {
432 let ty = &self.0.types[id];
433
434 let module = self.module(
435 ty.imports
436 .iter()
437 .map(|((m, n), t)| (m.as_str(), n.as_str(), *t)),
438 ty.exports.iter().map(|(n, t)| (n.as_str(), *t)),
439 );
440
441 let index = state.cur.encodable.core_type_count();
442 state.cur.encodable.core_type().module(&module);
443 index
444 }
445
446 fn component_instance_type(
447 &self,
448 state: &mut TypeState<'a>,
449 id: ComponentInstanceTypeId,
450 ) -> u32 {
451 let ty = &self.0.types[id];
452 let instance = self.instance(state, ty.exports.iter().map(|(n, t)| (n.as_str(), *t)));
453 let index = state.cur.encodable.type_count();
454 state.cur.encodable.ty().instance(&instance);
455 index
456 }
457
458 fn component_type(&self, state: &mut TypeState<'a>, id: ComponentTypeId) -> u32 {
459 let ty = &self.0.types[id];
460
461 let component = self.component(
462 state,
463 ty.imports.iter().map(|(n, t)| (n.as_str(), *t)),
464 ty.exports.iter().map(|(n, t)| (n.as_str(), *t)),
465 );
466
467 let index = state.cur.encodable.type_count();
468 state.cur.encodable.ty().component(&component);
469 index
470 }
471
472 fn component_func_type(&self, state: &mut TypeState<'a>, id: ComponentFuncTypeId) -> u32 {
473 let ty = &self.0.types[id];
474 let params = ty
475 .params
476 .iter()
477 .map(|(name, ty)| (name.as_str(), self.component_val_type(state, *ty)))
478 .collect::<Vec<_>>();
479
480 let result = ty.result.map(|ty| self.component_val_type(state, ty));
481
482 let index = state.cur.encodable.type_count();
483 let mut f = state.cur.encodable.ty().function();
484
485 f.params(params).result(result);
486
487 index
488 }
489
490 fn ty(&self, state: &mut TypeState<'a>, id: AnyTypeId) -> u32 {
500 let key = (PtrKey(self.0), id);
503 if let Some(ret) = state.cur.type_defs.get(&key) {
504 return *ret;
505 }
506
507 if let AnyTypeId::Component(ComponentAnyTypeId::Resource(resource)) = id {
510 if let Some((component, id)) = state.remapping.get(&resource.resource()) {
511 let key = (
512 PtrKey(*component),
513 AnyTypeId::Component(ComponentAnyTypeId::Resource(
514 resource.with_resource_id(*id),
515 )),
516 );
517 if let Some(ret) = state.cur.type_defs.get(&key) {
518 return *ret;
519 }
520 }
521 }
522
523 let idx = self._ty(state, id);
524 let prev = state.cur.type_defs.insert(key, idx);
525 assert!(prev.is_none());
526 idx
527 }
528
529 fn _ty(&self, state: &mut TypeState<'a>, mut id: AnyTypeId) -> u32 {
532 loop {
535 let key = (PtrKey(self.0), id);
536
537 if let Some(name) = state.cur.type_exports.get(&key) {
549 for key in state.cur.type_exports_rev[name].iter() {
550 if let Some(ret) = state.cur.type_defs.get(key) {
551 log::trace!("id already defined through a different component");
552 return *ret;
553 }
554 }
555 }
556
557 for (i, scope) in state.scopes.iter_mut().rev().enumerate() {
561 let (instance, name) = match scope.instance_exports.get(&key) {
562 Some(pair) => *pair,
563 None => continue,
564 };
565 let scope_idx = scope.encodable.type_count();
566 scope.encodable.alias(Alias::InstanceExport {
567 instance,
568 name,
569 kind: ComponentExportKind::Type,
570 });
571 match &scope.encodable {
572 Encodable::Instance(_) => log::trace!("instance"),
573 Encodable::Component(_) => log::trace!("component"),
574 Encodable::Builder(_) => log::trace!("builder"),
575 }
576 let ret = state.cur.encodable.type_count();
577 state.cur.encodable.alias(Alias::Outer {
578 count: i as u32 + 1,
579 index: scope_idx,
580 kind: ComponentOuterAliasKind::Type,
581 });
582 log::trace!("id defined in a different instance");
583 return ret;
584 }
585
586 if let Some((instance, name)) = state.cur.instance_exports.get(&key) {
587 let ret = state.cur.encodable.type_count();
588 state.cur.encodable.alias(Alias::InstanceExport {
589 instance: *instance,
590 name,
591 kind: ComponentExportKind::Type,
592 });
593 log::trace!("id defined in current instance");
594 return ret;
595 }
596
597 match id.peel_alias(&self.0.types) {
598 Some(next) => id = next,
599 None => break,
602 }
603 }
604
605 return match id {
607 AnyTypeId::Core(ComponentCoreTypeId::Sub(_)) => unreachable!(),
608 AnyTypeId::Core(ComponentCoreTypeId::Module(id)) => self.module_type(state, id),
609 AnyTypeId::Component(id) => match id {
610 ComponentAnyTypeId::Resource(r) => {
611 unreachable!(
612 "should have been handled in `TypeEncoder::component_entity_type`: {r:?}"
613 )
614 }
615 ComponentAnyTypeId::Defined(id) => self.defined_type(state, id),
616 ComponentAnyTypeId::Func(id) => self.component_func_type(state, id),
617 ComponentAnyTypeId::Instance(id) => self.component_instance_type(state, id),
618 ComponentAnyTypeId::Component(id) => self.component_type(state, id),
619 },
620 };
621 }
622
623 fn component_val_type(
624 &self,
625 state: &mut TypeState<'a>,
626 ty: ct::ComponentValType,
627 ) -> ComponentValType {
628 match ty {
629 ct::ComponentValType::Primitive(ty) => ComponentValType::Primitive(ty.into()),
630 ct::ComponentValType::Type(id) => {
631 ComponentValType::Type(self.ty(state, ComponentAnyTypeId::from(id).into()))
632 }
633 }
634 }
635
636 fn defined_type(&self, state: &mut TypeState<'a>, id: ComponentDefinedTypeId) -> u32 {
637 let ty = &self.0.types[id];
638
639 match ty {
640 ComponentDefinedType::Primitive(ty) => {
641 let index = state.cur.encodable.type_count();
642 state
643 .cur
644 .encodable
645 .ty()
646 .defined_type()
647 .primitive((*ty).into());
648 index
649 }
650 ComponentDefinedType::Record(r) => self.record(state, r),
651 ComponentDefinedType::Variant(v) => self.variant(state, v),
652 ComponentDefinedType::List(ty) => self.list(state, *ty),
653 ComponentDefinedType::FixedSizeList(ty, elements) => {
654 self.fixed_size_list(state, *ty, *elements)
655 }
656 ComponentDefinedType::Tuple(t) => self.tuple(state, t),
657 ComponentDefinedType::Flags(names) => Self::flags(&mut state.cur.encodable, names),
658 ComponentDefinedType::Enum(cases) => Self::enum_type(&mut state.cur.encodable, cases),
659 ComponentDefinedType::Option(ty) => self.option(state, *ty),
660 ComponentDefinedType::Result { ok, err } => self.result(state, *ok, *err),
661 ComponentDefinedType::Own(r) => {
662 let ty = self.ty(state, (*r).into());
663 let index = state.cur.encodable.type_count();
664 state.cur.encodable.ty().defined_type().own(ty);
665 index
666 }
667 ComponentDefinedType::Borrow(r) => {
668 let ty = self.ty(state, (*r).into());
669 let index = state.cur.encodable.type_count();
670 state.cur.encodable.ty().defined_type().borrow(ty);
671 index
672 }
673 ComponentDefinedType::Future(ty) => self.future(state, *ty),
674 ComponentDefinedType::Stream(ty) => self.stream(state, *ty),
675 }
676 }
677
678 fn record(&self, state: &mut TypeState<'a>, record: &RecordType) -> u32 {
679 let fields = record
680 .fields
681 .iter()
682 .map(|(n, ty)| (n.as_str(), self.component_val_type(state, *ty)))
683 .collect::<Vec<_>>();
684
685 let index = state.cur.encodable.type_count();
686 state.cur.encodable.ty().defined_type().record(fields);
687 index
688 }
689
690 fn variant(&self, state: &mut TypeState<'a>, variant: &VariantType) -> u32 {
691 let cases = variant
692 .cases
693 .iter()
694 .map(|(n, c)| {
695 (
696 n.as_str(),
697 c.ty.map(|ty| self.component_val_type(state, ty)),
698 c.refines
699 .as_deref()
700 .map(|r| variant.cases.iter().position(|(n, _)| n == r).unwrap() as u32),
701 )
702 })
703 .collect::<Vec<_>>();
704 let index = state.cur.encodable.type_count();
705 state.cur.encodable.ty().defined_type().variant(cases);
706 index
707 }
708
709 fn list(&self, state: &mut TypeState<'a>, ty: ct::ComponentValType) -> u32 {
710 let ty = self.component_val_type(state, ty);
711 let index = state.cur.encodable.type_count();
712 state.cur.encodable.ty().defined_type().list(ty);
713 index
714 }
715
716 fn fixed_size_list(
717 &self,
718 state: &mut TypeState<'a>,
719 ty: ct::ComponentValType,
720 elements: u32,
721 ) -> u32 {
722 let ty = self.component_val_type(state, ty);
723 let index = state.cur.encodable.type_count();
724 state
725 .cur
726 .encodable
727 .ty()
728 .defined_type()
729 .fixed_size_list(ty, elements);
730 index
731 }
732
733 fn tuple(&self, state: &mut TypeState<'a>, tuple: &TupleType) -> u32 {
734 let types = tuple
735 .types
736 .iter()
737 .map(|ty| self.component_val_type(state, *ty))
738 .collect::<Vec<_>>();
739 let index = state.cur.encodable.type_count();
740 state.cur.encodable.ty().defined_type().tuple(types);
741 index
742 }
743
744 fn flags(
745 encodable: &mut Encodable,
746 names: &wasmparser::collections::IndexSet<KebabString>,
747 ) -> u32 {
748 let index = encodable.type_count();
749 encodable
750 .ty()
751 .defined_type()
752 .flags(names.iter().map(|n| n.as_str()));
753 index
754 }
755
756 fn enum_type(
757 encodable: &mut Encodable,
758 cases: &wasmparser::collections::IndexSet<KebabString>,
759 ) -> u32 {
760 let index = encodable.type_count();
761 encodable
762 .ty()
763 .defined_type()
764 .enum_type(cases.iter().map(|c| c.as_str()));
765 index
766 }
767
768 fn option(&self, state: &mut TypeState<'a>, ty: ct::ComponentValType) -> u32 {
769 let ty = self.component_val_type(state, ty);
770
771 let index = state.cur.encodable.type_count();
772 state.cur.encodable.ty().defined_type().option(ty);
773 index
774 }
775
776 fn result(
777 &self,
778 state: &mut TypeState<'a>,
779 ok: Option<ct::ComponentValType>,
780 err: Option<ct::ComponentValType>,
781 ) -> u32 {
782 let ok = ok.map(|ty| self.component_val_type(state, ty));
783 let err = err.map(|ty| self.component_val_type(state, ty));
784
785 let index = state.cur.encodable.type_count();
786 state.cur.encodable.ty().defined_type().result(ok, err);
787 index
788 }
789
790 fn export(
791 &self,
792 name: &'a str,
793 export: ComponentEntityType,
794 state: &mut TypeState<'a>,
795 ) -> ComponentTypeRef {
796 let id = match export {
799 ComponentEntityType::Type { created: id, .. } => Some(id),
800 _ => None,
801 };
802 let export = self.component_entity_type(state, export);
803 if let Some(id) = id {
804 let key = (PtrKey(self.0), id.into());
806 let value = state.cur.encodable.type_count();
807 let prev = state.cur.type_defs.insert(key, value);
808 assert!(prev.is_none());
809 state.cur.add_type_export(key, name);
810 }
811 export
812 }
813
814 fn future(&self, state: &mut TypeState<'a>, ty: Option<ct::ComponentValType>) -> u32 {
815 let ty = ty.map(|ty| self.component_val_type(state, ty));
816
817 let index = state.cur.encodable.type_count();
818 state.cur.encodable.ty().defined_type().future(ty);
819 index
820 }
821
822 fn stream(&self, state: &mut TypeState<'a>, ty: Option<ct::ComponentValType>) -> u32 {
823 let ty = ty.map(|ty| self.component_val_type(state, ty));
824
825 let index = state.cur.encodable.type_count();
826 state.cur.encodable.ty().defined_type().stream(ty);
827 index
828 }
829}
830
831#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
833struct InstanceIndex(usize);
834
835enum ArgumentImportKind<'a> {
836 Item(&'a crate::graph::Component<'a>, ComponentEntityType),
840 Instance(IndexMap<&'a str, Vec<(&'a crate::graph::Component<'a>, ComponentEntityType)>>),
846}
847
848struct ArgumentImport<'a> {
850 name: &'a str,
852 kind: ArgumentImportKind<'a>,
854 instances: SmallVec<[(InstanceIndex, ImportIndex); 1]>,
856}
857
858impl ArgumentImport<'_> {
859 fn merge(&mut self, arg: Self, remapping: &mut Remapping) -> Result<()> {
860 assert_eq!(self.name, arg.name);
861 self.instances.extend(arg.instances);
862
863 if let ArgumentImportKind::Item(component, ComponentEntityType::Instance(id)) = &self.kind {
866 let exports = component.types[*id].exports.iter();
867
868 let mut map = IndexMap::with_capacity(exports.len());
869 for (name, ty) in exports {
870 map.insert(name.as_str(), vec![(*component, *ty)]);
871 }
872
873 self.kind = ArgumentImportKind::Instance(map);
874 }
875
876 match (&mut self.kind, arg.kind) {
877 (_, ArgumentImportKind::Instance(..)) => {
879 unreachable!("expected an item import to merge with")
880 }
881 (
883 ArgumentImportKind::Instance(exports),
884 ArgumentImportKind::Item(new_component, ComponentEntityType::Instance(id)),
885 ) => {
886 for (name, new_type) in new_component.types[id].exports.iter() {
887 let dst = exports.entry(name.as_str()).or_default();
888 for (existing_component, existing_type) in dst.iter_mut() {
889 if Self::types_compatible(
890 existing_component,
891 *existing_type,
892 new_component,
893 *new_type,
894 remapping,
895 ) {
896 continue;
897 }
898 bail!(
899 "cannot import instance with name `{name}` for \
900 an instantiation argument of component \
901 `{cname}` because it conflicts with an \
902 imported instantiation argument of component \
903 `{ecname}`",
904 name = self.name,
905 cname = new_component.name,
906 ecname = existing_component.name,
907 )
908 }
909 dst.push((new_component, *new_type));
910 }
911 }
912 (ArgumentImportKind::Instance(_), ArgumentImportKind::Item(component, ty)) => {
914 bail!(
915 "cannot import {ty} with name `{name}` for an instantiation \
916 argument of component `{cname}` because it conflicts with \
917 an instance imported with the same name",
918 name = self.name,
919 ty = type_desc(ty),
920 cname = component.name,
921 );
922 }
923 (
925 ArgumentImportKind::Item(existing_component, existing_type),
926 ArgumentImportKind::Item(new_component, new_type),
927 ) => {
928 if !Self::types_compatible(
929 existing_component,
930 *existing_type,
931 new_component,
932 new_type,
933 remapping,
934 ) {
935 bail!(
936 "cannot import {ty} with name `{name}` for an \
937 instantiation argument of component `{cname}` \
938 because it conflicts with an imported instantiation \
939 argument of component `{ecname}`",
940 ty = type_desc(new_type),
941 name = self.name,
942 cname = new_component.name,
943 ecname = existing_component.name,
944 )
945 }
946 }
947 }
948
949 Ok(())
950 }
951
952 fn types_compatible<'a>(
959 existing_component: &'a crate::graph::Component<'a>,
960 existing_type: ComponentEntityType,
961 new_component: &'a crate::graph::Component<'a>,
962 new_type: ComponentEntityType,
963 remapping: &mut Remapping,
964 ) -> bool {
965 let mut context =
966 SubtypeCx::new_with_refs(existing_component.types(), new_component.types());
967 let mut a_ty = existing_type;
968 context.a.remap_component_entity(&mut a_ty, remapping);
969 remapping.reset_type_cache();
970
971 let mut b_ty = new_type;
972 context.b.remap_component_entity(&mut b_ty, remapping);
973 remapping.reset_type_cache();
974
975 if context.component_entity_type(&a_ty, &b_ty, 0).is_err() {
976 return false;
977 }
978
979 context.swap();
980
981 context.component_entity_type(&b_ty, &a_ty, 0).is_ok()
982 }
983}
984
985enum ImportMapEntry<'a> {
991 Component(&'a crate::graph::Component<'a>),
993 Argument(ArgumentImport<'a>),
995}
996
997#[derive(Default)]
1000struct ImportMap<'a>(IndexMap<&'a str, ImportMapEntry<'a>>);
1001
1002impl<'a> ImportMap<'a> {
1003 fn new(import_components: bool, graph: &'a CompositionGraph) -> Result<Self> {
1004 let mut imports = Self::default();
1005
1006 if import_components {
1007 imports.add_component_imports(graph);
1008 }
1009
1010 imports.add_instantiation_imports(graph)?;
1011
1012 Ok(imports)
1013 }
1014
1015 fn add_component_imports(&mut self, graph: &'a CompositionGraph) {
1016 for entry in graph
1017 .components
1018 .values()
1019 .filter(|e| !e.instances.is_empty())
1020 {
1021 assert!(
1022 self.0
1023 .insert(
1024 &entry.component.name,
1025 ImportMapEntry::Component(&entry.component),
1026 )
1027 .is_none()
1028 );
1029 }
1030 }
1031
1032 fn add_instantiation_imports(&mut self, graph: &'a CompositionGraph) -> Result<()> {
1033 let remapping = &mut graph.resource_mapping.borrow().remapping();
1034 let mut imported = HashMap::new();
1035
1036 let mut component_defining_instance = HashMap::new();
1039 let mut deps = HashMap::new();
1040
1041 for (instance_index, instance) in graph.instances.values().enumerate() {
1042 let (component_index, _, entry) =
1043 graph.components.get_full(&instance.component).unwrap();
1044 let defining_instances = component_defining_instance
1045 .entry(component_index)
1046 .or_insert(HashMap::new());
1047
1048 let instance_index = InstanceIndex(instance_index);
1049
1050 for (import_index, name, _) in entry.component.imports() {
1052 if instance.connected.contains(&import_index) {
1053 continue;
1054 }
1055
1056 let (_, ty) = entry.component.import_entity_type(import_index).unwrap();
1057
1058 let arg = ArgumentImport {
1059 name,
1060 kind: ArgumentImportKind::Item(&entry.component, ty),
1061 instances: smallvec::smallvec![(instance_index, import_index)],
1062 };
1063
1064 match imported.entry((component_index, import_index)) {
1067 Entry::Occupied(e) => match self.0.get_index_mut(*e.get()).unwrap().1 {
1068 ImportMapEntry::Component(_) => {
1069 unreachable!("import should not be for a component")
1070 }
1071 ImportMapEntry::Argument(arg) => {
1072 arg.instances.push((instance_index, import_index));
1073 }
1074 },
1075 Entry::Vacant(e) => {
1076 DependencyRegistrar {
1082 types: &entry.component.types,
1083 defining_instances,
1084 cur: name,
1085 deps: &mut deps,
1086 }
1087 .entity(ty);
1088 let index = match self.0.entry(name.into()) {
1089 indexmap::map::Entry::Occupied(mut e) => match e.get_mut() {
1090 ImportMapEntry::Component(_) => {
1091 bail!(
1092 "cannot import {ty} `{name}` for an instantiation argument of component `{cname}` because it conflicts with a component imported with the same name",
1093 ty = type_desc(ty),
1094 cname = entry.component.name,
1095 );
1096 }
1097 ImportMapEntry::Argument(existing) => {
1098 existing.merge(arg, remapping)?;
1099 e.index()
1100 }
1101 },
1102 indexmap::map::Entry::Vacant(e) => {
1103 let index = e.index();
1104 e.insert(ImportMapEntry::Argument(arg));
1105 index
1106 }
1107 };
1108 e.insert(index);
1109 }
1110 }
1111 }
1112 }
1113
1114 let mut order = IndexSet::new();
1137 for (name, _) in self.0.iter() {
1138 toposort(&name[..], &deps, &mut order);
1139 }
1140 let order = order
1141 .into_iter()
1142 .map(|s| s.to_string())
1143 .collect::<IndexSet<_>>();
1144 self.0
1145 .sort_by_cached_key(|name, _| order.get_full(&name[..]).unwrap().0);
1146
1147 Ok(())
1148 }
1149}
1150
1151struct DependencyRegistrar<'a, 'b> {
1162 types: &'a types::Types,
1163 defining_instances: &'b mut HashMap<ComponentAnyTypeId, &'a str>,
1164 cur: &'a str,
1165 deps: &'b mut HashMap<&'a str, Vec<&'a str>>,
1166}
1167
1168impl DependencyRegistrar<'_, '_> {
1169 fn entity(&mut self, ty: ComponentEntityType) {
1170 match ty {
1171 ComponentEntityType::Type {
1172 created,
1173 referenced,
1174 } => {
1175 let prev = self.defining_instances.insert(created, self.cur);
1176 assert!(prev.is_none());
1177 self.ty(referenced);
1178 }
1179 ComponentEntityType::Module(_) => {}
1180 ComponentEntityType::Value(v) => self.val_type(v),
1181 ComponentEntityType::Instance(e) => self.instance(e),
1182 ComponentEntityType::Component(e) => self.component(e),
1183 ComponentEntityType::Func(e) => self.func(e),
1184 }
1185 }
1186
1187 fn ty(&mut self, ty: ComponentAnyTypeId) {
1188 match self.defining_instances.entry(ty) {
1189 Entry::Occupied(e) => {
1193 if *e.get() != self.cur {
1194 self.deps.entry(self.cur).or_default().push(*e.get());
1195 }
1196 return;
1197 }
1198
1199 Entry::Vacant(e) => {
1202 e.insert(self.cur);
1203 }
1204 }
1205
1206 if let Some(ty) = self.types.as_ref().peel_alias(ty) {
1209 return self.ty(ty);
1210 }
1211
1212 match ty {
1213 ComponentAnyTypeId::Resource(_) => {}
1214 ComponentAnyTypeId::Defined(id) => self.defined(id),
1215 ComponentAnyTypeId::Func(id) => self.func(id),
1216 ComponentAnyTypeId::Instance(id) => self.instance(id),
1217 ComponentAnyTypeId::Component(id) => self.component(id),
1218 }
1219 }
1220
1221 fn val_type(&mut self, ty: ct::ComponentValType) {
1222 match ty {
1223 ct::ComponentValType::Type(t) => self.ty(t.into()),
1224 ct::ComponentValType::Primitive(_) => {}
1225 }
1226 }
1227
1228 fn component(&mut self, ty: ComponentTypeId) {
1229 let ty = &self.types[ty];
1230 for (_, ty) in ty.imports.iter().chain(&ty.exports) {
1231 self.entity(*ty);
1232 }
1233 }
1234
1235 fn instance(&mut self, ty: ComponentInstanceTypeId) {
1236 for (_, ty) in self.types[ty].exports.iter() {
1237 self.entity(*ty);
1238 }
1239 }
1240
1241 fn func(&mut self, ty: ComponentFuncTypeId) {
1242 let ty = &self.types[ty];
1243 for ty in ty.params.iter().map(|p| p.1).chain(ty.result) {
1244 self.val_type(ty);
1245 }
1246 }
1247
1248 fn defined(&mut self, ty: ComponentDefinedTypeId) {
1249 match &self.types[ty] {
1250 ComponentDefinedType::Primitive(_)
1251 | ComponentDefinedType::Enum(_)
1252 | ComponentDefinedType::Flags(_) => {}
1253 ComponentDefinedType::List(t)
1254 | ComponentDefinedType::FixedSizeList(t, _)
1255 | ComponentDefinedType::Option(t) => self.val_type(*t),
1256 ComponentDefinedType::Own(r) | ComponentDefinedType::Borrow(r) => {
1257 self.ty(ComponentAnyTypeId::Resource(*r))
1258 }
1259 ComponentDefinedType::Record(r) => {
1260 for (_, ty) in r.fields.iter() {
1261 self.val_type(*ty);
1262 }
1263 }
1264 ComponentDefinedType::Tuple(r) => {
1265 for ty in r.types.iter() {
1266 self.val_type(*ty);
1267 }
1268 }
1269 ComponentDefinedType::Variant(r) => {
1270 for (_, case) in r.cases.iter() {
1271 if let Some(ty) = case.ty {
1272 self.val_type(ty);
1273 }
1274 }
1275 }
1276 ComponentDefinedType::Result { ok, err } => {
1277 if let Some(ok) = ok {
1278 self.val_type(*ok);
1279 }
1280 if let Some(err) = err {
1281 self.val_type(*err);
1282 }
1283 }
1284 ComponentDefinedType::Future(ty) => {
1285 if let Some(ty) = ty {
1286 self.val_type(*ty);
1287 }
1288 }
1289 ComponentDefinedType::Stream(ty) => {
1290 if let Some(ty) = ty {
1291 self.val_type(*ty);
1292 }
1293 }
1294 }
1295 }
1296}
1297
1298fn toposort<'a>(
1299 cur: &'a str,
1300 deps: &HashMap<&'a str, Vec<&'a str>>,
1301 order: &mut IndexSet<&'a str>,
1302) {
1303 if order.contains(cur) {
1304 return;
1305 }
1306 if let Some(list) = deps.get(cur) {
1307 for dep in list {
1308 toposort(dep, deps, order);
1309 }
1310 }
1311 let ok = order.insert(cur);
1312 assert!(ok);
1313}
1314
1315pub(crate) struct CompositionGraphEncoder<'a> {
1317 options: EncodeOptions,
1319 graph: &'a CompositionGraph<'a>,
1321 encoded_components: HashMap<PtrKey<'a, crate::graph::Component<'a>>, u32>,
1323 encoded_instances: HashMap<InstanceId, u32>,
1325 imported_args: HashMap<(InstanceIndex, ImportIndex), u32>,
1329 aliases: HashMap<(InstanceId, ExportIndex), u32>,
1334}
1335
1336impl<'a> CompositionGraphEncoder<'a> {
1337 pub(crate) fn new(options: EncodeOptions, graph: &'a CompositionGraph) -> Self {
1338 Self {
1339 options,
1340 graph,
1341 encoded_components: Default::default(),
1342 encoded_instances: Default::default(),
1343 imported_args: Default::default(),
1344 aliases: Default::default(),
1345 }
1346 }
1347
1348 pub(crate) fn encode(mut self) -> Result<Vec<u8>> {
1349 let mut encoded = ComponentBuilder::default();
1350
1351 self.encode_imports(&mut encoded)?;
1352 self.encode_components(&mut encoded);
1353 self.encode_instantiations(&mut encoded)?;
1354
1355 if let Some(id) = self.options.export {
1356 self.encode_exports(&mut encoded, id)?;
1357 }
1358
1359 Ok(encoded.finish())
1360 }
1361
1362 fn encode_imports(&mut self, encoded: &mut ComponentBuilder) -> Result<()> {
1363 let imports = ImportMap::new(!self.options.define_components, self.graph)?;
1364
1365 let mut state = TypeState::new_with_remapping(self.graph.remapping_map());
1368 state.cur.encodable = Encodable::Builder(mem::take(encoded));
1369
1370 for (name, entry) in imports.0 {
1371 log::trace!("encoding import {name}");
1372 match entry {
1373 ImportMapEntry::Component(component) => {
1374 let encoded = match &mut state.cur.encodable {
1375 Encodable::Builder(builder) => builder,
1376 _ => unreachable!(),
1377 };
1378 self.encode_component_import(encoded, name.as_ref(), component);
1379 }
1380 ImportMapEntry::Argument(arg) => {
1381 let index = match arg.kind {
1382 ArgumentImportKind::Item(component, ty) => {
1383 self.encode_item_import(&mut state, name.as_ref(), component, ty)
1384 }
1385 ArgumentImportKind::Instance(exports) => {
1386 self.encode_instance_import(&mut state, name.as_ref(), exports)
1387 }
1388 };
1389
1390 self.imported_args
1391 .extend(arg.instances.into_iter().map(|k| (k, index)));
1392 }
1393 }
1394 }
1395
1396 match &mut state.cur.encodable {
1399 Encodable::Builder(builder) => *encoded = mem::take(builder),
1400 _ => unreachable!(),
1401 }
1402
1403 Ok(())
1404 }
1405
1406 fn encode_component_import(
1407 &mut self,
1408 encoded: &mut ComponentBuilder,
1409 name: &str,
1410 component: &'a crate::graph::Component,
1411 ) -> u32 {
1412 let type_index = self.define_component_type(encoded, component);
1413 let index = self.import(encoded, name, ComponentTypeRef::Component(type_index));
1414
1415 assert!(
1416 self.encoded_components
1417 .insert(PtrKey(component), index)
1418 .is_none()
1419 );
1420
1421 index
1422 }
1423
1424 fn encode_item_import(
1425 &mut self,
1426 state: &mut TypeState<'a>,
1427 name: &str,
1428 component: &'a crate::graph::Component,
1429 ty: ComponentEntityType,
1430 ) -> u32 {
1431 log::trace!("encoding item import {name}");
1432 let encoder = TypeEncoder::new(component);
1433 let ty = encoder.component_entity_type(state, ty);
1434
1435 let encoded = match &mut state.cur.encodable {
1436 Encodable::Builder(builder) => builder,
1437 _ => unreachable!(),
1438 };
1439 self.import(encoded, name, ty)
1440 }
1441
1442 fn encode_instance_import(
1443 &mut self,
1444 state: &mut TypeState<'a>,
1445 name: &str,
1446 exports: IndexMap<&'a str, Vec<(&'a crate::graph::Component, ComponentEntityType)>>,
1447 ) -> u32 {
1448 log::trace!("encoding instance import {name}");
1449 state.push(Encodable::Instance(InstanceType::new()));
1450 for (name, types) in exports {
1451 let (component, ty) = types[0];
1452 log::trace!("export {name}: {ty:?}");
1453 let export = TypeEncoder::new(component).export(name, ty, state);
1454 let t = match &mut state.cur.encodable {
1455 Encodable::Instance(c) => c,
1456 _ => unreachable!(),
1457 };
1458 t.export(name, export);
1459
1460 for (component, ty) in types.iter().skip(1) {
1461 if let ComponentEntityType::Type { created, .. } = ty {
1462 state
1463 .cur
1464 .add_type_export((PtrKey(component), (*created).into()), name);
1465 }
1466 }
1467 }
1468
1469 let instance_type = match state.pop() {
1470 Encodable::Instance(c) => c,
1471 _ => unreachable!(),
1472 };
1473
1474 let encoded = match &mut state.cur.encodable {
1475 Encodable::Builder(builder) => builder,
1476 _ => unreachable!(),
1477 };
1478 let index = encoded.type_instance(None, &instance_type);
1479 self.import(encoded, name, ComponentTypeRef::Instance(index))
1480 }
1481
1482 fn encode_instantiations(&mut self, encoded: &mut ComponentBuilder) -> Result<()> {
1483 let ordering = self.graph.instantiation_order()?;
1484
1485 for id in self
1487 .graph
1488 .instances
1489 .keys()
1490 .filter(|id| !ordering.contains(*id))
1491 {
1492 self.encode_instantiation(encoded, *id)?;
1493 }
1494
1495 for id in ordering {
1497 self.encode_instantiation(encoded, id)?;
1498 }
1499
1500 Ok(())
1501 }
1502
1503 fn encode_exports(
1504 &mut self,
1505 encoded: &mut ComponentBuilder,
1506 instance_id: InstanceId,
1507 ) -> Result<()> {
1508 let instance = self.graph.instances.get(&instance_id).ok_or_else(|| {
1509 anyhow!("cannot export specified instance because it does not exist in the graph")
1510 })?;
1511 let entry = self.graph.components.get(&instance.component).unwrap();
1512
1513 let encoded_instance_index = self.encoded_instances[&instance_id];
1514
1515 for (export_index, export_name, kind, _) in entry.component.exports() {
1516 let kind = match kind {
1517 ComponentExternalKind::Module => ComponentExportKind::Module,
1518 ComponentExternalKind::Func => ComponentExportKind::Func,
1519 ComponentExternalKind::Value => ComponentExportKind::Value,
1520 ComponentExternalKind::Type => ComponentExportKind::Type,
1521 ComponentExternalKind::Instance => ComponentExportKind::Instance,
1522 ComponentExternalKind::Component => ComponentExportKind::Component,
1523 };
1524
1525 let index = match self.aliases.get(&(instance_id, export_index)) {
1526 Some(index) => *index,
1527 None => {
1528 let index = self.alias(encoded, encoded_instance_index, export_name, kind);
1529 self.aliases.insert((instance_id, export_index), index);
1530 index
1531 }
1532 };
1533
1534 encoded.export(export_name, kind, index, None);
1535 }
1536
1537 Ok(())
1538 }
1539
1540 fn encode_instantiation(
1541 &mut self,
1542 encoded: &mut ComponentBuilder,
1543 instance_id: InstanceId,
1544 ) -> Result<()> {
1545 let (instance_index, _, instance) = self.graph.instances.get_full(&instance_id).unwrap();
1546 let entry = &self.graph.components.get(&instance.component).unwrap();
1547
1548 let instance_index = InstanceIndex(instance_index);
1549 let encoded_component_index = self.encoded_components[&PtrKey(&entry.component)];
1550
1551 let args = self.instantiation_args(encoded, instance_index, &entry.component);
1552
1553 log::debug!(
1554 "instantiating component `{name}` with {args:?}",
1555 name = entry.component.name,
1556 );
1557
1558 let encoded_instance_index = encoded.instantiate(None, encoded_component_index, args);
1559
1560 self.encoded_instances
1561 .insert(instance_id, encoded_instance_index);
1562
1563 Ok(())
1564 }
1565
1566 fn encode_components(&mut self, encoded: &mut ComponentBuilder) {
1567 if !self.options.define_components {
1568 return;
1569 }
1570
1571 for entry in self
1572 .graph
1573 .components
1574 .values()
1575 .filter(|e| !e.instances.is_empty())
1576 {
1577 let index = self.define_component(encoded, &entry.component);
1578 assert!(
1579 self.encoded_components
1580 .insert(PtrKey(&entry.component), index)
1581 .is_none()
1582 );
1583 }
1584 }
1585
1586 fn define_component_type(
1587 &mut self,
1588 encoded: &mut ComponentBuilder,
1589 component: &crate::graph::Component,
1590 ) -> u32 {
1591 encoded.type_component(None, &component.ty())
1592 }
1593
1594 fn define_component(
1595 &mut self,
1596 encoded: &mut ComponentBuilder,
1597 component: &crate::graph::Component,
1598 ) -> u32 {
1599 log::debug!(
1600 "defining component `{name}` in composed component",
1601 name = component.name,
1602 );
1603 encoded.component_raw(None, component.bytes())
1604 }
1605
1606 fn instantiation_args(
1607 &mut self,
1608 encoded: &mut ComponentBuilder,
1609 instance_index: InstanceIndex,
1610 component: &'a crate::graph::Component,
1611 ) -> Vec<(&'a str, ComponentExportKind, u32)> {
1612 let (instance_id, instance) = self.graph.instances.get_index(instance_index.0).unwrap();
1613 let mut args = Vec::with_capacity(component.imports.len());
1614
1615 for (source_id, _, map) in self
1617 .graph
1618 .graph
1619 .edges_directed(*instance_id, EdgeDirection::Incoming)
1620 {
1621 assert!(source_id != *instance_id);
1622 let source_index = self.encoded_instances[&source_id];
1623 let (_, source_component) = &self.graph.get_component_of_instance(source_id).unwrap();
1624
1625 for (import_index, export_index) in map {
1626 let (name, ty) = component.import(*import_index).unwrap();
1628 let index = match export_index {
1629 Some(export_index) => {
1630 let (export_name, _, _) = source_component.export(*export_index).unwrap();
1631 match self.aliases.get(&(source_id, *export_index)) {
1632 Some(index) => *index,
1633 None => {
1634 let index = self.alias(
1635 encoded,
1636 source_index,
1637 export_name,
1638 type_ref_to_export_kind(ty),
1639 );
1640 self.aliases.insert((source_id, *export_index), index);
1641 index
1642 }
1643 }
1644 }
1645 None => source_index,
1646 };
1647 args.push((name, type_ref_to_export_kind(ty), index));
1648 }
1649 }
1650
1651 for (i, (name, ty)) in component.imports.iter().enumerate() {
1653 let import_index = ImportIndex(i);
1654 if instance.connected.contains(&import_index) {
1655 continue;
1656 }
1657
1658 let index = self.imported_args[&(instance_index, import_index)];
1659 args.push((name.as_str(), type_ref_to_export_kind(*ty), index));
1660 }
1661
1662 args
1663 }
1664
1665 fn import(&mut self, encoded: &mut ComponentBuilder, name: &str, ty: ComponentTypeRef) -> u32 {
1666 log::debug!("importing {ty:?} with `{name}` in composed component");
1667 encoded.import(name, ty)
1668 }
1669
1670 fn alias(
1671 &mut self,
1672 encoded: &mut ComponentBuilder,
1673 instance: u32,
1674 name: &str,
1675 kind: ComponentExportKind,
1676 ) -> u32 {
1677 log::debug!(
1678 "aliasing {kind:?} export `{name}` from encoded index {instance} in composed component"
1679 );
1680 encoded.alias_export(instance, name, kind)
1681 }
1682}