@@ -14,6 +14,7 @@ use wasm_encoder::{
1414
1515/// A type used to abstract the API differences between a component builder,
1616/// component type, and instance type from `wasm-encoder`.
17+ #[ derive( Debug ) ]
1718enum Encodable {
1819 Builder ( ComponentBuilder ) ,
1920 Instance ( InstanceType ) ,
@@ -94,7 +95,7 @@ impl Default for Encodable {
9495 }
9596}
9697
97- #[ derive( Default ) ]
98+ #[ derive( Debug , Default ) ]
9899pub struct Scope {
99100 /// The map from types to encoded type index.
100101 pub type_indexes : IndexMap < Type , u32 > ,
@@ -108,7 +109,7 @@ pub struct Scope {
108109 encodable : Encodable ,
109110}
110111
111- #[ derive( Default ) ]
112+ #[ derive( Debug , Default ) ]
112113pub struct State {
113114 /// The stack of encoding scopes.
114115 scopes : Vec < Scope > ,
@@ -630,7 +631,8 @@ impl<'a> TypeEncoder<'a> {
630631
631632 fn import ( & self , state : & mut State , name : & str , kind : ItemKind ) {
632633 if let ItemKind :: Type ( Type :: Resource ( id) ) = kind {
633- return self . import_resource ( state, name, id) ;
634+ self . import_resource ( state, name, id) ;
635+ return ;
634636 }
635637
636638 log:: debug!( "encoding {kind} import `{name}`" , kind = kind. desc( self . 0 ) ) ;
@@ -669,9 +671,9 @@ impl<'a> TypeEncoder<'a> {
669671 }
670672 }
671673
672- fn import_resource ( & self , state : & mut State , name : & str , id : ResourceId ) {
673- if state. current . resources . contains_key ( name) {
674- return ;
674+ pub fn import_resource ( & self , state : & mut State , name : & str , id : ResourceId ) -> u32 {
675+ if let Some ( index ) = state. current . resources . get ( name) {
676+ return * index ;
675677 }
676678
677679 log:: debug!( "encoding import of resource `{name}`" ) ;
@@ -687,17 +689,43 @@ impl<'a> TypeEncoder<'a> {
687689
688690 log:: debug!( "encoded outer alias for resource `{name}` to type index {index}" ) ;
689691 index
690- } else if let Some ( alias_of) = resource. alias_of {
691- // This is an alias to another resource at the same scope
692- let orig =
693- state. current . resources [ self . 0 [ self . 0 . resolve_resource ( alias_of) ] . name . as_str ( ) ] ;
692+ } else if let Some ( alias) = resource. alias {
693+ let source = self . 0 . resolve_resource ( alias. source ) ;
694+ let source_index = if let Some ( index) =
695+ state. current . resources . get ( self . 0 [ source] . name . as_str ( ) )
696+ {
697+ // The source resource was previously imported
698+ * index
699+ } else if let Some ( index) = state. current . type_indexes . get ( & Type :: Resource ( source) ) {
700+ // The source resource isn't directly imported, but was previously aliased
701+ * index
702+ } else {
703+ // Otherwise, we need to alias the source resource
704+ // This should only occur for resources owned by interfaces
705+ let source_index = state. current . encodable . type_count ( ) ;
706+ let iid = self . 0 [ alias. owner . expect ( "should have owner" ) ]
707+ . id
708+ . as_deref ( )
709+ . expect ( "expected an interface with an id" ) ;
710+ state. current . encodable . alias ( Alias :: InstanceExport {
711+ instance : state. current . instances [ iid] ,
712+ kind : ComponentExportKind :: Type ,
713+ name : self . 0 [ source] . name . as_str ( ) ,
714+ } ) ;
715+ state
716+ . current
717+ . type_indexes
718+ . insert ( Type :: Resource ( source) , source_index) ;
719+ source_index
720+ } ;
721+
694722 let index = state. current . encodable . type_count ( ) ;
695723 state
696724 . current
697725 . encodable
698- . import_type ( name, ComponentTypeRef :: Type ( TypeBounds :: Eq ( orig ) ) ) ;
726+ . import_type ( name, ComponentTypeRef :: Type ( TypeBounds :: Eq ( source_index ) ) ) ;
699727
700- log:: debug!( "encoded import for resource `{name}` as type index {index} (alias of type index {orig })" ) ;
728+ log:: debug!( "encoded import for resource `{name}` as type index {index} (alias of type index {source_index })" ) ;
701729 index
702730 } else {
703731 // Otherwise, this is a new resource type, import with a subtype bounds
@@ -712,6 +740,7 @@ impl<'a> TypeEncoder<'a> {
712740 } ;
713741
714742 state. current . resources . insert ( resource. name . clone ( ) , index) ;
743+ index
715744 }
716745
717746 fn export ( & self , state : & mut State , name : & str , kind : ItemKind ) -> u32 {
@@ -759,10 +788,10 @@ impl<'a> TypeEncoder<'a> {
759788 Self :: export_type ( state, name, ComponentTypeRef :: Type ( TypeBounds :: Eq ( outer) ) ) ;
760789 log:: debug!( "encoded outer alias for resource `{name}` as type index {index}" ) ;
761790 index
762- } else if let Some ( alias_of ) = resource. alias_of {
791+ } else if let Some ( alias ) = resource. alias {
763792 // This is an alias to another resource at the same scope
764- let index =
765- state . current . resources [ self . 0 [ self . 0 . resolve_resource ( alias_of ) ] . name . as_str ( ) ] ;
793+ let index = state . current . resources
794+ [ self . 0 [ self . 0 . resolve_resource ( alias . source ) ] . name . as_str ( ) ] ;
766795 let index =
767796 Self :: export_type ( state, name, ComponentTypeRef :: Type ( TypeBounds :: Eq ( index) ) ) ;
768797 log:: debug!( "encoded alias for resource `{name}` as type index {index}" ) ;
0 commit comments