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;
}
}