public Type GetConstructedGenericTypeForHandle(RuntimeTypeHandle typeHandle) { RuntimeTypeHandle genericTypeDefinitionHandle; RuntimeTypeHandle[] genericTypeArgumentHandles; genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(typeHandle, out genericTypeArgumentHandles); // Reflection blocked constructed generic types simply pretend to not be generic // This is reasonable, as the behavior of reflection blocked types is supposed // to be that they expose the minimal information about a type that is necessary // for users of Object.GetType to move from that type to a type that isn't // reflection blocked. By not revealing that reflection blocked types are generic // we are making it appear as if implementation detail types exposed to user code // are all non-generic, which is theoretically possible, and by doing so // we avoid (in all known circumstances) the very complicated case of representing // the interfaces, base types, and generic parameter types of reflection blocked // generic type definitions. if (ExecutionEnvironment.IsReflectionBlocked(genericTypeDefinitionHandle)) { return RuntimeBlockedTypeInfo.GetRuntimeBlockedTypeInfo(typeHandle, isGenericTypeDefinition: false); } RuntimeTypeInfo genericTypeDefinition = genericTypeDefinitionHandle.GetTypeForRuntimeTypeHandle(); int count = genericTypeArgumentHandles.Length; RuntimeTypeInfo[] genericTypeArguments = new RuntimeTypeInfo[count]; for (int i = 0; i < count; i++) { genericTypeArguments[i] = genericTypeArgumentHandles[i].GetTypeForRuntimeTypeHandle(); } return genericTypeDefinition.GetConstructedGenericType(genericTypeArguments, typeHandle); }
private RuntimeTypeHandle GetOpenTypeDefinition(RuntimeTypeHandle typeHandle, out RuntimeTypeHandle[] typeArgumentsHandles) { if (RuntimeAugments.IsGenericType(typeHandle)) { return(RuntimeAugments.GetGenericInstantiation(typeHandle, out typeArgumentsHandles)); } typeArgumentsHandles = null; return(typeHandle); }
public CanonicallyEquivalentEntryLocator(RuntimeTypeHandle typeToFind, CanonicalFormKind kind) { if (RuntimeAugments.IsGenericType(typeToFind)) { _genericDefinition = RuntimeAugments.GetGenericInstantiation(typeToFind, out _genericArgs); } else { _genericArgs = null; _genericDefinition = default(RuntimeTypeHandle); } _typeToFind = typeToFind; _canonKind = kind; _defType = null; }
internal override bool MatchParsedEntry(RuntimeTypeHandle tentativeType) { // // Entries read from the hashtable are loaded as DefTypes, and compared to the input. // This lookup is slower than the lookups using RuntimeTypeHandles, but can handle cases where we don't have // RuntimeTypeHandle values for all of the components of the input DefType, but still need to look it up in case the type // statically exists and has an existing RuntimeTypeHandle value. // TypeSystemContext context = _typeToLookup.Context; RuntimeTypeHandle[] parsedArgsHandles; RuntimeTypeHandle parsedTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(tentativeType, out parsedArgsHandles); DefType parsedTypeDefinition = (DefType)context.ResolveRuntimeTypeHandle(parsedTypeDefinitionHandle); Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(parsedArgsHandles); DefType parsedGenericType = context.ResolveGenericInstantiation(parsedTypeDefinition, parsedArgs); return(parsedGenericType == _typeToLookup); }
private static bool ImplementsIComparable(RuntimeTypeHandle t) { int interfaceCount = RuntimeAugments.GetInterfaceCount(t); for (int i = 0; i < interfaceCount; i++) { RuntimeTypeHandle interfaceType = RuntimeAugments.GetInterface(t, i); if (!RuntimeAugments.IsGenericType(interfaceType)) { continue; } RuntimeTypeHandle genericDefinition; RuntimeTypeHandle[] genericTypeArgs; genericDefinition = RuntimeAugments.GetGenericInstantiation(interfaceType, out genericTypeArgs); if (genericDefinition.Equals(typeof(IComparable <>).TypeHandle)) { if (genericTypeArgs.Length != 1) { continue; } if (RuntimeAugments.IsValueType(t)) { if (genericTypeArgs[0].Equals(t)) { return(true); } } else if (RuntimeAugments.IsAssignableFrom(genericTypeArgs[0], t)) { return(true); } } } return(false); }
private string GetTypeNameDebug(RuntimeTypeHandle rtth) { string result; if (RuntimeAugments.IsGenericType(rtth)) { RuntimeTypeHandle[] typeArgumentsHandles; RuntimeTypeHandle openTypeDef = RuntimeAugments.GetGenericInstantiation(rtth, out typeArgumentsHandles);; result = GetTypeNameDebug(openTypeDef) + "<"; for (int i = 0; i < typeArgumentsHandles.Length; i++) { result += (i == 0 ? "" : ",") + GetTypeNameDebug(typeArgumentsHandles[i]); } return(result + ">"); } else { System.Reflection.Runtime.General.QTypeDefinition qTypeDefinition; // Check if we have metadata. if (Instance.TryGetMetadataForNamedType(rtth, out qTypeDefinition)) { return(qTypeDefinition.NativeFormatHandle.GetFullName(qTypeDefinition.NativeFormatReader)); } } result = "EEType:0x"; ulong num = (ulong)RuntimeAugments.GetPointerFromTypeHandle(rtth); int shift = IntPtr.Size * 8; const string HexDigits = "0123456789ABCDEF"; while (shift > 0) { shift -= 4; int digit = (int)((num >> shift) & 0xF); result += HexDigits[digit]; } return(result); }
public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth) { TypeDesc returnedType; if (_runtimeTypeHandleResolutionCache.TryGetValue(rtth, out returnedType)) { return(returnedType); } if (rtth.Equals(CanonType.RuntimeTypeHandle)) { returnedType = CanonType; } else if (rtth.Equals(UniversalCanonType.RuntimeTypeHandle)) { returnedType = UniversalCanonType; } else if (RuntimeAugments.IsGenericTypeDefinition(rtth)) { returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth); if (returnedType == null) { unsafe { TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericArgumentCount]; for (int i = 0; i < genericParameters.Length; i++) { genericParameters[i] = GetSignatureVariable(i, false); } returnedType = new NoMetadataType(this, rtth, null, new Instantiation(genericParameters), rtth.GetHashCode()); } } } else if (RuntimeAugments.IsGenericType(rtth)) { RuntimeTypeHandle typeDefRuntimeTypeHandle; RuntimeTypeHandle[] genericArgRuntimeTypeHandles; typeDefRuntimeTypeHandle = RuntimeAugments.GetGenericInstantiation(rtth, out genericArgRuntimeTypeHandles); DefType typeDef = (DefType)ResolveRuntimeTypeHandle(typeDefRuntimeTypeHandle); Instantiation genericArgs = ResolveRuntimeTypeHandles(genericArgRuntimeTypeHandles); returnedType = ResolveGenericInstantiation(typeDef, genericArgs); } else if (RuntimeAugments.IsArrayType(rtth)) { RuntimeTypeHandle elementTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth); TypeDesc elementType = ResolveRuntimeTypeHandle(elementTypeHandle); unsafe { if (rtth.ToEETypePtr()->IsSzArray) { returnedType = GetArrayType(elementType); } else { returnedType = GetArrayType(elementType, rtth.ToEETypePtr()->ArrayRank); } } } else if (RuntimeAugments.IsUnmanagedPointerType(rtth)) { RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth); TypeDesc targetType = ResolveRuntimeTypeHandle(targetTypeHandle); returnedType = GetPointerType(targetType); } else if (RuntimeAugments.IsByRefType(rtth)) { RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth); TypeDesc targetType = ResolveRuntimeTypeHandle(targetTypeHandle); returnedType = GetByRefType(targetType); } else { returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth); if (returnedType == null) { returnedType = new NoMetadataType(this, rtth, null, Instantiation.Empty, rtth.GetHashCode()); } } // We either retrieved an existing DefType that is already registered with the runtime // or one that is not associated with an MethodTable yet. If it's not associated, associate it. if (returnedType.RuntimeTypeHandle.IsNull()) { TypeBuilderState state = returnedType.GetTypeBuilderStateIfExist(); bool skipStoringRuntimeTypeHandle = false; // If we've already attempted to lookup and failed to retrieve this type handle, we // may have already decided to create a new one. In that case, do not attempt to abort // that creation process as it may have already begun the process of type creation if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle) { skipStoringRuntimeTypeHandle = true; } if (!skipStoringRuntimeTypeHandle) { returnedType.SetRuntimeTypeHandleUnsafe(rtth); } } _runtimeTypeHandleResolutionCache.Add(rtth, returnedType); return(returnedType.WithDebugName()); }
public bool TryGetConstructedGenericTypeComponents(RuntimeTypeHandle runtimeTypeHandle, out RuntimeTypeHandle genericTypeDefinitionHandle, out RuntimeTypeHandle[] genericTypeArgumentHandles) { genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(runtimeTypeHandle, out genericTypeArgumentHandles); return(true); }
// This method computes the method pointer and dictionary pointer for a GVM. // Inputs: // - targetTypeHanlde: target type on which the GVM is implemented // - nameAndSignature: name and signature of the GVM method // - genericMethodArgumentHandles: GVM instantiation arguments // Outputs: // - methodPointer: pointer to the GVM's implementation // - dictionaryPointer: (if applicable) pointer to the dictionary to be used with the GVM call public bool TryGetGenericVirtualMethodPointer(RuntimeTypeHandle targetTypeHandle, MethodNameAndSignature nameAndSignature, RuntimeTypeHandle[] genericMethodArgumentHandles, out IntPtr methodPointer, out IntPtr dictionaryPointer) { methodPointer = dictionaryPointer = IntPtr.Zero; TypeSystemContext context = TypeSystemContextFactory.Create(); DefType targetType = (DefType)context.ResolveRuntimeTypeHandle(targetTypeHandle); Instantiation methodInstantiation = context.ResolveRuntimeTypeHandles(genericMethodArgumentHandles); InstantiatedMethod method = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, targetType, nameAndSignature, methodInstantiation, IntPtr.Zero, false); if (!method.CanShareNormalGenericCode()) { // First see if we can find an exact method implementation for the GVM (avoid using USG implementations if we can, // because USG code is much slower). if (TryLookupExactMethodPointerForComponents(targetTypeHandle, nameAndSignature, genericMethodArgumentHandles, out methodPointer)) { Debug.Assert(methodPointer != IntPtr.Zero); TypeSystemContextFactory.Recycle(context); return(true); } } // If we cannot find an exact method entry point, look for an equivalent template and compute the generic dictinoary TemplateLocator templateLocator = new TemplateLocator(); NativeLayoutInfo nativeLayoutInfo = new NativeLayoutInfo(); InstantiatedMethod templateMethod = templateLocator.TryGetGenericMethodTemplate(method, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token); if (templateMethod == null) { return(false); } methodPointer = templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal) ? templateMethod.UsgFunctionPointer : templateMethod.FunctionPointer; if (!TryLookupGenericMethodDictionaryForComponents(targetTypeHandle, nameAndSignature, genericMethodArgumentHandles, out dictionaryPointer)) { using (LockHolder.Hold(_typeLoaderLock)) { // Now that we hold the lock, we may find that existing types can now find // their associated RuntimeTypeHandle. Flush the type builder states as a way // to force the reresolution of RuntimeTypeHandles which couldn't be found before. context.FlushTypeBuilderStates(); if (!TypeBuilder.TryBuildGenericMethod(method, out dictionaryPointer)) { return(false); } } } Debug.Assert(methodPointer != IntPtr.Zero && dictionaryPointer != IntPtr.Zero); if (templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal)) { // Check if we need to wrap the method pointer into a calling convention converter thunk if (!TypeLoaderEnvironment.Instance.MethodSignatureHasVarsNeedingCallingConventionConverter(context, nameAndSignature.Signature)) { TypeSystemContextFactory.Recycle(context); return(true); } RuntimeTypeHandle[] typeArgs = Array.Empty <RuntimeTypeHandle>(); if (RuntimeAugments.IsGenericType(targetTypeHandle)) { RuntimeAugments.GetGenericInstantiation(targetTypeHandle, out typeArgs); } // Create a CallingConventionConverter to call the method correctly IntPtr thunkPtr = CallConverterThunk.MakeThunk( CallConverterThunk.ThunkKind.StandardToGenericInstantiating, methodPointer, nameAndSignature.Signature, dictionaryPointer, typeArgs, genericMethodArgumentHandles); Debug.Assert(thunkPtr != IntPtr.Zero); methodPointer = thunkPtr; // Set dictionaryPointer to null so we don't make a fat function pointer around the whole thing. dictionaryPointer = IntPtr.Zero; // TODO! add a new call converter thunk that will pass the instantiating arg through and use a fat function pointer. // should allow us to make fewer thunks. } TypeSystemContextFactory.Recycle(context); return(true); }
internal static String ToDisplayStringIfAvailable(this Type type, List <int> genericParameterOffsets) { RuntimeTypeHandle runtimeTypeHandle = ReflectionCoreExecution.ExecutionDomain.GetTypeHandleIfAvailable(type); bool hasRuntimeTypeHandle = !runtimeTypeHandle.Equals(default(RuntimeTypeHandle)); if (type.HasElementType) { if (type.IsArray) { // Multidim arrays. This is the one case where GetElementType() isn't pay-for-play safe so // talk to the diagnostic mapping tables directly if possible or give up. if (!hasRuntimeTypeHandle) { return(null); } int rank = type.GetArrayRank(); return(CreateArrayTypeStringIfAvailable(type.GetElementType(), rank)); } else { String s = type.GetElementType().ToDisplayStringIfAvailable(null); if (s == null) { return(null); } return(s + (type.IsPointer ? "*" : "&")); } } else if (((hasRuntimeTypeHandle && RuntimeAugments.IsGenericType(runtimeTypeHandle)) || type.IsConstructedGenericType)) { Type genericTypeDefinition; Type[] genericTypeArguments; if (hasRuntimeTypeHandle) { RuntimeTypeHandle genericTypeDefinitionHandle; RuntimeTypeHandle[] genericTypeArgumentHandles; genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(runtimeTypeHandle, out genericTypeArgumentHandles); genericTypeDefinition = Type.GetTypeFromHandle(genericTypeDefinitionHandle); genericTypeArguments = new Type[genericTypeArgumentHandles.Length]; for (int i = 0; i < genericTypeArguments.Length; i++) { genericTypeArguments[i] = Type.GetTypeFromHandle(genericTypeArgumentHandles[i]); } } else { genericTypeDefinition = type.GetGenericTypeDefinition(); genericTypeArguments = type.GenericTypeArguments; } return(CreateConstructedGenericTypeStringIfAvailable(genericTypeDefinition, genericTypeArguments)); } else if (type.IsGenericParameter) { return(type.Name); } else if (hasRuntimeTypeHandle) { String s; if (!DiagnosticMappingTables.TryGetDiagnosticStringForNamedType(runtimeTypeHandle, out s, genericParameterOffsets)) { return(null); } return(s); } else { return(null); } }
internal static string ToDisplayStringIfAvailable(this Type type, List <int> genericParameterOffsets) { RuntimeTypeHandle runtimeTypeHandle = ReflectionCoreExecution.ExecutionDomain.GetTypeHandleIfAvailable(type); bool hasRuntimeTypeHandle = !runtimeTypeHandle.Equals(default(RuntimeTypeHandle)); if (type.HasElementType) { if (type.IsArray) { // Multidim arrays. This is the one case where GetElementType() isn't pay-for-play safe so // talk to the diagnostic mapping tables directly if possible or give up. if (!hasRuntimeTypeHandle) { return(null); } int rank = type.GetArrayRank(); return(CreateArrayTypeStringIfAvailable(type.GetElementType(), rank)); } else { string s = type.GetElementType().ToDisplayStringIfAvailable(null); if (s == null) { return(null); } return(s + (type.IsPointer ? "*" : "&")); } } else if (((hasRuntimeTypeHandle && RuntimeAugments.IsGenericType(runtimeTypeHandle)) || type.IsConstructedGenericType)) { Type genericTypeDefinition; Type[] genericTypeArguments; if (hasRuntimeTypeHandle) { RuntimeTypeHandle genericTypeDefinitionHandle; RuntimeTypeHandle[] genericTypeArgumentHandles; genericTypeDefinitionHandle = RuntimeAugments.GetGenericInstantiation(runtimeTypeHandle, out genericTypeArgumentHandles); genericTypeDefinition = Type.GetTypeFromHandle(genericTypeDefinitionHandle); genericTypeArguments = new Type[genericTypeArgumentHandles.Length]; for (int i = 0; i < genericTypeArguments.Length; i++) { genericTypeArguments[i] = Type.GetTypeFromHandle(genericTypeArgumentHandles[i]); } } else { genericTypeDefinition = type.GetGenericTypeDefinition(); genericTypeArguments = type.GenericTypeArguments; } return(CreateConstructedGenericTypeStringIfAvailable(genericTypeDefinition, genericTypeArguments)); } else if (type.IsGenericParameter) { return(type.Name); } else if (hasRuntimeTypeHandle) { string s; if (!DiagnosticMappingTables.TryGetDiagnosticStringForNamedType(runtimeTypeHandle, out s, genericParameterOffsets)) { return(null); } return(s); } else { // First, see if Type.Name is available. If Type.Name is available, then we can be reasonably confident that it is safe to call Type.FullName. // We'll still wrap the call in a try-catch as a failsafe. string s = type.InternalNameIfAvailable; if (s == null) { return(null); } try { s = type.FullName; } catch (MissingMetadataException) { } // Insert commas so that CreateConstructedGenericTypeStringIfAvailable can fill the blanks. // This is not strictly correct for types nested under generic types, but at this point we're doing // best effort within reason. if (type.IsGenericTypeDefinition) { s += "["; int genericArgCount = type.GetGenericArguments().Length; while (genericArgCount-- > 0) { genericParameterOffsets.Add(s.Length); if (genericArgCount > 0) { s = s + ","; } } s += "]"; } return(s); } }