private RuntimeTypeHandle GetTypeDefinition(RuntimeTypeHandle typeHandle) { if (RuntimeAugments.IsGenericType(typeHandle)) { return(RuntimeAugments.GetGenericDefinition(typeHandle)); } return(typeHandle); }
public sealed override MethodBase GetMethodBaseFromStartAddressIfAvailable(IntPtr methodStartAddress) { RuntimeTypeHandle declaringTypeHandle = default(RuntimeTypeHandle); QMethodDefinition methodHandle; RuntimeTypeHandle[] genericMethodTypeArgumentHandles; if (!ReflectionExecution.ExecutionEnvironment.TryGetMethodForOriginalLdFtnResult(methodStartAddress, ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles)) { return(null); } if (RuntimeAugments.IsGenericType(declaringTypeHandle)) { declaringTypeHandle = RuntimeAugments.GetGenericDefinition(declaringTypeHandle); } // We don't use the type argument handles as we want the uninstantiated method info return(ReflectionCoreExecution.ExecutionDomain.GetMethod(declaringTypeHandle, methodHandle, genericMethodTypeArgumentHandles: null)); }
public static bool TryGetMethodMetadataFromStartAddress(IntPtr methodStartAddress, out MetadataReader reader, out TypeDefinitionHandle typeHandle, out MethodHandle methodHandle) { reader = null; typeHandle = default(TypeDefinitionHandle); methodHandle = default(MethodHandle); RuntimeTypeHandle declaringTypeHandle = default(RuntimeTypeHandle); if (!ExecutionEnvironment.TryGetMethodForOriginalLdFtnResult(methodStartAddress, ref declaringTypeHandle, out QMethodDefinition qMethodDefinition, out _)) { return(false); } if (!qMethodDefinition.IsNativeFormatMetadataBased) { return(false); } if (RuntimeAugments.IsGenericType(declaringTypeHandle)) { declaringTypeHandle = RuntimeAugments.GetGenericDefinition(declaringTypeHandle); } if (!ExecutionEnvironment.TryGetMetadataForNamedType(declaringTypeHandle, out QTypeDefinition qTypeDefinition)) { return(false); } Debug.Assert(qTypeDefinition.IsNativeFormatMetadataBased); Debug.Assert(qTypeDefinition.NativeFormatReader == qMethodDefinition.NativeFormatReader); reader = qTypeDefinition.NativeFormatReader; typeHandle = qTypeDefinition.NativeFormatHandle; methodHandle = qMethodDefinition.NativeFormatHandle; return(true); }
internal override bool MatchParsedEntry(RuntimeTypeHandle tentativeType) { RuntimeTypeHandle parsedTypeDefinitionHandle = RuntimeAugments.GetGenericDefinition(tentativeType); if (!parsedTypeDefinitionHandle.Equals(_genericTypeDefinitionHandle)) { return(false); } int lookupArity = (_typeToLookup != null ? _typeToLookup.Instantiation.Length : _genericTypeArgumentHandles.Length); for (int i = 0; i < lookupArity; i++) { RuntimeTypeHandle parsedArg = RuntimeAugments.GetGenericArgument(tentativeType, i); RuntimeTypeHandle lookupArg = (_typeToLookup != null ? _typeToLookup.Instantiation[i].RuntimeTypeHandle : _genericTypeArgumentHandles[i]); if (!parsedArg.Equals(lookupArg)) { return(false); } } return(true); }
public sealed override EnumInfo GetEnumInfo(RuntimeTypeHandle typeHandle) { // Handle the weird case of an enum type nested under a generic type that makes the // enum itself generic RuntimeTypeHandle typeDefHandle = typeHandle; if (RuntimeAugments.IsGenericType(typeHandle)) { typeDefHandle = RuntimeAugments.GetGenericDefinition(typeHandle); } // If the type is reflection blocked, we pretend there are no enum values defined if (ReflectionExecution.ExecutionEnvironment.IsReflectionBlocked(typeDefHandle)) { return(new EnumInfo(RuntimeAugments.GetEnumUnderlyingType(typeHandle), Array.Empty <object>(), Array.Empty <string>(), false)); } QTypeDefinition qTypeDefinition; if (!ReflectionExecution.ExecutionEnvironment.TryGetMetadataForNamedType(typeDefHandle, out qTypeDefinition)) { throw ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(Type.GetTypeFromHandle(typeDefHandle)); } if (qTypeDefinition.IsNativeFormatMetadataBased) { return(NativeFormatEnumInfo.Create(typeHandle, qTypeDefinition.NativeFormatReader, qTypeDefinition.NativeFormatHandle)); } #if ECMA_METADATA_SUPPORT if (qTypeDefinition.IsEcmaFormatMetadataBased) { return(EcmaFormatEnumInfo.Create(typeHandle, qTypeDefinition.EcmaFormatReader, qTypeDefinition.EcmaFormatHandle)); } #endif return(null); }
private bool FindMatchingInterfaceSlot(NativeFormatModuleInfo module, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle instanceTypeHandle, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch, bool defaultMethods) { uint numTargetImplementations = entryParser.GetUnsigned(); #if GVM_RESOLUTION_TRACE Debug.WriteLine(" :: Declaring type = " + GetTypeNameDebug(declaringType)); Debug.WriteLine(" :: Target type = " + GetTypeNameDebug(openTargetTypeHandle)); #endif for (uint j = 0; j < numTargetImplementations; j++) { uint nameAndSigToken = entryParser.GetUnsigned(); MethodNameAndSignature targetMethodNameAndSignature = null; RuntimeTypeHandle targetTypeHandle = default; bool isDefaultInterfaceMethodImplementation; if (nameAndSigToken != SpecialGVMInterfaceEntry.Diamond && nameAndSigToken != SpecialGVMInterfaceEntry.Reabstraction) { targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, module.Handle, nameAndSigToken); targetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); isDefaultInterfaceMethodImplementation = RuntimeAugments.IsInterface(targetTypeHandle); #if GVM_RESOLUTION_TRACE Debug.WriteLine(" Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle)); #endif } else { isDefaultInterfaceMethodImplementation = true; } uint numIfaceImpls = entryParser.GetUnsigned(); for (uint k = 0; k < numIfaceImpls; k++) { RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); #if GVM_RESOLUTION_TRACE Debug.WriteLine(" -> Current implementing type = " + GetTypeNameDebug(implementingTypeHandle)); #endif uint numIfaceSigs = entryParser.GetUnsigned(); if (!openTargetTypeHandle.Equals(implementingTypeHandle) || defaultMethods != isDefaultInterfaceMethodImplementation) { // Skip over signatures data for (uint l = 0; l < numIfaceSigs; l++) { entryParser.GetUnsigned(); } continue; } for (uint l = 0; l < numIfaceSigs; l++) { RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle); NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, entryParser.GetUnsigned()); if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(ref ifaceSigParser, module.Handle, targetTypeInstantiation, null, out currentIfaceTypeHandle)) { #if GVM_RESOLUTION_TRACE Debug.WriteLine(" -> Current interface on type = " + GetTypeNameDebug(currentIfaceTypeHandle)); #endif Debug.Assert(!currentIfaceTypeHandle.IsNull()); if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) || (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle))) { #if GVM_RESOLUTION_TRACE Debug.WriteLine(" " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!"); #endif if (targetMethodNameAndSignature == null) { if (nameAndSigToken == SpecialGVMInterfaceEntry.Diamond) { throw new AmbiguousImplementationException(); } else { Debug.Assert(nameAndSigToken == SpecialGVMInterfaceEntry.Reabstraction); throw new EntryPointNotFoundException(); } } // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller if (!RuntimeAugments.IsInterface(targetTypeHandle) || !RuntimeAugments.IsGenericTypeDefinition(targetTypeHandle)) { // Not a default interface method or default interface method on a non-generic type. // We have a usable type handle. declaringType = targetTypeHandle; } else if (RuntimeAugments.IsGenericType(currentIfaceTypeHandle) && RuntimeAugments.GetGenericDefinition(currentIfaceTypeHandle).Equals(targetTypeHandle)) { // Default interface method implemented on the same type that declared the slot. // Use the instantiation as-is from what we found. declaringType = currentIfaceTypeHandle; } else { declaringType = default; // Default interface method implemented on a different generic interface. // We need to find a usable instantiation. There should be only one match because we // would be dealing with a diamond otherwise. int numInstanceInterfaces = RuntimeAugments.GetInterfaceCount(instanceTypeHandle); for (int instIntfIndex = 0; instIntfIndex < numInstanceInterfaces; instIntfIndex++) { RuntimeTypeHandle instIntf = RuntimeAugments.GetInterface(instanceTypeHandle, instIntfIndex); if (RuntimeAugments.IsGenericType(instIntf) && RuntimeAugments.GetGenericDefinition(instIntf).Equals(targetTypeHandle)) { // Got a potential interface. Check if the implementing interface is in the interface // list. We don't want IsAssignableFrom because we need an exact match. int numIntInterfaces = RuntimeAugments.GetInterfaceCount(instIntf); for (int intIntfIndex = 0; intIntfIndex < numIntInterfaces; intIntfIndex++) { if (RuntimeAugments.GetInterface(instIntf, intIntfIndex).Equals(currentIfaceTypeHandle)) { Debug.Assert(declaringType.IsNull()); declaringType = instIntf; #if !DEBUG break; #endif } } #if !DEBUG if (!declaringType.IsNull()) { break; } #endif } } Debug.Assert(!declaringType.IsNull()); } methodNameAndSignature = targetMethodNameAndSignature; return(true); } } } } } return(false); }