1use crate::{
2 CoreExtern, CoreFuncType, DefinedType, Enum, Flags, FuncType, FuncTypeId, Interface,
3 InterfaceId, ItemKind, ModuleType, ModuleTypeId, Record, Resource, ResourceAlias, ResourceId,
4 Type, Types, UsedType, ValueType, Variant, World, WorldId,
5};
6use anyhow::{bail, Context, Result};
7use indexmap::IndexMap;
8use semver::Version;
9use std::borrow::Borrow;
10use std::fmt;
11use std::{collections::HashMap, path::Path, rc::Rc};
12use wasmparser::{
13 component_types::{self as wasm},
14 names::{ComponentName, ComponentNameKind},
15 Chunk, Encoding, Parser, Payload, ValidPayload, Validator, WasmFeatures,
16};
17
18#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
20pub struct PackageKey {
21 name: String,
23 version: Option<Version>,
25}
26
27impl PackageKey {
28 pub fn new(package: &Package) -> Self {
30 Self {
31 name: package.name.clone(),
32 version: package.version.clone(),
33 }
34 }
35
36 pub fn name(&self) -> &str {
38 &self.name
39 }
40
41 pub fn version(&self) -> Option<&Version> {
43 self.version.as_ref()
44 }
45}
46
47impl fmt::Display for PackageKey {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(f, "{name}", name = self.name)?;
50 if let Some(version) = &self.version {
51 write!(f, "@{version}")?;
52 }
53
54 Ok(())
55 }
56}
57
58#[derive(Copy, Clone, Hash, PartialEq, Eq)]
60pub struct BorrowedPackageKey<'a> {
61 pub name: &'a str,
63 pub version: Option<&'a Version>,
65}
66
67impl<'a> BorrowedPackageKey<'a> {
68 pub fn new(package: &'a Package) -> Self {
70 Self {
71 name: &package.name,
72 version: package.version.as_ref(),
73 }
74 }
75
76 pub fn from_name_and_version(name: &'a str, version: Option<&'a Version>) -> Self {
78 Self { name, version }
79 }
80
81 pub fn into_owned(self) -> PackageKey {
83 PackageKey {
84 name: self.name.to_owned(),
85 version: self.version.cloned(),
86 }
87 }
88}
89
90impl fmt::Display for BorrowedPackageKey<'_> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 write!(f, "{name}", name = self.name)?;
93 if let Some(version) = self.version {
94 write!(f, "@{version}")?;
95 }
96
97 Ok(())
98 }
99}
100
101pub trait BorrowedKey {
103 fn borrowed_key(&self) -> BorrowedPackageKey;
105}
106
107impl BorrowedKey for PackageKey {
108 fn borrowed_key(&self) -> BorrowedPackageKey {
109 BorrowedPackageKey {
110 name: &self.name,
111 version: self.version.as_ref(),
112 }
113 }
114}
115
116impl BorrowedKey for BorrowedPackageKey<'_> {
117 fn borrowed_key(&self) -> BorrowedPackageKey {
118 *self
119 }
120}
121
122impl<'a> Borrow<dyn BorrowedKey + 'a> for PackageKey {
123 fn borrow(&self) -> &(dyn BorrowedKey + 'a) {
124 self
125 }
126}
127
128impl Eq for (dyn BorrowedKey + '_) {}
129
130impl PartialEq for (dyn BorrowedKey + '_) {
131 fn eq(&self, other: &dyn BorrowedKey) -> bool {
132 self.borrowed_key().eq(&other.borrowed_key())
133 }
134}
135
136impl std::hash::Hash for (dyn BorrowedKey + '_) {
137 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
138 self.borrowed_key().hash(state)
139 }
140}
141
142#[derive(Clone)]
146#[cfg_attr(feature = "serde", derive(serde::Serialize))]
147#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
148pub struct Package {
149 name: String,
151 version: Option<Version>,
153 #[cfg_attr(feature = "serde", serde(skip))]
157 bytes: Vec<u8>,
158 ty: WorldId,
160 instance_type: InterfaceId,
162 definitions: IndexMap<String, ItemKind>,
164}
165
166impl Package {
167 pub fn key(&self) -> BorrowedPackageKey {
169 BorrowedPackageKey::new(self)
170 }
171
172 pub fn from_file(
176 name: &str,
177 version: Option<&Version>,
178 path: impl AsRef<Path>,
179 types: &mut Types,
180 ) -> Result<Self> {
181 let path = path.as_ref();
182 let bytes = std::fs::read(path)
183 .with_context(|| format!("failed to read `{path}`", path = path.display()))?;
184 Self::from_bytes(name, version, bytes, types)
185 }
186
187 pub fn from_bytes(
191 name: &str,
192 version: Option<&Version>,
193 bytes: impl Into<Vec<u8>>,
194 types: &mut Types,
195 ) -> Result<Self> {
196 let bytes = bytes.into();
197 if !Parser::is_component(&bytes) {
198 bail!("package `{name}` is not a binary-encoded WebAssembly component");
199 }
200
201 let mut parser = Parser::new(0);
202 let mut parsers = Vec::new();
203 let mut validator = Validator::new_with_features(WasmFeatures::all());
204 let mut imports = Vec::new();
205 let mut exports = Vec::new();
206
207 let mut cur = bytes.as_ref();
208 loop {
209 match parser.parse(cur, true)? {
210 Chunk::Parsed { payload, consumed } => {
211 cur = &cur[consumed..];
212
213 match validator.payload(&payload)? {
214 ValidPayload::Ok => {
215 if !parsers.is_empty() {
217 continue;
218 }
219
220 match payload {
221 Payload::Version { encoding, .. } => {
222 assert_eq!(encoding, Encoding::Component);
223 }
224 Payload::ComponentImportSection(s) => {
225 imports.reserve(s.count() as usize);
226 for import in s {
227 imports.push(import?.name.0);
228 }
229 }
230 Payload::ComponentExportSection(s) => {
231 exports.reserve(s.count() as usize);
232 for export in s {
233 exports.push(export?.name.0);
234 }
235 }
236 _ => {}
237 }
238 }
239 ValidPayload::Func(_, _) => {}
240 ValidPayload::Parser(next) => {
241 parsers.push(parser);
242 parser = next;
243 }
244 ValidPayload::End(wasm_types) => match parsers.pop() {
245 Some(parent) => parser = parent,
246 None => {
247 let mut converter = TypeConverter::new(types, wasm_types);
248
249 let imports = imports
250 .into_iter()
251 .map(|i| Ok((i.to_string(), converter.import(i)?)))
252 .collect::<Result<_>>()?;
253
254 let exports: IndexMap<String, ItemKind> = exports
255 .into_iter()
256 .map(|i| Ok((i.to_string(), converter.export(i)?)))
257 .collect::<Result<_>>()?;
258
259 let ty = types.add_world(World {
260 id: None,
261 uses: Default::default(),
262 imports,
263 exports: exports.clone(),
264 });
265
266 let instance_type = types.add_interface(Interface {
267 id: None,
268 uses: Default::default(),
269 exports,
270 });
271
272 let definitions = Self::find_definitions(types, ty);
273
274 return Ok(Self {
275 name: name.to_owned(),
276 version: version.map(ToOwned::to_owned),
277 bytes,
278 ty,
279 instance_type,
280 definitions,
281 });
282 }
283 },
284 }
285 }
286 Chunk::NeedMoreData(_) => panic!("all data should be present"),
287 }
288 }
289 }
290
291 pub fn name(&self) -> &str {
293 &self.name
294 }
295
296 pub fn version(&self) -> Option<&Version> {
298 self.version.as_ref()
299 }
300
301 pub fn bytes(&self) -> &[u8] {
305 &self.bytes
306 }
307
308 pub fn ty(&self) -> WorldId {
310 self.ty
311 }
312
313 pub fn instance_type(&self) -> InterfaceId {
316 self.instance_type
317 }
318
319 pub fn definitions(&self) -> &IndexMap<String, ItemKind> {
321 &self.definitions
322 }
323
324 fn find_definitions(types: &Types, world: WorldId) -> IndexMap<String, ItemKind> {
325 let exports = &types[world].exports;
327 let mut defs = IndexMap::new();
328 for (name, kind) in exports {
329 if let ItemKind::Type(Type::World(id)) = kind {
330 let world = &types[*id];
331 if world.exports.len() != 1 {
332 continue;
333 }
334
335 let (export_name, kind) = world.exports.get_index(0).unwrap();
337 match ComponentName::new(export_name, 0).unwrap().kind() {
338 ComponentNameKind::Interface(_) => {}
339 _ => continue,
340 }
341
342 match kind {
343 ItemKind::Instance(id) => {
344 defs.insert(name.clone(), ItemKind::Type(Type::Interface(*id)));
345 }
346 ItemKind::Component(id) => {
347 defs.insert(name.clone(), ItemKind::Type(Type::World(*id)));
348 }
349 _ => continue,
350 }
351 }
352 }
353
354 defs
355 }
356}
357
358impl fmt::Debug for Package {
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 f.debug_struct("Package")
361 .field("name", &self.name)
362 .field("version", &self.version)
363 .field("bytes", &"...")
364 .field("ty", &self.ty)
365 .field("instance_type", &self.instance_type)
366 .field("definitions", &self.definitions)
367 .finish()
368 }
369}
370
371#[derive(Debug, Clone, Copy, PartialEq, Eq)]
372enum Owner {
373 Interface(InterfaceId),
375 World(WorldId),
377}
378
379#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
380enum Entity {
381 Type(Type),
383 Resource(ResourceId),
385}
386
387struct TypeConverter<'a> {
390 types: &'a mut Types,
391 wasm_types: Rc<wasmparser::types::Types>,
392 cache: HashMap<wasm::AnyTypeId, Entity>,
393 resource_map: HashMap<wasm::ResourceId, ResourceId>,
394 owners: HashMap<wasm::ComponentAnyTypeId, (Owner, String)>,
395}
396
397impl<'a> TypeConverter<'a> {
398 fn new(types: &'a mut Types, wasm_types: wasmparser::types::Types) -> Self {
399 Self {
400 types,
401 wasm_types: Rc::new(wasm_types),
402 cache: Default::default(),
403 resource_map: Default::default(),
404 owners: Default::default(),
405 }
406 }
407
408 fn import(&mut self, name: &str) -> Result<ItemKind> {
409 let import = self
410 .wasm_types
411 .component_entity_type_of_import(name)
412 .unwrap();
413 self.entity(name, import)
414 }
415
416 fn export(&mut self, name: &str) -> Result<ItemKind> {
417 let export = self
418 .wasm_types
419 .component_entity_type_of_export(name)
420 .unwrap();
421 self.entity(name, export)
422 }
423
424 fn component_func_type(&mut self, id: wasm::ComponentFuncTypeId) -> Result<FuncTypeId> {
425 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Func(id));
426 if let Some(ty) = self.cache.get(&key) {
427 match ty {
428 Entity::Type(Type::Func(id)) => return Ok(*id),
429 _ => panic!("invalid cached type"),
430 }
431 }
432
433 let wasm_types = self.wasm_types.clone();
434 let func_ty = &wasm_types[id];
435 let params = func_ty
436 .params
437 .iter()
438 .map(|(name, ty)| Ok((name.to_string(), self.component_val_type(*ty)?)))
439 .collect::<Result<_>>()?;
440
441 let result = match func_ty.result {
442 Some(ty) => Some(self.component_val_type(ty)?),
443 None => None,
444 };
445
446 let id = self.types.add_func_type(FuncType { params, result });
447 self.cache.insert(key, Entity::Type(Type::Func(id)));
448 Ok(id)
449 }
450
451 fn module_type(&mut self, id: wasm::ComponentCoreModuleTypeId) -> Result<ModuleTypeId> {
452 let key = wasm::AnyTypeId::Core(wasm::ComponentCoreTypeId::Module(id));
453 if let Some(ty) = self.cache.get(&key) {
454 match ty {
455 Entity::Type(Type::Module(id)) => return Ok(*id),
456 _ => panic!("invalid cached type"),
457 }
458 }
459
460 let module_ty = &self.wasm_types[id];
461
462 let imports = module_ty
463 .imports
464 .iter()
465 .map(|((module, name), ty)| ((module.clone(), name.clone()), self.entity_type(*ty)))
466 .collect();
467
468 let exports = module_ty
469 .exports
470 .iter()
471 .map(|(name, ty)| (name.clone(), self.entity_type(*ty)))
472 .collect();
473
474 let module_id = self.types.add_module_type(ModuleType { imports, exports });
475 self.cache
476 .insert(key, Entity::Type(Type::Module(module_id)));
477 Ok(module_id)
478 }
479
480 fn ty(&mut self, name: &str, id: wasm::ComponentAnyTypeId) -> Result<Type> {
481 match id {
482 wasm::ComponentAnyTypeId::Defined(id) => {
483 Ok(Type::Value(self.component_defined_type(id)?))
484 }
485 wasm::ComponentAnyTypeId::Func(id) => Ok(Type::Func(self.component_func_type(id)?)),
486 wasm::ComponentAnyTypeId::Component(id) => {
487 Ok(Type::World(self.component_type(None, id)?))
488 }
489 wasm::ComponentAnyTypeId::Instance(id) => {
490 Ok(Type::Interface(self.component_instance_type(None, id)?))
491 }
492 wasm::ComponentAnyTypeId::Resource(id) => Ok(Type::Resource(self.resource(name, id))),
493 }
494 }
495
496 fn component_val_type(&mut self, ty: wasm::ComponentValType) -> Result<ValueType> {
497 match ty {
498 wasm::ComponentValType::Primitive(ty) => Ok(ValueType::Primitive(ty.into())),
499 wasm::ComponentValType::Type(id) => Ok(self.component_defined_type(id)?),
500 }
501 }
502
503 fn component_instance_type(
504 &mut self,
505 name: Option<&str>,
506 id: wasm::ComponentInstanceTypeId,
507 ) -> Result<InterfaceId> {
508 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Instance(id));
509 if let Some(ty) = self.cache.get(&key) {
510 match ty {
511 Entity::Type(Type::Interface(id)) => {
512 return Ok(*id);
513 }
514 _ => panic!("invalid cached type"),
515 }
516 }
517
518 let wasm_types = self.wasm_types.clone();
519 let instance_ty = &wasm_types[id];
520 let id = self.types.add_interface(Interface {
521 id: name.and_then(|n| n.contains(':').then(|| n.to_owned())),
522 uses: Default::default(),
523 exports: IndexMap::with_capacity(instance_ty.exports.len()),
524 });
525
526 for (name, ty) in &instance_ty.exports {
527 let export = self.entity(name, *ty)?;
528
529 if let wasm::ComponentEntityType::Type {
530 referenced,
531 created,
532 } = ty
533 {
534 self.use_or_own(Owner::Interface(id), name, *referenced, *created);
535
536 if let ItemKind::Type(Type::Resource(res)) = export {
538 if let Some(ResourceAlias { owner, .. }) = &mut self.types[res].alias {
539 if let Some(owner_id) = owner {
540 if *owner_id == id {
541 *owner = None;
542 }
543 }
544 }
545 }
546 }
547
548 let prev = self.types[id].exports.insert(name.clone(), export);
549 assert!(prev.is_none());
550 }
551
552 self.cache.insert(key, Entity::Type(Type::Interface(id)));
553 Ok(id)
554 }
555
556 fn entity(&mut self, name: &str, ty: wasm::ComponentEntityType) -> Result<ItemKind> {
557 match ty {
558 wasm::ComponentEntityType::Module(id) => Ok(ItemKind::Module(self.module_type(id)?)),
559 wasm::ComponentEntityType::Value(ty) => {
560 Ok(ItemKind::Value(self.component_val_type(ty)?))
561 }
562 wasm::ComponentEntityType::Type { created, .. } => {
563 Ok(ItemKind::Type(self.ty(name, created)?))
564 }
565 wasm::ComponentEntityType::Func(id) => {
566 Ok(ItemKind::Func(self.component_func_type(id)?))
567 }
568 wasm::ComponentEntityType::Instance(id) => Ok(ItemKind::Instance(
569 self.component_instance_type(Some(name), id)?,
570 )),
571 wasm::ComponentEntityType::Component(id) => {
572 Ok(ItemKind::Component(self.component_type(Some(name), id)?))
573 }
574 }
575 }
576
577 fn use_or_own(
578 &mut self,
579 owner: Owner,
580 name: &str,
581 referenced: wasm::ComponentAnyTypeId,
582 created: wasm::ComponentAnyTypeId,
583 ) {
584 if let Some((other, orig)) = self.find_owner(referenced) {
585 match *other {
586 Owner::Interface(interface) if owner != *other => {
587 let used = UsedType {
588 interface,
589 name: if name != orig {
590 Some(orig.to_string())
591 } else {
592 None
593 },
594 };
595
596 let uses = match owner {
598 Owner::Interface(id) => &mut self.types[id].uses,
599 Owner::World(id) => &mut self.types[id].uses,
600 };
601
602 uses.insert(name.to_string(), used);
603 }
604 _ => {}
605 }
606 return;
607 }
608
609 let prev = self.owners.insert(created, (owner, name.to_string()));
611 assert!(prev.is_none());
612 }
613
614 fn component_type(&mut self, name: Option<&str>, id: wasm::ComponentTypeId) -> Result<WorldId> {
615 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Component(id));
616 if let Some(ty) = self.cache.get(&key) {
617 match ty {
618 Entity::Type(Type::World(id)) => return Ok(*id),
619 _ => panic!("invalid cached type"),
620 }
621 }
622
623 let wasm_types = self.wasm_types.clone();
624 let component_ty = &wasm_types[id];
625 let id = self.types.add_world(World {
626 id: name.and_then(|n| n.contains(':').then(|| n.to_owned())),
627 uses: Default::default(),
628 imports: IndexMap::with_capacity(component_ty.imports.len()),
629 exports: IndexMap::with_capacity(component_ty.exports.len()),
630 });
631
632 for (name, ty) in &component_ty.imports {
633 let import = self.entity(name, *ty)?;
634
635 if let wasm::ComponentEntityType::Type {
636 referenced,
637 created,
638 } = ty
639 {
640 self.use_or_own(Owner::World(id), name, *referenced, *created);
641 }
642
643 let prev = self.types[id].imports.insert(name.clone(), import);
644 assert!(prev.is_none());
645 }
646
647 for (name, ty) in &component_ty.exports {
648 let ty = self.entity(name, *ty)?;
649 let prev = self.types[id].exports.insert(name.clone(), ty);
650 assert!(prev.is_none());
651 }
652
653 self.cache.insert(key, Entity::Type(Type::World(id)));
654 Ok(id)
655 }
656
657 fn component_defined_type(&mut self, id: wasm::ComponentDefinedTypeId) -> Result<ValueType> {
658 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Defined(id));
659 if let Some(ty) = self.cache.get(&key) {
660 match ty {
661 Entity::Type(Type::Value(ty)) => return Ok(*ty),
662 _ => panic!("invalid cached type"),
663 }
664 }
665
666 let wasm_types = self.wasm_types.clone();
667 let ty = match &wasm_types[id] {
668 wasm::ComponentDefinedType::Primitive(ty) => ValueType::Defined(
669 self.types
670 .add_defined_type(DefinedType::Alias(ValueType::Primitive((*ty).into()))),
671 ),
672 wasm::ComponentDefinedType::Record(ty) => {
673 let fields = ty
674 .fields
675 .iter()
676 .map(|(name, ty)| Ok((name.as_str().to_owned(), self.component_val_type(*ty)?)))
677 .collect::<Result<_>>()?;
678
679 ValueType::Defined(
680 self.types
681 .add_defined_type(DefinedType::Record(Record { fields })),
682 )
683 }
684 wasm::ComponentDefinedType::Variant(ty) => {
685 let cases = ty
686 .cases
687 .iter()
688 .map(|(name, case)| {
689 Ok((
690 name.as_str().to_owned(),
691 case.ty.map(|ty| self.component_val_type(ty)).transpose()?,
692 ))
693 })
694 .collect::<Result<_>>()?;
695
696 ValueType::Defined(
697 self.types
698 .add_defined_type(DefinedType::Variant(Variant { cases })),
699 )
700 }
701 wasm::ComponentDefinedType::List(ty) => {
702 let ty = self.component_val_type(*ty)?;
703 ValueType::Defined(self.types.add_defined_type(DefinedType::List(ty)))
704 }
705 wasm::ComponentDefinedType::Tuple(ty) => {
706 let types = ty
707 .types
708 .iter()
709 .map(|ty| self.component_val_type(*ty))
710 .collect::<Result<_>>()?;
711 ValueType::Defined(self.types.add_defined_type(DefinedType::Tuple(types)))
712 }
713 wasm::ComponentDefinedType::Flags(flags) => {
714 let flags = flags.iter().map(|flag| flag.as_str().to_owned()).collect();
715 ValueType::Defined(
716 self.types
717 .add_defined_type(DefinedType::Flags(Flags(flags))),
718 )
719 }
720 wasm::ComponentDefinedType::Enum(cases) => {
721 let cases = cases.iter().map(|case| case.as_str().to_owned()).collect();
722 ValueType::Defined(self.types.add_defined_type(DefinedType::Enum(Enum(cases))))
723 }
724 wasm::ComponentDefinedType::Option(ty) => {
725 let ty = self.component_val_type(*ty)?;
726 ValueType::Defined(self.types.add_defined_type(DefinedType::Option(ty)))
727 }
728 wasm::ComponentDefinedType::Result { ok, err } => {
729 let ok = ok.map(|ty| self.component_val_type(ty)).transpose()?;
730 let err = err.map(|ty| self.component_val_type(ty)).transpose()?;
731 ValueType::Defined(self.types.add_defined_type(DefinedType::Result { ok, err }))
732 }
733 wasm::ComponentDefinedType::Borrow(id) => ValueType::Borrow(
734 match self.cache.get(&wasm::AnyTypeId::Component(
735 wasm::ComponentAnyTypeId::Resource(*id),
736 )) {
737 Some(Entity::Resource(id)) => *id,
738 _ => panic!("expected a resource"),
739 },
740 ),
741 wasm::ComponentDefinedType::Own(id) => ValueType::Own(
742 match self.cache.get(&wasm::AnyTypeId::Component(
743 wasm::ComponentAnyTypeId::Resource(*id),
744 )) {
745 Some(Entity::Resource(id)) => *id,
746 _ => panic!("expected a resource"),
747 },
748 ),
749 wasm::ComponentDefinedType::Stream(ty) => {
750 let stream = ty.map(|ty| self.component_val_type(ty)).transpose()?;
751 ValueType::Defined(self.types.add_defined_type(DefinedType::Stream(stream)))
752 }
753 wasm::ComponentDefinedType::Future(ty) => {
754 let option = ty.map(|ty| self.component_val_type(ty)).transpose()?;
755 ValueType::Defined(self.types.add_defined_type(DefinedType::Future(option)))
756 }
757 wasm::ComponentDefinedType::FixedSizeList(ty, _) => {
758 let ty = self.component_val_type(*ty)?;
759 ValueType::Defined(self.types.add_defined_type(DefinedType::List(ty)))
760 }
761 };
762
763 self.cache.insert(key, Entity::Type(Type::Value(ty)));
764 Ok(ty)
765 }
766
767 fn resource(&mut self, name: &str, id: wasm::AliasableResourceId) -> ResourceId {
768 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Resource(id));
769 if let Some(ty) = self.cache.get(&key) {
770 match ty {
771 Entity::Resource(id) => return *id,
772 _ => panic!("invalid cached type"),
773 }
774 }
775
776 if let Some(resource_id) = self.resource_map.get(&id.resource()) {
778 let alias_id = self.types.add_resource(Resource {
779 name: name.to_owned(),
780 alias: Some(ResourceAlias {
781 owner: match self.find_owner(wasm::ComponentAnyTypeId::Resource(id)) {
782 Some((Owner::Interface(id), _)) => Some(*id),
783 _ => None,
784 },
785 source: *resource_id,
786 }),
787 });
788 self.cache.insert(key, Entity::Resource(alias_id));
789 return alias_id;
790 }
791
792 let resource_id = self.types.add_resource(Resource {
794 name: name.to_owned(),
795 alias: None,
796 });
797
798 self.resource_map.insert(id.resource(), resource_id);
799 self.cache.insert(key, Entity::Resource(resource_id));
800 resource_id
801 }
802
803 fn entity_type(&self, ty: wasmparser::types::EntityType) -> CoreExtern {
804 match ty {
805 wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)),
806 wasmparser::types::EntityType::Table(ty) => ty.into(),
807 wasmparser::types::EntityType::Memory(ty) => ty.into(),
808 wasmparser::types::EntityType::Global(ty) => ty.into(),
809 wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)),
810 }
811 }
812
813 fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> CoreFuncType {
814 let func_ty = self.wasm_types[ty].unwrap_func();
815 CoreFuncType {
816 params: func_ty.params().iter().copied().map(Into::into).collect(),
817 results: func_ty.results().iter().copied().map(Into::into).collect(),
818 }
819 }
820
821 fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<&(Owner, String)> {
822 let mut prev = None;
823 while prev.is_none() {
824 prev = self.owners.get(&id);
825 id = match self.wasm_types.peel_alias(id) {
826 Some(next) => next,
827 None => break,
828 };
829 }
830 prev
831 }
832}