22// The .NET Foundation licenses this file to you under the MIT license.
33
44using System ;
5+ using System . Collections . Generic ;
56
67using Internal . Metadata . NativeFormat . Writer ;
78
@@ -18,6 +19,10 @@ namespace ILCompiler.Metadata
1819{
1920 partial class Transform < TPolicy >
2021 {
22+ private EntityMap < ForwarderKey , TypeForwarder > _forwarders = new EntityMap < ForwarderKey , TypeForwarder > ( EqualityComparer < ForwarderKey > . Default ) ;
23+
24+ private Action < ForwarderKey , TypeForwarder > _initForwarder ;
25+
2126 private void HandleTypeForwarders ( Cts . Ecma . EcmaModule module )
2227 {
2328 foreach ( var exportedTypeHandle in module . MetadataReader . ExportedTypes )
@@ -30,7 +35,7 @@ private void HandleTypeForwarders(Cts.Ecma.EcmaModule module)
3035 Ecma . ExportedType exportedType = module . MetadataReader . GetExportedType ( exportedTypeHandle ) ;
3136 if ( exportedType . IsForwarder || exportedType . Implementation . Kind == Ecma . HandleKind . ExportedType )
3237 {
33- HandleTypeForwarder ( module , exportedType ) ;
38+ HandleTypeForwarder ( module , exportedTypeHandle ) ;
3439 }
3540 else
3641 {
@@ -39,11 +44,18 @@ private void HandleTypeForwarders(Cts.Ecma.EcmaModule module)
3944 }
4045 }
4146
42- private TypeForwarder HandleTypeForwarder ( Cts . Ecma . EcmaModule module , Ecma . ExportedType exportedType )
47+ private TypeForwarder HandleTypeForwarder ( Cts . Ecma . EcmaModule module , Ecma . ExportedTypeHandle handle )
48+ {
49+ return _forwarders . GetOrCreate ( new ForwarderKey ( module , handle ) , _initForwarder ?? ( _initForwarder = InitializeTypeForwarder ) ) ;
50+ }
51+
52+ private void InitializeTypeForwarder ( ForwarderKey key , TypeForwarder record )
4353 {
54+ Cts . Ecma . EcmaModule module = key . Module ;
4455 Ecma . MetadataReader reader = module . MetadataReader ;
45- string name = reader . GetString ( exportedType . Name ) ;
46- TypeForwarder result ;
56+ Ecma . ExportedType exportedType = reader . GetExportedType ( key . ExportedType ) ;
57+
58+ record . Name = HandleString ( reader . GetString ( exportedType . Name ) ) ;
4759
4860 switch ( exportedType . Implementation . Kind )
4961 {
@@ -67,35 +79,36 @@ private TypeForwarder HandleTypeForwarder(Cts.Ecma.EcmaModule module, Ecma.Expor
6779 else
6880 refName . SetPublicKeyToken ( reader . GetBlobBytes ( assemblyRef . PublicKeyOrToken ) ) ;
6981
70- result = new TypeForwarder
71- {
72- Name = HandleString ( name ) ,
73- Scope = HandleScopeReference ( refName ) ,
74- } ;
82+ record . Scope = HandleScopeReference ( refName ) ;
7583
76- namespaceDefinition . TypeForwarders . Add ( result ) ;
84+ namespaceDefinition . TypeForwarders . Add ( record ) ;
7785 }
7886 break ;
7987
8088 case Ecma . HandleKind . ExportedType :
8189 {
82- TypeForwarder scope = HandleTypeForwarder ( module , reader . GetExportedType ( ( Ecma . ExportedTypeHandle ) exportedType . Implementation ) ) ;
90+ TypeForwarder scope = HandleTypeForwarder ( module , ( Ecma . ExportedTypeHandle ) exportedType . Implementation ) ;
8391
84- result = new TypeForwarder
85- {
86- Name = HandleString ( name ) ,
87- Scope = scope . Scope ,
88- } ;
92+ record . Scope = scope . Scope ;
8993
90- scope . NestedTypes . Add ( result ) ;
94+ scope . NestedTypes . Add ( record ) ;
9195 }
9296 break ;
9397
9498 default :
9599 throw new BadImageFormatException ( ) ;
96100 }
101+ }
102+
103+ private readonly struct ForwarderKey : IEquatable < ForwarderKey >
104+ {
105+ public readonly Cts . Ecma . EcmaModule Module ;
106+ public readonly Ecma . ExportedTypeHandle ExportedType ;
107+ public ForwarderKey ( Cts . Ecma . EcmaModule module , Ecma . ExportedTypeHandle exportedType )
108+ => ( Module , ExportedType ) = ( module , exportedType ) ;
97109
98- return result ;
110+ public bool Equals ( ForwarderKey other ) => Module == other . Module && ExportedType == other . ExportedType ;
111+ public override int GetHashCode ( ) => HashCode . Combine ( Module . GetHashCode ( ) , ExportedType . GetHashCode ( ) ) ;
99112 }
100113 }
101114}
0 commit comments