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.Assemblies; 11 using System.Reflection.Runtime.Dispensers; 12 using System.Reflection.Runtime.PropertyInfos; 13 14 using Internal.Reflection.Core; 15 using Internal.Reflection.Core.Execution; 16 17 18 //================================================================================================================= 19 // This file collects the various chokepoints that create the various Runtime*Info objects. This allows 20 // easy reviewing of the overall caching and unification policy. 21 // 22 // The dispenser functions are defined as static members of the associated Info class. This permits us 23 // to keep the constructors private to ensure that these really are the only ways to obtain these objects. 24 //================================================================================================================= 25 26 namespace System.Reflection.Runtime.Assemblies 27 { 28 //----------------------------------------------------------------------------------------------------------- 29 // Assemblies (maps 1-1 with a MetadataReader/ScopeDefinitionHandle. 30 //----------------------------------------------------------------------------------------------------------- 31 internal partial class RuntimeAssembly 32 { 33 /// <summary> 34 /// Returns non-null or throws. 35 /// </summary> GetRuntimeAssembly(RuntimeAssemblyName assemblyRefName)36 internal static RuntimeAssembly GetRuntimeAssembly(RuntimeAssemblyName assemblyRefName) 37 { 38 RuntimeAssembly result; 39 Exception assemblyLoadException = TryGetRuntimeAssembly(assemblyRefName, out result); 40 if (assemblyLoadException != null) 41 throw assemblyLoadException; 42 return result; 43 } 44 45 /// <summary> 46 /// Returns non-null or throws. 47 /// </summary> GetRuntimeAssemblyFromByteArray(byte[] rawAssembly, byte[] pdbSymbolStore)48 internal static RuntimeAssembly GetRuntimeAssemblyFromByteArray(byte[] rawAssembly, byte[] pdbSymbolStore) 49 { 50 AssemblyBinder binder = ReflectionCoreExecution.ExecutionDomain.ReflectionDomainSetup.AssemblyBinder; 51 AssemblyBindResult bindResult; 52 Exception exception; 53 if (!binder.Bind(rawAssembly, pdbSymbolStore, out bindResult, out exception)) 54 { 55 if (exception != null) 56 throw exception; 57 else 58 throw new BadImageFormatException(); 59 } 60 61 RuntimeAssembly result = GetRuntimeAssembly(bindResult); 62 return result; 63 } 64 65 /// <summary> 66 /// Returns null if no assembly matches the assemblyRefName. Throws for other error cases. 67 /// </summary> GetRuntimeAssemblyIfExists(RuntimeAssemblyName assemblyRefName)68 internal static RuntimeAssembly GetRuntimeAssemblyIfExists(RuntimeAssemblyName assemblyRefName) 69 { 70 object runtimeAssemblyOrException = s_assemblyRefNameToAssemblyDispenser.GetOrAdd(assemblyRefName); 71 if (runtimeAssemblyOrException is RuntimeAssembly runtimeAssembly) 72 return runtimeAssembly; 73 return null; 74 } 75 TryGetRuntimeAssembly(RuntimeAssemblyName assemblyRefName, out RuntimeAssembly result)76 internal static Exception TryGetRuntimeAssembly(RuntimeAssemblyName assemblyRefName, out RuntimeAssembly result) 77 { 78 object runtimeAssemblyOrException = s_assemblyRefNameToAssemblyDispenser.GetOrAdd(assemblyRefName); 79 if (runtimeAssemblyOrException is RuntimeAssembly runtimeAssembly) 80 { 81 result = runtimeAssembly; 82 return null; 83 } 84 else 85 { 86 result = null; 87 return (Exception)runtimeAssemblyOrException; 88 } 89 } 90 91 // The "object" here is either a RuntimeAssembly or an Exception. 92 private static readonly Dispenser<RuntimeAssemblyName, object> s_assemblyRefNameToAssemblyDispenser = 93 DispenserFactory.CreateDispenser<RuntimeAssemblyName, object>( 94 DispenserScenario.AssemblyRefName_Assembly, 95 delegate (RuntimeAssemblyName assemblyRefName) 96 { 97 AssemblyBinder binder = ReflectionCoreExecution.ExecutionDomain.ReflectionDomainSetup.AssemblyBinder; 98 AssemblyBindResult bindResult; 99 Exception exception; 100 if (!binder.Bind(assemblyRefName, out bindResult, out exception)) 101 return exception; 102 103 return GetRuntimeAssembly(bindResult); 104 } 105 ); 106 GetRuntimeAssembly(AssemblyBindResult bindResult)107 private static RuntimeAssembly GetRuntimeAssembly(AssemblyBindResult bindResult) 108 { 109 RuntimeAssembly result = null; 110 111 GetNativeFormatRuntimeAssembly(bindResult, ref result); 112 if (result != null) 113 return result; 114 115 GetEcmaRuntimeAssembly(bindResult, ref result); 116 if (result != null) 117 return result; 118 119 throw new PlatformNotSupportedException(); 120 } 121 122 // Use C# partial method feature to avoid complex #if logic, whichever code files are included will drive behavior GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly)123 static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly); GetEcmaRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly)124 static partial void GetEcmaRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly); 125 } 126 } 127 128 namespace System.Reflection.Runtime.MethodInfos 129 { 130 //----------------------------------------------------------------------------------------------------------- 131 // ConstructorInfos 132 //----------------------------------------------------------------------------------------------------------- 133 internal sealed partial class RuntimePlainConstructorInfo<TRuntimeMethodCommon> : RuntimeConstructorInfo 134 { GetRuntimePlainConstructorInfo(TRuntimeMethodCommon common)135 internal static RuntimePlainConstructorInfo<TRuntimeMethodCommon> GetRuntimePlainConstructorInfo(TRuntimeMethodCommon common) 136 { 137 return new RuntimePlainConstructorInfo<TRuntimeMethodCommon>(common); 138 } 139 } 140 141 //----------------------------------------------------------------------------------------------------------- 142 // Constructors for array types. 143 //----------------------------------------------------------------------------------------------------------- 144 internal sealed partial class RuntimeSyntheticConstructorInfo : RuntimeConstructorInfo 145 { GetRuntimeSyntheticConstructorInfo(SyntheticMethodId syntheticMethodId, RuntimeArrayTypeInfo declaringType, RuntimeTypeInfo[] runtimeParameterTypes, InvokerOptions options, CustomMethodInvokerAction action)146 internal static RuntimeSyntheticConstructorInfo GetRuntimeSyntheticConstructorInfo(SyntheticMethodId syntheticMethodId, RuntimeArrayTypeInfo declaringType, RuntimeTypeInfo[] runtimeParameterTypes, InvokerOptions options, CustomMethodInvokerAction action) 147 { 148 return new RuntimeSyntheticConstructorInfo(syntheticMethodId, declaringType, runtimeParameterTypes, options, action); 149 } 150 } 151 152 //----------------------------------------------------------------------------------------------------------- 153 // Nullary constructor for types manufactured by Type.GetTypeFromCLSID(). 154 //----------------------------------------------------------------------------------------------------------- 155 internal sealed partial class RuntimeCLSIDNullaryConstructorInfo : RuntimeConstructorInfo 156 { GetRuntimeCLSIDNullaryConstructorInfo(RuntimeCLSIDTypeInfo declaringType)157 internal static RuntimeCLSIDNullaryConstructorInfo GetRuntimeCLSIDNullaryConstructorInfo(RuntimeCLSIDTypeInfo declaringType) 158 { 159 return new RuntimeCLSIDNullaryConstructorInfo(declaringType); 160 } 161 } 162 163 //----------------------------------------------------------------------------------------------------------- 164 // MethodInfos for method definitions (i.e. Foo.Moo() or Foo.Moo<>() but not Foo.Moo<int>) 165 //----------------------------------------------------------------------------------------------------------- 166 internal sealed partial class RuntimeNamedMethodInfo<TRuntimeMethodCommon> 167 { GetRuntimeNamedMethodInfo(TRuntimeMethodCommon common, RuntimeTypeInfo reflectedType)168 internal static RuntimeNamedMethodInfo<TRuntimeMethodCommon> GetRuntimeNamedMethodInfo(TRuntimeMethodCommon common, RuntimeTypeInfo reflectedType) 169 { 170 RuntimeNamedMethodInfo<TRuntimeMethodCommon> method = new RuntimeNamedMethodInfo<TRuntimeMethodCommon>(common, reflectedType); 171 method.WithDebugName(); 172 return method; 173 } 174 } 175 176 //----------------------------------------------------------------------------------------------------------- 177 // MethodInfos for constructed generic methods (Foo.Moo<int> but not Foo.Moo<>) 178 //----------------------------------------------------------------------------------------------------------- 179 internal sealed partial class RuntimeConstructedGenericMethodInfo : RuntimeMethodInfo 180 { GetRuntimeConstructedGenericMethodInfo(RuntimeNamedMethodInfo genericMethodDefinition, RuntimeTypeInfo[] genericTypeArguments)181 internal static RuntimeMethodInfo GetRuntimeConstructedGenericMethodInfo(RuntimeNamedMethodInfo genericMethodDefinition, RuntimeTypeInfo[] genericTypeArguments) 182 { 183 return new RuntimeConstructedGenericMethodInfo(genericMethodDefinition, genericTypeArguments).WithDebugName(); 184 } 185 } 186 187 //----------------------------------------------------------------------------------------------------------- 188 // MethodInfos for the Get/Set methods on array types. 189 //----------------------------------------------------------------------------------------------------------- 190 internal sealed partial class RuntimeSyntheticMethodInfo : RuntimeMethodInfo 191 { GetRuntimeSyntheticMethodInfo(SyntheticMethodId syntheticMethodId, String name, RuntimeArrayTypeInfo declaringType, RuntimeTypeInfo[] runtimeParameterTypes, RuntimeTypeInfo returnType, InvokerOptions options, CustomMethodInvokerAction action)192 internal static RuntimeMethodInfo GetRuntimeSyntheticMethodInfo(SyntheticMethodId syntheticMethodId, String name, RuntimeArrayTypeInfo declaringType, RuntimeTypeInfo[] runtimeParameterTypes, RuntimeTypeInfo returnType, InvokerOptions options, CustomMethodInvokerAction action) 193 { 194 return new RuntimeSyntheticMethodInfo(syntheticMethodId, name, declaringType, runtimeParameterTypes, returnType, options, action).WithDebugName(); 195 } 196 } 197 } 198 199 namespace System.Reflection.Runtime.ParameterInfos 200 { 201 //----------------------------------------------------------------------------------------------------------- 202 // ParameterInfos for MethodBase objects with no Parameter metadata. 203 //----------------------------------------------------------------------------------------------------------- 204 internal sealed partial class RuntimeThinMethodParameterInfo : RuntimeMethodParameterInfo 205 { GetRuntimeThinMethodParameterInfo(MethodBase member, int position, QSignatureTypeHandle qualifiedParameterType, TypeContext typeContext)206 internal static RuntimeThinMethodParameterInfo GetRuntimeThinMethodParameterInfo(MethodBase member, int position, QSignatureTypeHandle qualifiedParameterType, TypeContext typeContext) 207 { 208 return new RuntimeThinMethodParameterInfo(member, position, qualifiedParameterType, typeContext); 209 } 210 } 211 212 //----------------------------------------------------------------------------------------------------------- 213 // ParameterInfos returned by PropertyInfo.GetIndexParameters() 214 //----------------------------------------------------------------------------------------------------------- 215 internal sealed partial class RuntimePropertyIndexParameterInfo : RuntimeParameterInfo 216 { GetRuntimePropertyIndexParameterInfo(RuntimePropertyInfo member, RuntimeParameterInfo backingParameter)217 internal static RuntimePropertyIndexParameterInfo GetRuntimePropertyIndexParameterInfo(RuntimePropertyInfo member, RuntimeParameterInfo backingParameter) 218 { 219 return new RuntimePropertyIndexParameterInfo(member, backingParameter); 220 } 221 } 222 223 //----------------------------------------------------------------------------------------------------------- 224 // ParameterInfos returned by Get/Set methods on array types. 225 //----------------------------------------------------------------------------------------------------------- 226 internal sealed partial class RuntimeSyntheticParameterInfo : RuntimeParameterInfo 227 { GetRuntimeSyntheticParameterInfo(MemberInfo member, int position, RuntimeTypeInfo parameterType)228 internal static RuntimeSyntheticParameterInfo GetRuntimeSyntheticParameterInfo(MemberInfo member, int position, RuntimeTypeInfo parameterType) 229 { 230 return new RuntimeSyntheticParameterInfo(member, position, parameterType); 231 } 232 } 233 } 234