1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.IO;
6 using System.Collections.Generic;
7 
8 using System.Reflection.Runtime.General;
9 using System.Reflection.Runtime.TypeInfos;
10 using System.Reflection.Runtime.TypeInfos.NativeFormat;
11 using System.Reflection.Runtime.Assemblies;
12 using System.Reflection.Runtime.Assemblies.NativeFormat;
13 using System.Reflection.Runtime.Dispensers;
14 using System.Reflection.Runtime.PropertyInfos;
15 
16 using Internal.Reflection.Core;
17 using Internal.Reflection.Core.Execution;
18 
19 using Internal.Metadata.NativeFormat;
20 
21 //=================================================================================================================
22 // This file collects the various chokepoints that create the various Runtime*Info objects. This allows
23 // easy reviewing of the overall caching and unification policy.
24 //
25 // The dispenser functions are defined as static members of the associated Info class. This permits us
26 // to keep the constructors private to ensure that these really are the only ways to obtain these objects.
27 //=================================================================================================================
28 
29 namespace System.Reflection.Runtime.Assemblies
30 {
31     //-----------------------------------------------------------------------------------------------------------
32     // Assemblies (maps 1-1 with a MetadataReader/ScopeDefinitionHandle.
33     //-----------------------------------------------------------------------------------------------------------
34     internal partial class RuntimeAssembly
35     {
GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly)36        static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly)
37         {
38             if (bindResult.Reader != null)
39                 runtimeAssembly = NativeFormatRuntimeAssembly.GetRuntimeAssembly(bindResult.Reader, bindResult.ScopeDefinitionHandle, bindResult.OverflowScopes);
40         }
41     }
42 }
43 
44 namespace System.Reflection.Runtime.Assemblies.NativeFormat
45 {
46     internal sealed partial class NativeFormatRuntimeAssembly
47     {
GetRuntimeAssembly(MetadataReader reader, ScopeDefinitionHandle scope, IEnumerable<QScopeDefinition> overflowScopes)48         internal static RuntimeAssembly GetRuntimeAssembly(MetadataReader reader, ScopeDefinitionHandle scope, IEnumerable<QScopeDefinition> overflowScopes)
49         {
50             return s_scopeToAssemblyDispenser.GetOrAdd(new RuntimeAssemblyKey(reader, scope, overflowScopes));
51         }
52 
53         private static readonly Dispenser<RuntimeAssemblyKey, RuntimeAssembly> s_scopeToAssemblyDispenser =
54             DispenserFactory.CreateDispenserV<RuntimeAssemblyKey, RuntimeAssembly>(
55                 DispenserScenario.Scope_Assembly,
56                 delegate (RuntimeAssemblyKey qScopeDefinition)
57                 {
58                     return (RuntimeAssembly)new NativeFormat.NativeFormatRuntimeAssembly(qScopeDefinition.Reader, qScopeDefinition.Handle, qScopeDefinition.Overflows);
59                 }
60         );
61 
62         //-----------------------------------------------------------------------------------------------------------
63         // Captures a qualified scope (a reader plus a handle) representing the canonical definition of an assembly,
64         // plus a set of "overflow" scopes representing additional pieces of the assembly.
65         //-----------------------------------------------------------------------------------------------------------
66         private struct RuntimeAssemblyKey : IEquatable<RuntimeAssemblyKey>
67         {
RuntimeAssemblyKeySystem.Reflection.Runtime.Assemblies.NativeFormat.NativeFormatRuntimeAssembly.RuntimeAssemblyKey68             public RuntimeAssemblyKey(MetadataReader reader, ScopeDefinitionHandle handle, IEnumerable<QScopeDefinition> overflows)
69             {
70                 _reader = reader;
71                 _handle = handle;
72                 _overflows = overflows;
73             }
74 
75             public MetadataReader Reader { get { return _reader; } }
76             public ScopeDefinitionHandle Handle { get { return _handle; } }
77             public IEnumerable<QScopeDefinition> Overflows { get { return _overflows; } }
78             public ScopeDefinition ScopeDefinition
79             {
80                 get
81                 {
82                     return _handle.GetScopeDefinition(_reader);
83                 }
84             }
85 
EqualsSystem.Reflection.Runtime.Assemblies.NativeFormat.NativeFormatRuntimeAssembly.RuntimeAssemblyKey86             public override bool Equals(Object obj)
87             {
88                 if (!(obj is RuntimeAssemblyKey other))
89                     return false;
90                 return Equals(other);
91             }
92 
93 
EqualsSystem.Reflection.Runtime.Assemblies.NativeFormat.NativeFormatRuntimeAssembly.RuntimeAssemblyKey94             public bool Equals(RuntimeAssemblyKey other)
95             {
96                 // Equality depends only on the canonical definition of an assembly, not
97                 // the overflows.
98                 if (!(_reader == other._reader))
99                     return false;
100                 if (!(_handle.Equals(other._handle)))
101                     return false;
102                 return true;
103             }
104 
GetHashCodeSystem.Reflection.Runtime.Assemblies.NativeFormat.NativeFormatRuntimeAssembly.RuntimeAssemblyKey105             public override int GetHashCode()
106             {
107                 return _handle.GetHashCode();
108             }
109 
110             private readonly MetadataReader _reader;
111             private readonly ScopeDefinitionHandle _handle;
112             private readonly IEnumerable<QScopeDefinition> _overflows;
113         }
114     }
115 }
116 
117 namespace System.Reflection.Runtime.FieldInfos.NativeFormat
118 {
119     //-----------------------------------------------------------------------------------------------------------
120     // FieldInfos
121     //-----------------------------------------------------------------------------------------------------------
122     internal sealed partial class NativeFormatRuntimeFieldInfo
123     {
GetRuntimeFieldInfo(FieldHandle fieldHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)124         internal static RuntimeFieldInfo GetRuntimeFieldInfo(FieldHandle fieldHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)
125         {
126             return new NativeFormatRuntimeFieldInfo(fieldHandle, definingTypeInfo, contextTypeInfo, reflectedType).WithDebugName();
127         }
128     }
129 }
130 
131 namespace System.Reflection.Runtime.PropertyInfos.NativeFormat
132 {
133     //-----------------------------------------------------------------------------------------------------------
134     // PropertyInfos
135     //-----------------------------------------------------------------------------------------------------------
136     internal sealed partial class NativeFormatRuntimePropertyInfo
137     {
GetRuntimePropertyInfo(PropertyHandle propertyHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)138         internal static RuntimePropertyInfo GetRuntimePropertyInfo(PropertyHandle propertyHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)
139         {
140             return new NativeFormatRuntimePropertyInfo(propertyHandle, definingTypeInfo, contextTypeInfo, reflectedType).WithDebugName();
141         }
142     }
143 }
144 
145 namespace System.Reflection.Runtime.EventInfos.NativeFormat
146 {
147     //-----------------------------------------------------------------------------------------------------------
148     // EventInfos
149     //-----------------------------------------------------------------------------------------------------------
150     internal sealed partial class NativeFormatRuntimeEventInfo
151     {
GetRuntimeEventInfo(EventHandle eventHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)152         internal static RuntimeEventInfo GetRuntimeEventInfo(EventHandle eventHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)
153         {
154             return new NativeFormatRuntimeEventInfo(eventHandle, definingTypeInfo, contextTypeInfo, reflectedType).WithDebugName();
155         }
156     }
157 }
158 
159 namespace System.Reflection.Runtime.Modules.NativeFormat
160 {
161     //-----------------------------------------------------------------------------------------------------------
162     // Modules (these exist only because Modules still exist in the Win8P surface area. There is a 1-1
163     //          mapping between Assemblies and Modules.)
164     //-----------------------------------------------------------------------------------------------------------
165     internal sealed partial class NativeFormatRuntimeModule
166     {
GetRuntimeModule(NativeFormatRuntimeAssembly assembly)167         internal static RuntimeModule GetRuntimeModule(NativeFormatRuntimeAssembly assembly)
168         {
169             return new NativeFormatRuntimeModule(assembly);
170         }
171     }
172 }
173 
174 namespace System.Reflection.Runtime.ParameterInfos.NativeFormat
175 {
176     //-----------------------------------------------------------------------------------------------------------
177     // ParameterInfos for MethodBase objects with Parameter metadata.
178     //-----------------------------------------------------------------------------------------------------------
179     internal sealed partial class NativeFormatMethodParameterInfo
180     {
GetNativeFormatMethodParameterInfo(MethodBase member, MethodHandle methodHandle, int position, ParameterHandle parameterHandle, QSignatureTypeHandle qualifiedParameterType, TypeContext typeContext)181         internal static NativeFormatMethodParameterInfo GetNativeFormatMethodParameterInfo(MethodBase member, MethodHandle methodHandle, int position, ParameterHandle parameterHandle, QSignatureTypeHandle qualifiedParameterType, TypeContext typeContext)
182         {
183             return new NativeFormatMethodParameterInfo(member, methodHandle, position, parameterHandle, qualifiedParameterType, typeContext);
184         }
185     }
186 }
187 
188 namespace System.Reflection.Runtime.CustomAttributes
189 {
190     using NativeFormat;
191 
192     //-----------------------------------------------------------------------------------------------------------
193     // CustomAttributeData objects returned by various CustomAttributes properties.
194     //-----------------------------------------------------------------------------------------------------------
195     internal abstract partial class RuntimeCustomAttributeData
196     {
GetCustomAttributes(MetadataReader reader, CustomAttributeHandleCollection customAttributeHandles)197         internal static IEnumerable<CustomAttributeData> GetCustomAttributes(MetadataReader reader, CustomAttributeHandleCollection customAttributeHandles)
198         {
199             foreach (CustomAttributeHandle customAttributeHandle in customAttributeHandles)
200                 yield return GetCustomAttributeData(reader, customAttributeHandle);
201         }
202 
GetCustomAttributeData(MetadataReader reader, CustomAttributeHandle customAttributeHandle)203         private static CustomAttributeData GetCustomAttributeData(MetadataReader reader, CustomAttributeHandle customAttributeHandle)
204         {
205             return new NativeFormatCustomAttributeData(reader, customAttributeHandle);
206         }
207     }
208 }
209