diff --git a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs index e75f982abcdc23..c9418961afd9bb 100644 --- a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs +++ b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs @@ -32,7 +32,7 @@ public static DefType GetClosestDefType(this TypeDesc type) { if (!type.IsArrayTypeWithoutGenericInterfaces()) { - MetadataType arrayShadowType = type.Context.SystemModule.GetType("System", "Array`1", throwIfNotFound: false); + MetadataType arrayShadowType = type.Context.SystemModule.GetType("System", "Array`1", NotFoundBehavior.ReturnNull); if (arrayShadowType != null) { return arrayShadowType.MakeInstantiatedType(((ArrayType)type).ElementType); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs index d9d3de41634de8..dd38a715c5fe2a 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs @@ -40,5 +40,6 @@ public enum ExceptionStringID // BadImageFormatException BadImageFormatGeneric, + BadImageFormatSpecific, } } diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataTypeSystemContext.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataTypeSystemContext.cs index b578eb6ca6abcd..d8ed92df961e6f 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataTypeSystemContext.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataTypeSystemContext.cs @@ -73,7 +73,7 @@ public virtual void SetSystemModule(ModuleDesc systemModule) { // Require System.Object to be present as a minimal sanity check. // The set of required well-known types is not strictly defined since different .NET profiles implement different subsets. - MetadataType type = systemModule.GetType("System", s_wellKnownTypeNames[typeIndex], typeIndex == (int)WellKnownType.Object); + MetadataType type = systemModule.GetType("System", s_wellKnownTypeNames[typeIndex], typeIndex == (int)WellKnownType.Object ? NotFoundBehavior.Throw : NotFoundBehavior.ReturnNull); if (type != null) { type.SetWellKnownType((WellKnownType)(typeIndex + 1)); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ModuleDesc.cs b/src/coreclr/tools/Common/TypeSystem/Common/ModuleDesc.cs index c1e143dfe192cf..f2d45c1550b2d9 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ModuleDesc.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ModuleDesc.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; namespace Internal.TypeSystem @@ -28,8 +29,13 @@ public ModuleDesc(TypeSystemContext context, IAssemblyDesc assembly) /// /// Gets a type in this module with the specified name. + /// If notFoundBehavior == NotFoundBehavior.ReturnResolutionFailure + /// then ModuleDesc.GetTypeResolutionFailure will be set to the failure, and the function will return null /// - public abstract MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true); + public abstract MetadataType GetType(string nameSpace, string name, NotFoundBehavior notFoundBehavior = NotFoundBehavior.Throw); + + [ThreadStatic] + public static ResolutionFailure GetTypeResolutionFailure; /// /// Gets the global <Module> type. diff --git a/src/coreclr/tools/Common/TypeSystem/Common/NotFoundBehavior.cs b/src/coreclr/tools/Common/TypeSystem/Common/NotFoundBehavior.cs new file mode 100644 index 00000000000000..1403bb8e0863e6 --- /dev/null +++ b/src/coreclr/tools/Common/TypeSystem/Common/NotFoundBehavior.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Internal.TypeSystem +{ + public enum NotFoundBehavior + { + Throw, + ReturnNull, + ReturnResolutionFailure + } +} \ No newline at end of file diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx index b0efd67b4adc55..489fa6d1e3d9fa 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx +++ b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx @@ -180,4 +180,7 @@ The format of a DLL or executable being loaded is invalid + + The format of a DLL or executable being loaded is invalid with {0} + diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ResolutionFailure.cs b/src/coreclr/tools/Common/TypeSystem/Common/ResolutionFailure.cs new file mode 100644 index 00000000000000..04d75a5e5ae9c3 --- /dev/null +++ b/src/coreclr/tools/Common/TypeSystem/Common/ResolutionFailure.cs @@ -0,0 +1,110 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Internal.TypeSystem +{ + public sealed class ResolutionFailure + { + private enum FailureType + { + TypeLoadException1, + TypeLoadException2, + TypeLoadException3, + MissingMethodException1, + MissingFieldException1, + MissingAssemblyException1, + } + + private ResolutionFailure() { } + + private FailureType _failureType; + private string _namespace; + private string _name; + private string _moduleName; + private ModuleDesc _module; + private TypeDesc _owningType; + private MethodSignature _methodSignature; + + + public static ResolutionFailure GetTypeLoadResolutionFailure(string nestedTypeName, ModuleDesc module) + { + ResolutionFailure failure = new ResolutionFailure(); + failure._failureType = FailureType.TypeLoadException1; + failure._name = nestedTypeName; + failure._module = module; + return failure; + } + + public static ResolutionFailure GetTypeLoadResolutionFailure(string @namespace, string name, ModuleDesc module) + { + ResolutionFailure failure = new ResolutionFailure(); + failure._failureType = FailureType.TypeLoadException2; + failure._namespace = @namespace; + failure._name = name; + failure._module = module; + return failure; + } + + public static ResolutionFailure GetTypeLoadResolutionFailure(string @namespace, string name, string moduleName) + { + ResolutionFailure failure = new ResolutionFailure(); + failure._failureType = FailureType.TypeLoadException3; + failure._namespace = @namespace; + failure._name = name; + failure._moduleName = moduleName; + return failure; + } + + public static ResolutionFailure GetMissingMethodFailure(TypeDesc owningType, string methodName, MethodSignature signature) + { + ResolutionFailure failure = new ResolutionFailure(); + failure._failureType = FailureType.MissingMethodException1; + failure._methodSignature = signature; + failure._name = methodName; + failure._owningType = owningType; + return failure; + } + + public static ResolutionFailure GetMissingFieldFailure(TypeDesc owningType, string fieldName) + { + ResolutionFailure failure = new ResolutionFailure(); + failure._failureType = FailureType.MissingMethodException1; + failure._name = fieldName; + failure._owningType = owningType; + return failure; + } + + public static ResolutionFailure GetAssemblyResolutionFailure(string simpleName) + { + ResolutionFailure failure = new ResolutionFailure(); + failure._failureType = FailureType.MissingAssemblyException1; + failure._name = simpleName; + return failure; + } + + public void Throw() + { + switch(_failureType) + { + case FailureType.TypeLoadException1: + ThrowHelper.ThrowTypeLoadException(_name, _module); + break; + case FailureType.TypeLoadException2: + ThrowHelper.ThrowTypeLoadException(_namespace, _name, _module); + break; + case FailureType.TypeLoadException3: + ThrowHelper.ThrowTypeLoadException(_namespace, _name, _moduleName); + break; + case FailureType.MissingMethodException1: + ThrowHelper.ThrowMissingMethodException(_owningType, _name, _methodSignature); + break; + case FailureType.MissingFieldException1: + ThrowHelper.ThrowMissingFieldException(_owningType, _name); + break; + case FailureType.MissingAssemblyException1: + ThrowHelper.ThrowFileNotFoundException(ExceptionStringID.FileLoadErrorGeneric, _name); + break; + } + } + } +} diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs b/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs index bfe36b4cd82998..cf644ad14d4c95 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs @@ -22,6 +22,11 @@ public static void ThrowTypeLoadException(string @namespace, string name, Module ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, Format.Type(@namespace, name), Format.Module(module)); } + public static void ThrowTypeLoadException(string @namespace, string name, string moduleName) + { + ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, Format.Type(@namespace, name), moduleName); + } + [System.Diagnostics.DebuggerHidden] public static void ThrowTypeLoadException(TypeDesc type) { diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.cs b/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.cs index 094ade10facaa8..90c02f6ad3aab0 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.cs @@ -59,6 +59,12 @@ public static void ThrowBadImageFormatException() throw new TypeSystemException.BadImageFormatException(); } + [System.Diagnostics.DebuggerHidden] + public static void ThrowBadImageFormatException(string message) + { + throw new TypeSystemException.BadImageFormatException(message); + } + private static partial class Format { public static string OwningModule(TypeDesc type) diff --git a/src/coreclr/tools/Common/TypeSystem/Common/TypeSystemException.cs b/src/coreclr/tools/Common/TypeSystem/Common/TypeSystemException.cs index 17836ca309bd0a..598f0f602748e7 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/TypeSystemException.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/TypeSystemException.cs @@ -155,6 +155,12 @@ internal BadImageFormatException() : base(ExceptionStringID.BadImageFormatGeneric) { } + + internal BadImageFormatException(string reason) + : base(ExceptionStringID.BadImageFormatSpecific, reason) + { + + } } } } diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs index 1b901f5e623ed2..d63e92da547669 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs @@ -276,7 +276,7 @@ private static MetadataType GetType(this ModuleDesc module, string fullName, boo namespaceName = fullName.Substring(0, split); typeName = fullName.Substring(split + 1); } - return module.GetType(namespaceName, typeName, throwIfNotFound); + return module.GetType(namespaceName, typeName, throwIfNotFound ? NotFoundBehavior.Throw : NotFoundBehavior.ReturnNull); } private static AssemblyName FindAssemblyIfNamePresent(string name) diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs index 31a4c8def5c50c..b6d5e4fd41f8b7 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs @@ -98,7 +98,7 @@ private TypeDesc InitializeFieldType() var metadataReader = MetadataReader; BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetFieldDefinition(_handle).Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader, NotFoundBehavior.Throw); var fieldType = parser.ParseFieldSignature(); return (_fieldType = fieldType); } @@ -264,7 +264,7 @@ public override MarshalAsDescriptor GetMarshalAsDescriptor() if ((definition.Attributes & FieldAttributes.HasFieldMarshal) != 0) { BlobReader marshalAsReader = reader.GetBlobReader(definition.GetMarshallingDescriptor()); - EcmaSignatureParser parser = new EcmaSignatureParser(_type.EcmaModule, marshalAsReader); + EcmaSignatureParser parser = new EcmaSignatureParser(_type.EcmaModule, marshalAsReader, NotFoundBehavior.Throw); return parser.ParseMarshalAsDescriptor(); } diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs index da5126529e4837..182a87c56765f4 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs @@ -82,7 +82,7 @@ private MethodSignature InitializeSignature() var metadataReader = MetadataReader; BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetMethodDefinition(_handle).Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader, NotFoundBehavior.Throw); var signature = parser.ParseMethodSignature(); return (_signature = signature); } @@ -573,7 +573,7 @@ private MarshalAsDescriptor GetMarshalAsDescriptor(Parameter parameter) { MetadataReader metadataReader = MetadataReader; BlobReader marshalAsReader = metadataReader.GetBlobReader(parameter.GetMarshallingDescriptor()); - EcmaSignatureParser parser = new EcmaSignatureParser(Module, marshalAsReader); + EcmaSignatureParser parser = new EcmaSignatureParser(Module, marshalAsReader, NotFoundBehavior.Throw); MarshalAsDescriptor marshalAs = parser.ParseMarshalAsDescriptor(); Debug.Assert(marshalAs != null); return marshalAs; diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs index 389f0607399b6b..737b266b9b6e62 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaModule.cs @@ -96,7 +96,7 @@ protected override IEntityHandleObject CreateValueFromKey(EntityHandle handle) { MethodDefinitionHandle methodDefinitionHandle = (MethodDefinitionHandle)handle; TypeDefinitionHandle typeDefinitionHandle = _module._metadataReader.GetMethodDefinition(methodDefinitionHandle).GetDeclaringType(); - EcmaType type = (EcmaType)_module.GetObject(typeDefinitionHandle); + EcmaType type = (EcmaType)_module.GetObject(typeDefinitionHandle, NotFoundBehavior.Throw); item = new EcmaMethod(type, methodDefinitionHandle); } break; @@ -105,7 +105,7 @@ protected override IEntityHandleObject CreateValueFromKey(EntityHandle handle) { FieldDefinitionHandle fieldDefinitionHandle = (FieldDefinitionHandle)handle; TypeDefinitionHandle typeDefinitionHandle = _module._metadataReader.GetFieldDefinition(fieldDefinitionHandle).GetDeclaringType(); - EcmaType type = (EcmaType)_module.GetObject(typeDefinitionHandle); + EcmaType type = (EcmaType)_module.GetObject(typeDefinitionHandle, NotFoundBehavior.Throw); item = new EcmaField(type, fieldDefinitionHandle); } break; @@ -149,7 +149,9 @@ protected override IEntityHandleObject CreateValueFromKey(EntityHandle handle) break; default: - throw new BadImageFormatException("Unknown metadata token type: " + handle.Kind); + ThrowHelper.ThrowBadImageFormatException("unknown metadata token type: " + handle.Kind); + item = null; + break; } switch (handle.Kind) @@ -261,7 +263,8 @@ public MethodDesc EntryPoint } // Bad metadata - throw new BadImageFormatException(); + ThrowHelper.ThrowBadImageFormatException(); + return null; } } @@ -277,7 +280,7 @@ public bool IsPlatformNeutral } } - public sealed override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true) + public sealed override MetadataType GetType(string nameSpace, string name, NotFoundBehavior notFoundBehavior) { var stringComparer = _metadataReader.StringComparer; @@ -300,12 +303,20 @@ public sealed override MetadataType GetType(string nameSpace, string name, bool { if (exportedType.IsForwarder) { - Object implementation = GetObject(exportedType.Implementation); + Object implementation = GetObject(exportedType.Implementation, notFoundBehavior); + + if (implementation == null) + return null; if (implementation is ModuleDesc) { return ((ModuleDesc)(implementation)).GetType(nameSpace, name); } + else if (implementation is ResolutionFailure failure) + { + ModuleDesc.GetTypeResolutionFailure = failure; + return null; + } // TODO throw new NotImplementedException(); @@ -315,42 +326,57 @@ public sealed override MetadataType GetType(string nameSpace, string name, bool } } - if (throwIfNotFound) - ThrowHelper.ThrowTypeLoadException(nameSpace, name, this); + if (notFoundBehavior != NotFoundBehavior.ReturnNull) + { + var failure = ResolutionFailure.GetTypeLoadResolutionFailure(nameSpace, name, this); + if (notFoundBehavior == NotFoundBehavior.Throw) + failure.Throw(); + + ModuleDesc.GetTypeResolutionFailure = failure; + return null; + } return null; } public TypeDesc GetType(EntityHandle handle) { - TypeDesc type = GetObject(handle) as TypeDesc; + TypeDesc type = GetObject(handle, NotFoundBehavior.Throw) as TypeDesc; if (type == null) - throw new BadImageFormatException("Type expected"); + ThrowHelper.ThrowBadImageFormatException($"type expected for handle {handle.ToString()}"); return type; } public MethodDesc GetMethod(EntityHandle handle) { - MethodDesc method = GetObject(handle) as MethodDesc; + MethodDesc method = GetObject(handle, NotFoundBehavior.Throw) as MethodDesc; if (method == null) - throw new BadImageFormatException("Method expected"); + ThrowHelper.ThrowBadImageFormatException($"method expected for handle {handle.ToString()}"); return method; } public FieldDesc GetField(EntityHandle handle) { - FieldDesc field = GetObject(handle) as FieldDesc; + FieldDesc field = GetObject(handle, NotFoundBehavior.Throw) as FieldDesc; if (field == null) - throw new BadImageFormatException("Field expected"); + ThrowHelper.ThrowBadImageFormatException($"field expected for handle {handle.ToString()}"); return field; } - public Object GetObject(EntityHandle handle) + public Object GetObject(EntityHandle handle, NotFoundBehavior notFoundBehavior = NotFoundBehavior.Throw) { IEntityHandleObject obj = _resolvedTokens.GetOrCreateValue(handle); if (obj is EcmaObjectLookupWrapper) { - return ((EcmaObjectLookupWrapper)obj).Object; + object result = ((EcmaObjectLookupWrapper)obj).Object; + if ((result is ResolutionFailure failure) && (notFoundBehavior != NotFoundBehavior.ReturnResolutionFailure)) + { + if (notFoundBehavior == NotFoundBehavior.ReturnNull) + return null; + else + failure.Throw(); + } + return result; } else { @@ -362,12 +388,22 @@ private Object ResolveMethodSpecification(MethodSpecificationHandle handle) { MethodSpecification methodSpecification = _metadataReader.GetMethodSpecification(handle); - MethodDesc methodDef = GetMethod(methodSpecification.Method); + object resolvedMethod = GetObject(methodSpecification.Method, NotFoundBehavior.ReturnResolutionFailure); + if (resolvedMethod is ResolutionFailure) + return resolvedMethod; + + MethodDesc methodDef = resolvedMethod as MethodDesc; + if (methodDef == null) + ThrowHelper.ThrowBadImageFormatException($"method expected for handle {handle.ToString()}"); BlobReader signatureReader = _metadataReader.GetBlobReader(methodSpecification.Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure); TypeDesc[] instantiation = parser.ParseMethodSpecSignature(); + + if (instantiation == null) + return parser.ResolutionFailure; + return Context.GetInstantiatedMethod(methodDef, new Instantiation(instantiation)); } @@ -375,9 +411,11 @@ private Object ResolveStandaloneSignature(StandaloneSignatureHandle handle) { StandaloneSignature signature = _metadataReader.GetStandaloneSignature(handle); BlobReader signatureReader = _metadataReader.GetBlobReader(signature.Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure); MethodSignature methodSig = parser.ParseMethodSignature(); + if (methodSig == null) + return parser.ResolutionFailure; return methodSig; } @@ -386,23 +424,30 @@ private Object ResolveTypeSpecification(TypeSpecificationHandle handle) TypeSpecification typeSpecification = _metadataReader.GetTypeSpecification(handle); BlobReader signatureReader = _metadataReader.GetBlobReader(typeSpecification.Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure); - return parser.ParseType(); + TypeDesc parsedType = parser.ParseType(); + if (parsedType == null) + return parser.ResolutionFailure; + else + return parsedType; } private Object ResolveMemberReference(MemberReferenceHandle handle) { MemberReference memberReference = _metadataReader.GetMemberReference(handle); - Object parent = GetObject(memberReference.Parent); + Object parent = GetObject(memberReference.Parent, NotFoundBehavior.ReturnResolutionFailure); + + if (parent is ResolutionFailure) + return parent; TypeDesc parentTypeDesc = parent as TypeDesc; if (parentTypeDesc != null) { BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure); string name = _metadataReader.GetString(memberReference.Name); @@ -412,11 +457,13 @@ private Object ResolveMemberReference(MemberReferenceHandle handle) if (field != null) return field; - ThrowHelper.ThrowMissingFieldException(parentTypeDesc, name); + return ResolutionFailure.GetMissingFieldFailure(parentTypeDesc, name); } else { MethodSignature sig = parser.ParseMethodSignature(); + if (sig == null) + return parser.ResolutionFailure; TypeDesc typeDescToInspect = parentTypeDesc; Instantiation substitution = default(Instantiation); @@ -460,7 +507,7 @@ private Object ResolveMemberReference(MemberReferenceHandle handle) typeDescToInspect = baseType; } while (typeDescToInspect != null); - ThrowHelper.ThrowMissingMethodException(parentTypeDesc, name, sig); + return ResolutionFailure.GetMissingMethodFailure(parentTypeDesc, name, sig); } } else if (parent is MethodDesc) @@ -472,18 +519,26 @@ private Object ResolveMemberReference(MemberReferenceHandle handle) throw new NotImplementedException("MemberRef to a global function or variable."); } - throw new BadImageFormatException(); + ThrowHelper.ThrowBadImageFormatException(); + return null; } private Object ResolveTypeReference(TypeReferenceHandle handle) { TypeReference typeReference = _metadataReader.GetTypeReference(handle); - Object resolutionScope = GetObject(typeReference.ResolutionScope); + Object resolutionScope = GetObject(typeReference.ResolutionScope, NotFoundBehavior.ReturnResolutionFailure); + if (resolutionScope is ResolutionFailure) + { + return resolutionScope; + } if (resolutionScope is ModuleDesc) { - return ((ModuleDesc)(resolutionScope)).GetType(_metadataReader.GetString(typeReference.Namespace), _metadataReader.GetString(typeReference.Name)); + object result = ((ModuleDesc)(resolutionScope)).GetType(_metadataReader.GetString(typeReference.Namespace), _metadataReader.GetString(typeReference.Name), NotFoundBehavior.ReturnResolutionFailure); + if (result == null) + result = ModuleDesc.GetTypeResolutionFailure; + return result; } else if (resolutionScope is MetadataType) @@ -495,7 +550,7 @@ private Object ResolveTypeReference(TypeReferenceHandle handle) if (result != null) return result; - ThrowHelper.ThrowTypeLoadException(typeName, ((MetadataType)resolutionScope).Module); + return ResolutionFailure.GetTypeLoadResolutionFailure(typeName, ((MetadataType)resolutionScope).Module); } // TODO @@ -523,20 +578,24 @@ private Object ResolveAssemblyReference(AssemblyReferenceHandle handle) an.CultureName = _metadataReader.GetString(assemblyReference.Culture); an.ContentType = GetContentTypeFromAssemblyFlags(assemblyReference.Flags); - return _moduleResolver.ResolveAssembly(an); + var assembly = _moduleResolver.ResolveAssembly(an, throwIfNotFound: false); + if (assembly == null) + return ResolutionFailure.GetAssemblyResolutionFailure(an.Name); + else + return assembly; } private Object ResolveExportedType(ExportedTypeHandle handle) { ExportedType exportedType = _metadataReader.GetExportedType(handle); - var implementation = GetObject(exportedType.Implementation); + var implementation = GetObject(exportedType.Implementation, NotFoundBehavior.ReturnResolutionFailure); if (implementation is ModuleDesc) { var module = (ModuleDesc)implementation; string nameSpace = _metadataReader.GetString(exportedType.Namespace); string name = _metadataReader.GetString(exportedType.Name); - return module.GetType(nameSpace, name); + return module.GetType(nameSpace, name, NotFoundBehavior.ReturnResolutionFailure); } else if (implementation is MetadataType) @@ -545,12 +604,17 @@ private Object ResolveExportedType(ExportedTypeHandle handle) string name = _metadataReader.GetString(exportedType.Name); var nestedType = type.GetNestedType(name); if (nestedType == null) - ThrowHelper.ThrowTypeLoadException(name, this); + return ResolutionFailure.GetTypeLoadResolutionFailure(name, this); return nestedType; } + else if (implementation is ResolutionFailure) + { + return implementation; + } else { - throw new BadImageFormatException("Unknown metadata token type for exported type"); + ThrowHelper.ThrowBadImageFormatException(); + return null; } } diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index 9a39fc67c12665..cb3766f98bc6a4 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -14,40 +14,75 @@ namespace Internal.TypeSystem.Ecma public struct EcmaSignatureParser { private TypeSystemContext _tsc; - private Func _typeResolver; + private Func _typeResolver; + private NotFoundBehavior _notFoundBehavior; private EcmaModule _ecmaModule; private BlobReader _reader; + private ResolutionFailure _resolutionFailure; private Stack _indexStack; private List _embeddedSignatureDataList; - public EcmaSignatureParser(TypeSystemContext tsc, Func typeResolver, BlobReader reader) + public EcmaSignatureParser(TypeSystemContext tsc, Func typeResolver, BlobReader reader, NotFoundBehavior notFoundBehavior) { + _notFoundBehavior = notFoundBehavior; _ecmaModule = null; _tsc = tsc; _typeResolver = typeResolver; _reader = reader; _indexStack = null; _embeddedSignatureDataList = null; + _resolutionFailure = null; } - public EcmaSignatureParser(EcmaModule ecmaModule, BlobReader reader) + public EcmaSignatureParser(EcmaModule ecmaModule, BlobReader reader, NotFoundBehavior notFoundBehavior) { + _notFoundBehavior = notFoundBehavior; _ecmaModule = ecmaModule; _tsc = ecmaModule.Context; _typeResolver = null; _reader = reader; _indexStack = null; _embeddedSignatureDataList = null; + _resolutionFailure = null; } + void SetResolutionFailure(ResolutionFailure failure) + { + if (_resolutionFailure == null) + _resolutionFailure = failure; + } + + public ResolutionFailure ResolutionFailure => _resolutionFailure; + private TypeDesc ResolveHandle(EntityHandle handle) { + object resolvedValue; if (_ecmaModule != null) - return _ecmaModule.GetType(handle); + { + resolvedValue = _ecmaModule.GetObject(handle, _notFoundBehavior); + } else - return _typeResolver(handle); + { + resolvedValue = _typeResolver(handle, _notFoundBehavior); + } + + if (resolvedValue == null) + return null; + if (resolvedValue is ResolutionFailure failure) + { + SetResolutionFailure(failure); + return null; + } + if (resolvedValue is TypeDesc type) + { + return type; + } + else + { + throw new BadImageFormatException("Type expected"); + } } private TypeDesc GetWellKnownType(WellKnownType wellKnownType) @@ -57,7 +92,6 @@ private TypeDesc GetWellKnownType(WellKnownType wellKnownType) private TypeDesc ParseType(SignatureTypeCode typeCode) { - if (_indexStack != null) { int was = _indexStack.Pop(); @@ -114,7 +148,12 @@ private TypeDesc ParseTypeImpl(SignatureTypeCode typeCode) case SignatureTypeCode.TypeHandle: return ResolveHandle(_reader.ReadTypeHandle()); case SignatureTypeCode.SZArray: - return _tsc.GetArrayType(ParseType()); + { + var elementType = ParseType(); + if (elementType == null) + return null; + return _tsc.GetArrayType(elementType); + } case SignatureTypeCode.Array: { var elementType = ParseType(); @@ -128,12 +167,27 @@ private TypeDesc ParseTypeImpl(SignatureTypeCode typeCode) for (int j = 0; j < lowerBoundsCount; j++) _reader.ReadCompressedInteger(); - return _tsc.GetArrayType(elementType, rank); + if (elementType != null) + return _tsc.GetArrayType(elementType, rank); + else + return null; } case SignatureTypeCode.ByReference: - return ParseType().MakeByRefType(); + { + TypeDesc byRefedType = ParseType(); + if (byRefedType != null) + return byRefedType.MakeByRefType(); + else + return null; + } case SignatureTypeCode.Pointer: - return _tsc.GetPointerType(ParseType()); + { + TypeDesc pointedAtType = ParseType(); + if (pointedAtType != null) + return _tsc.GetPointerType(pointedAtType); + else + return null; + } case SignatureTypeCode.GenericTypeParameter: return _tsc.GetSignatureVariable(_reader.ReadCompressedInteger(), false); case SignatureTypeCode.GenericMethodParameter: @@ -141,19 +195,36 @@ private TypeDesc ParseTypeImpl(SignatureTypeCode typeCode) case SignatureTypeCode.GenericTypeInstance: { TypeDesc typeDef = ParseType(); - MetadataType metadataTypeDef = typeDef as MetadataType; - if (metadataTypeDef == null) - throw new BadImageFormatException(); + MetadataType metadataTypeDef = null; + + if (typeDef != null) + { + metadataTypeDef = typeDef as MetadataType; + if (metadataTypeDef == null) + throw new BadImageFormatException(); + } TypeDesc[] instance = new TypeDesc[_reader.ReadCompressedInteger()]; for (int i = 0; i < instance.Length; i++) + { instance[i] = ParseType(); - return _tsc.GetInstantiatedType(metadataTypeDef, new Instantiation(instance)); + if (instance[i] == null) + metadataTypeDef = null; + } + + if (metadataTypeDef != null) + return _tsc.GetInstantiatedType(metadataTypeDef, new Instantiation(instance)); + else + return null; } case SignatureTypeCode.TypedReference: return GetWellKnownType(WellKnownType.TypedReference); case SignatureTypeCode.FunctionPointer: - return _tsc.GetFunctionPointerType(ParseMethodSignatureInternal(skipEmbeddedSignatureData: true)); + MethodSignature sig = ParseMethodSignatureInternal(skipEmbeddedSignatureData: true); + if (sig != null) + return _tsc.GetFunctionPointerType(sig); + else + return null; default: throw new BadImageFormatException(); } @@ -320,12 +391,19 @@ private MethodSignature ParseMethodSignatureImpl(bool skipEmbeddedSignatureData) EmbeddedSignatureData[] embeddedSignatureDataArray = (_embeddedSignatureDataList == null || _embeddedSignatureDataList.Count == 0 || skipEmbeddedSignatureData) ? null : _embeddedSignatureDataList.ToArray(); - return new MethodSignature(flags, arity, returnType, parameters, embeddedSignatureDataArray); + if (_resolutionFailure == null) + return new MethodSignature(flags, arity, returnType, parameters, embeddedSignatureDataArray); + else + return null; } public PropertySignature ParsePropertySignature() { + // As PropertySignature is a struct, we cannot return null + if (_notFoundBehavior != NotFoundBehavior.Throw) + throw new ArgumentException(); + SignatureHeader header = _reader.ReadSignatureHeader(); if (header.Kind != SignatureKind.Property) throw new BadImageFormatException(); @@ -392,7 +470,10 @@ public LocalVariableDefinition[] ParseLocalsSignature() { locals = Array.Empty(); } - return locals; + if (_resolutionFailure == null) + return locals; + else + return null; } public TypeDesc[] ParseMethodSpecSignature() @@ -410,7 +491,10 @@ public TypeDesc[] ParseMethodSpecSignature() { arguments[i] = ParseType(); } - return arguments; + if (_resolutionFailure == null) + return arguments; + else + return null; } public MarshalAsDescriptor ParseMarshalAsDescriptor() diff --git a/src/coreclr/tools/Common/TypeSystem/IL/EcmaMethodIL.cs b/src/coreclr/tools/Common/TypeSystem/IL/EcmaMethodIL.cs index e0142800be95d2..02e5207c90a8b7 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/EcmaMethodIL.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/EcmaMethodIL.cs @@ -89,7 +89,7 @@ public override LocalVariableDefinition[] GetLocals() return Array.Empty(); BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetStandaloneSignature(localSignature).Signature); - EcmaSignatureParser parser = new EcmaSignatureParser(_module, signatureReader); + EcmaSignatureParser parser = new EcmaSignatureParser(_module, signatureReader, NotFoundBehavior.Throw); LocalVariableDefinition[] locals = parser.ParseLocalsSignature(); Interlocked.CompareExchange(ref _locals, locals, null); @@ -131,13 +131,13 @@ public override ILExceptionRegion[] GetExceptionRegions() return _ilExceptionRegions; } - public override object GetObject(int token) + public override object GetObject(int token, NotFoundBehavior notFoundBehavior = NotFoundBehavior.Throw) { // UserStrings cannot be wrapped in EntityHandle if ((token & 0xFF000000) == 0x70000000) return _module.GetUserString(MetadataTokens.UserStringHandle(token)); - return _module.GetObject(MetadataTokens.EntityHandle(token)); + return _module.GetObject(MetadataTokens.EntityHandle(token), notFoundBehavior); } } } diff --git a/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs b/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs index 0723d40b363ffe..3c6d4c1d0b2237 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs @@ -22,7 +22,7 @@ public static MetadataType GetHelperType(this TypeSystemContext context, string public static MetadataType GetOptionalHelperType(this TypeSystemContext context, string name) { - MetadataType helperType = context.SystemModule.GetType(HelperTypesNamespace, name, throwIfNotFound: false); + MetadataType helperType = context.SystemModule.GetType(HelperTypesNamespace, name, NotFoundBehavior.ReturnNull); return helperType; } @@ -111,7 +111,7 @@ public static MetadataType GetKnownNestedType(this MetadataType type, string nam /// public static MetadataType GetKnownType(this ModuleDesc module, string @namespace, string name) { - MetadataType type = module.GetType(@namespace, name, false); + MetadataType type = module.GetType(@namespace, name, NotFoundBehavior.ReturnNull); if (type == null) { throw new InvalidOperationException( diff --git a/src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.cs b/src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.cs index 7192e547f39a67..9def3ed499b8be 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.cs @@ -89,9 +89,9 @@ public override LocalVariableDefinition[] GetLocals() return (clone == null) ? locals : clone; } - public override Object GetObject(int token) + public override Object GetObject(int token, NotFoundBehavior notFoundBehavior) { - Object o = _methodIL.GetObject(token); + Object o = _methodIL.GetObject(token, notFoundBehavior); if (o is MethodDesc) { diff --git a/src/coreclr/tools/Common/TypeSystem/IL/MethodIL.cs b/src/coreclr/tools/Common/TypeSystem/IL/MethodIL.cs index 83fecc15119b14..b5eb21fcba4297 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/MethodIL.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/MethodIL.cs @@ -86,7 +86,7 @@ public abstract partial class MethodIL /// (typically a , , , /// or ). /// - public abstract Object GetObject(int token); + public abstract Object GetObject(int token, NotFoundBehavior notFoundBehavior = NotFoundBehavior.ReturnNull); /// /// Gets a list of exception regions this method body defines. diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ILEmitter.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ILEmitter.cs index 67f79ad809dc8b..aa203289c3c6e5 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ILEmitter.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ILEmitter.cs @@ -620,7 +620,7 @@ public override LocalVariableDefinition[] GetLocals() { return _locals; } - public override Object GetObject(int token) + public override Object GetObject(int token, NotFoundBehavior notFoundBehavior) { return _tokens[(token & 0xFFFFFF) - 1]; } diff --git a/src/coreclr/tools/ILVerification/ILVerification.projitems b/src/coreclr/tools/ILVerification/ILVerification.projitems index c68e48bdc552cb..35b992f6f023c9 100644 --- a/src/coreclr/tools/ILVerification/ILVerification.projitems +++ b/src/coreclr/tools/ILVerification/ILVerification.projitems @@ -46,6 +46,12 @@ TypeSystem\Common\ModuleDesc.cs + + TypeSystem\Common\NotFoundBehavior.cs + + + TypeSystem\Common\ResolutionFailure.cs + TypeSystem\Common\TypeSystemEntity.cs diff --git a/src/coreclr/tools/ILVerification/SimpleArrayOfTRuntimeInterfacesAlgorithm.cs b/src/coreclr/tools/ILVerification/SimpleArrayOfTRuntimeInterfacesAlgorithm.cs index 3a08440c4fa75d..019f669a73a060 100644 --- a/src/coreclr/tools/ILVerification/SimpleArrayOfTRuntimeInterfacesAlgorithm.cs +++ b/src/coreclr/tools/ILVerification/SimpleArrayOfTRuntimeInterfacesAlgorithm.cs @@ -35,7 +35,7 @@ public SimpleArrayOfTRuntimeInterfacesAlgorithm(ModuleDesc systemModule) int count = 0; for (int i = 0; i < s_genericRuntimeInterfacesNames.Length; ++i) { - MetadataType runtimeInterface =_systemModule.GetType("System.Collections.Generic", s_genericRuntimeInterfacesNames[i], false); + MetadataType runtimeInterface =_systemModule.GetType("System.Collections.Generic", s_genericRuntimeInterfacesNames[i], NotFoundBehavior.ReturnNull); if (runtimeInterface != null) _genericRuntimeInterfaces[count++] = runtimeInterface; }; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs index b26d9ab6226fbc..8b419d4b3955fd 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs @@ -106,7 +106,7 @@ public ProfileData ParseIBCDataFromModule(EcmaModule ecmaModule) case CorTokenType.mdtMethodDef: case CorTokenType.mdtMemberRef: case CorTokenType.mdtMethodSpec: - object metadataObject = ecmaModule.GetObject(System.Reflection.Metadata.Ecma335.MetadataTokens.EntityHandle((int)entry.Token)); + object metadataObject = ecmaModule.GetObject(System.Reflection.Metadata.Ecma335.MetadataTokens.EntityHandle((int)entry.Token), NotFoundBehavior.ReturnNull); if (metadataObject is MethodDesc) { associatedMethod = (MethodDesc)metadataObject; @@ -346,7 +346,7 @@ private uint LookupIbcTypeToken(ref EcmaModule externalModule, uint ibcToken, Di if (!(m is EcmaModule)) continue; - foundType = (EcmaType)m.GetType(typeNamespace, typeName, throwIfNotFound: false); + foundType = (EcmaType)m.GetType(typeNamespace, typeName, NotFoundBehavior.ReturnNull); if (foundType != null) { externalModule = foundType.EcmaModule; @@ -356,7 +356,7 @@ private uint LookupIbcTypeToken(ref EcmaModule externalModule, uint ibcToken, Di } else { - foundType = (EcmaType)externalModule.GetType(typeNamespace, typeName, throwIfNotFound: false); + foundType = (EcmaType)externalModule.GetType(typeNamespace, typeName, NotFoundBehavior.ReturnNull); } if (foundType == null) @@ -451,7 +451,7 @@ public EcmaModule GetModuleFromIndex(int index) { if (EcmaModule.MetadataReader.GetTableRowCount(TableIndex.AssemblyRef) < index) return null; - return EcmaModule.GetObject(MetadataTokens.EntityHandle(((int)CorTokenType.mdtAssemblyRef) | index)) as EcmaModule; + return EcmaModule.GetObject(MetadataTokens.EntityHandle(((int)CorTokenType.mdtAssemblyRef) | index), NotFoundBehavior.ReturnNull) as EcmaModule; } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs index 987300df24b286..22e54a8922adb8 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs @@ -41,7 +41,12 @@ TypeSystemEntityOrUnknown IPgoSchemaDataLoader.TypeFr // token type is 0, therefore it can't be a type return new TypeSystemEntityOrUnknown((int)token); } - return new TypeSystemEntityOrUnknown((TypeDesc)_ilBody.GetObject((int)token)); + TypeDesc foundType = _ilBody.GetObject((int)token, NotFoundBehavior.ReturnNull) as TypeDesc; + if (foundType == null) + { + return new TypeSystemEntityOrUnknown((int)token & 0x00FFFFFF); + } + return new TypeSystemEntityOrUnknown(foundType); } catch { @@ -265,7 +270,9 @@ static IEnumerable ReadMIbcGroup(TypeSystemContext tsc, EcmaM metadataObject = null; try { - metadataObject = ilBody.GetObject(token); + metadataObject = ilBody.GetObject(token, NotFoundBehavior.ReturnNull); + if (metadataObject == null) + metadataObject = metadataNotResolvable; } catch (TypeSystemException) { @@ -509,7 +516,7 @@ public override MetadataType GetGlobalModuleType() throw new NotImplementedException(); } - public override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true) + public override MetadataType GetType(string nameSpace, string name, NotFoundBehavior notFoundBehavior) { TypeSystemContext context = Context; @@ -519,9 +526,14 @@ public override MetadataType GetType(string nameSpace, string name, bool throwIf return Context.UniversalCanonType; else { - if (throwIfNotFound) + if (notFoundBehavior != NotFoundBehavior.ReturnNull) { - throw new TypeLoadException($"{nameSpace}.{name}"); + var failure = ResolutionFailure.GetTypeLoadResolutionFailure(nameSpace, name, "System.Private.Canon"); + ModuleDesc.GetTypeResolutionFailure = failure; + if (notFoundBehavior == NotFoundBehavior.Throw) + failure.Throw(); + + return null; } return null; } diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj index c8e83d94bf8484..580438dcc29d2d 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj @@ -146,6 +146,12 @@ TypeSystem\Common\ModuleDesc.cs + + TypeSystem\Common\NotFoundBehavior.cs + + + TypeSystem\Common\ResolutionFailure.cs + TypeSystem\Common\TypeSystemEntity.cs diff --git a/src/coreclr/tools/dotnet-pgo/R2RSignatureTypeProvider.cs b/src/coreclr/tools/dotnet-pgo/R2RSignatureTypeProvider.cs index 0bc52929256b9a..a640425f209b4e 100644 --- a/src/coreclr/tools/dotnet-pgo/R2RSignatureTypeProvider.cs +++ b/src/coreclr/tools/dotnet-pgo/R2RSignatureTypeProvider.cs @@ -97,7 +97,11 @@ MethodDesc IR2RSignatureTypeProvider.GetMethodFromMemberRef(MetadataReader reader, MemberReferenceHandle handle, TypeDesc owningTypeOverride) { var ecmaModule = (EcmaModule)_tsc.GetModuleForSimpleName(reader.GetString(reader.GetAssemblyDefinition().Name)); - var method = (MethodDesc)ecmaModule.GetObject(handle); + var method = (MethodDesc)ecmaModule.GetObject(handle, NotFoundBehavior.ReturnNull); + if (method == null) + { + return null; + } if (owningTypeOverride != null) { return _tsc.GetMethodForInstantiatedType(method.GetTypicalMethodDefinition(), (InstantiatedType)owningTypeOverride); @@ -108,7 +112,11 @@ MethodDesc IR2RSignatureTypeProvider.GetMethodFromMethodDef(MetadataReader reader, MethodDefinitionHandle handle, TypeDesc owningTypeOverride) { var ecmaModule = (EcmaModule)_tsc.GetModuleForSimpleName(reader.GetString(reader.GetAssemblyDefinition().Name)); - var method = (MethodDesc)ecmaModule.GetObject(handle); + var method = (MethodDesc)ecmaModule.GetObject(handle, NotFoundBehavior.ReturnNull); + if (method == null) + { + return null; + } if (owningTypeOverride != null) { return _tsc.GetMethodForInstantiatedType(method.GetTypicalMethodDefinition(), (InstantiatedType)owningTypeOverride); @@ -214,19 +222,19 @@ TypeDesc ISZArrayTypeProvider.GetSZArrayType(TypeDesc elementType) TypeDesc ISimpleTypeProvider.GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) { var ecmaModule = (EcmaModule)_tsc.GetModuleForSimpleName(reader.GetString(reader.GetAssemblyDefinition().Name)); - return (TypeDesc)ecmaModule.GetObject(handle); + return (TypeDesc)ecmaModule.GetObject(handle, NotFoundBehavior.ReturnNull); } TypeDesc ISimpleTypeProvider.GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) { var ecmaModule = (EcmaModule)_tsc.GetModuleForSimpleName(reader.GetString(reader.GetAssemblyDefinition().Name)); - return (TypeDesc)ecmaModule.GetObject(handle); + return (TypeDesc)ecmaModule.GetObject(handle, NotFoundBehavior.ReturnNull); } TypeDesc ISignatureTypeProvider.GetTypeFromSpecification(MetadataReader reader, R2RSigProviderContext genericContext, TypeSpecificationHandle handle, byte rawTypeKind) { var ecmaModule = (EcmaModule)_tsc.GetModuleForSimpleName(reader.GetString(reader.GetAssemblyDefinition().Name)); - return (TypeDesc)ecmaModule.GetObject(handle); + return (TypeDesc)ecmaModule.GetObject(handle, NotFoundBehavior.ReturnNull); } } } diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs index 1cb1138a492930..bb32521c0b750e 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection.Metadata; using System.Text; @@ -120,7 +121,7 @@ public TypeRefTypeSystemContext(IEnumerable refReaders) { TypeRefSignatureParserProvider parserHelper = new TypeRefSignatureParserProvider(this, peInfo.handleLookup); - Func resolverFunc = ResolveTypeRefForPeInfo; + Func resolverFunc = ResolveTypeRefForPeInfo; int memberRefRowCount = peInfo.reader.GetTableRowCount(TableIndex.MemberRef); for (int row = 1; row <= memberRefRowCount; row++) { @@ -142,7 +143,7 @@ public TypeRefTypeSystemContext(IEnumerable refReaders) continue; } - EcmaSignatureParser ecmaSigParse = new EcmaSignatureParser(this, ResolveTypeRefForPeInfo, peInfo.reader.GetBlobReader(memberRef.Signature)); + EcmaSignatureParser ecmaSigParse = new EcmaSignatureParser(this, ResolveTypeRefForPeInfo, peInfo.reader.GetBlobReader(memberRef.Signature), NotFoundBehavior.ReturnNull); string name = peInfo.reader.GetString(memberRef.Name); if (memberRef.GetKind() == MemberReferenceKind.Method) @@ -157,8 +158,9 @@ public TypeRefTypeSystemContext(IEnumerable refReaders) } } - TypeDesc ResolveTypeRefForPeInfo(EntityHandle handle) + TypeDesc ResolveTypeRefForPeInfo(EntityHandle handle, NotFoundBehavior notFoundBehavior) { + Debug.Assert(notFoundBehavior == NotFoundBehavior.ReturnNull); TypeRefTypeSystemType type = null; if (handle.Kind == HandleKind.TypeReference) { diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemModule.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemModule.cs index 45529383eeab7e..d057112766cca1 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemModule.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemModule.cs @@ -71,11 +71,16 @@ private TypeRefTypeSystemType GetTypeInternal(string nameSpace, string name) return type; } - public override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true) + public override MetadataType GetType(string nameSpace, string name, NotFoundBehavior notFoundBehavior) { MetadataType type = GetTypeInternal(nameSpace, name); - if ((type == null) && throwIfNotFound) - ThrowHelper.ThrowTypeLoadException(nameSpace, name, this); + if ((type == null) && notFoundBehavior != NotFoundBehavior.ReturnNull) + { + ResolutionFailure failure = ResolutionFailure.GetTypeLoadResolutionFailure(nameSpace, name, this); + ModuleDesc.GetTypeResolutionFailure = failure; + if (notFoundBehavior == NotFoundBehavior.Throw) + failure.Throw(); + } return type; } }