}
else if (pClsMT != NULL)
{
- DispatchSlot impl(pClsMT->FindDispatchSlotForInterfaceMD(pIntfMD));
+ DispatchSlot impl(pClsMT->FindDispatchSlotForInterfaceMD(pIntfMD, FALSE /* throwOnConflict */));
pClassMD = impl.GetMethodDesc();
}
if (m_pICustomQueryInterfaceGetInterfaceMD == NULL)
m_pICustomQueryInterfaceGetInterfaceMD = m_thClass.GetMethodTable()->GetMethodDescForInterfaceMethod(
- MscorlibBinder::GetMethod(METHOD__ICUSTOM_QUERYINTERFACE__GET_INTERFACE));
+ MscorlibBinder::GetMethod(METHOD__ICUSTOM_QUERYINTERFACE__GET_INTERFACE),
+ TRUE /* throwOnConflict */);
RETURN m_pICustomQueryInterfaceGetInterfaceMD;
}
// <TODO>it looks like we need to pass an ownerType in here.
// Why can we take a delegate to an interface method anyway? </TODO>
//
- pCorrectedMethod = pMTTarg->FindDispatchSlotForInterfaceMD(pCorrectedMethod).GetMethodDesc();
+ pCorrectedMethod = pMTTarg->FindDispatchSlotForInterfaceMD(pCorrectedMethod, TRUE /* throwOnConflict */).GetMethodDesc();
_ASSERTE(pCorrectedMethod != NULL);
}
}
// <TODO>it looks like we need to pass an ownerType in here.
// Why can we take a delegate to an interface method anyway? </TODO>
//
- MethodDesc * pDispatchSlotMD = pMTTarg->FindDispatchSlotForInterfaceMD(pMeth).GetMethodDesc();
+ MethodDesc * pDispatchSlotMD = pMTTarg->FindDispatchSlotForInterfaceMD(pMeth, TRUE /* throwOnConflict */).GetMethodDesc();
if (pDispatchSlotMD == NULL)
{
COMPlusThrow(kArgumentException, W("Arg_DlgtTargMeth"));
{
case CustomMarshalerMethods_MarshalNativeToManaged:
pMD = pMT->GetMethodDescForInterfaceMethod(
- MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED));
+ MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED),
+ TRUE /* throwOnConflict */);
break;
case CustomMarshalerMethods_MarshalManagedToNative:
pMD = pMT->GetMethodDescForInterfaceMethod(
- MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE));
+ MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE),
+ TRUE /* throwOnConflict */);
break;
case CustomMarshalerMethods_CleanUpNativeData:
pMD = pMT->GetMethodDescForInterfaceMethod(
- MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA));
+ MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA),
+ TRUE /* throwOnConflict */);
break;
case CustomMarshalerMethods_CleanUpManagedData:
pMD = pMT->GetMethodDescForInterfaceMethod(
- MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA));
+ MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA),
+ TRUE /* throwOnConflict */);
break;
case CustomMarshalerMethods_GetNativeDataSize:
pMD = pMT->GetMethodDescForInterfaceMethod(
- MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE));
+ MscorlibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE),
+ TRUE /* throwOnConflict */);
break;
case CustomMarshalerMethods_GetInstance:
// Must look this up by name since it's static
CONTRACT_END;
MethodTable *pMT = hndCustomAttrProvider.AsMethodTable();
- MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(METHOD__ICUSTOM_ATTR_PROVIDER__GET_CUSTOM_ATTRIBUTES));
+ MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(METHOD__ICUSTOM_ATTR_PROVIDER__GET_CUSTOM_ATTRIBUTES), TRUE /* throwOnConflict */);
// Return the specified method desc.
RETURN pMD;
CONTRACT_END;
MethodTable *pMT = m_pSimpleWrapperOwner->GetMethodTable();
- MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(Method));
+ MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(Method), TRUE /* throwOnConflict */);
// Return the specified method desc.
RETURN pMD;
CONTRACT_END;
MethodTable *pMT = m_pSimpleWrapperOwner->GetMethodTable();
- MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(Method));
+ MethodDesc *pMD = pMT->GetMethodDescForInterfaceMethod(MscorlibBinder::GetMethod(Method), TRUE /* throwOnConflict */);
// Return the specified method desc.
RETURN pMD;
pOwnerMT = pOwnerMT->GetCanonicalMethodTable();
}
- // In a try block because the interface method resolution might end up being
- // ambiguous (diamond inheritance case of default interface methods).
- EX_TRY
- {
- pDevirtMD = pDerivedMT->GetMethodDescForInterfaceMethod(TypeHandle(pOwnerMT), pBaseMD);
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(RethrowTransientExceptions)
+ pDevirtMD = pDerivedMT->GetMethodDescForInterfaceMethod(TypeHandle(pOwnerMT), pBaseMD, FALSE /* throwOnConflict */);
}
else if (!pBaseMD->HasClassOrMethodInstantiation())
{
- // In a try block because the interface method resolution might end up being
- // ambiguous (diamond inheritance case of default interface methods).
- EX_TRY
- {
- pDevirtMD = pDerivedMT->GetMethodDescForInterfaceMethod(pBaseMD);
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(RethrowTransientExceptions)
+ pDevirtMD = pDerivedMT->GetMethodDescForInterfaceMethod(pBaseMD, FALSE /* throwOnConflict */);
}
if (pDevirtMD == nullptr)
TypeHandle resulTypeHnd = resultTypeObj->GetType();
MethodTable *pResultMT = resulTypeHnd.GetMethodTable();
- RETURN(pResultMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD));
+ RETURN(pResultMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */));
}
#endif
#endif // !FEATURE_COMINTEROP
// Handle pure COM+ types.
- RETURN (pServerMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD));
+ RETURN (pServerMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */));
}
#ifdef FEATURE_COMINTEROP
// Calling GetTarget here instead of FindDispatchImpl gives us caching functionality to increase speed.
PCODE tgt = VirtualCallStubManager::GetTarget(
- pItfMT->GetLoaderAllocator()->GetDispatchToken(pItfMT->GetTypeID(), pItfMD->GetSlot()), this);
+ pItfMT->GetLoaderAllocator()->GetDispatchToken(pItfMT->GetTypeID(), pItfMD->GetSlot()), this, TRUE /* throwOnConflict */);
if (tgt != NULL)
{
}
//==========================================================================================
-MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceMD)
+MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceMD, BOOL throwOnConflict)
{
CONTRACTL
{
CONTRACTL_END;
WRAPPER_NO_CONTRACT;
- return GetMethodDescForInterfaceMethod(TypeHandle(pInterfaceMD->GetMethodTable()), pInterfaceMD);
+ return GetMethodDescForInterfaceMethod(TypeHandle(pInterfaceMD->GetMethodTable()), pInterfaceMD, throwOnConflict);
}
//==========================================================================================
-MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(TypeHandle ownerType, MethodDesc *pInterfaceMD)
+MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(TypeHandle ownerType, MethodDesc *pInterfaceMD, BOOL throwOnConflict)
{
CONTRACTL
{
MethodTable *pInterfaceMT = ownerType.AsMethodTable();
#ifdef CROSSGEN_COMPILE
- DispatchSlot implSlot(FindDispatchSlot(pInterfaceMT->GetTypeID(), pInterfaceMD->GetSlot()));
+ DispatchSlot implSlot(FindDispatchSlot(pInterfaceMT->GetTypeID(), pInterfaceMD->GetSlot(), throwOnConflict));
+ if (implSlot.IsNull())
+ {
+ _ASSERTE(!throwOnConflict);
+ return NULL;
+ }
PCODE pTgt = implSlot.GetTarget();
#else
PCODE pTgt = VirtualCallStubManager::GetTarget(
pInterfaceMT->GetLoaderAllocator()->GetDispatchToken(pInterfaceMT->GetTypeID(), pInterfaceMD->GetSlot()),
- this);
+ this, throwOnConflict);
+ if (pTgt == NULL)
+ {
+ _ASSERTE(!throwOnConflict);
+ return NULL;
+ }
#endif
pMD = MethodTable::GetMethodDescForSlotAddress(pTgt);
#ifdef _DEBUG
- MethodDesc *pDispSlotMD = FindDispatchSlotForInterfaceMD(ownerType, pInterfaceMD).GetMethodDesc();
+ MethodDesc *pDispSlotMD = FindDispatchSlotForInterfaceMD(ownerType, pInterfaceMD, throwOnConflict).GetMethodDesc();
_ASSERTE(pDispSlotMD == pMD);
#endif // _DEBUG
MethodTable::FindDispatchImpl(
UINT32 typeID,
UINT32 slotNumber,
- DispatchSlot * pImplSlot)
+ DispatchSlot * pImplSlot,
+ BOOL throwOnConflict)
{
CONTRACT (BOOL) {
INSTANCE_CHECK;
if (FindDefaultInterfaceImplementation(
pIfcMD, // the interface method being resolved
pIfcMT, // the interface being resolved
- &pDefaultMethod))
+ &pDefaultMethod,
+ throwOnConflict))
{
// Now, construct a DispatchSlot to return in *pImplSlot
DispatchSlot ds(pDefaultMethod->GetMethodEntryPoint());
BOOL MethodTable::FindDefaultInterfaceImplementation(
MethodDesc *pInterfaceMD,
MethodTable *pInterfaceMT,
- MethodDesc **ppDefaultMethod
+ MethodDesc **ppDefaultMethod,
+ BOOL throwOnConflict
)
{
CONTRACT(BOOL) {
}
else if (pBestCandidateMT != candidates[i].pMT)
{
- ThrowExceptionForConflictingOverride(this, pInterfaceMT, pInterfaceMD);
+ if (throwOnConflict)
+ ThrowExceptionForConflictingOverride(this, pInterfaceMT, pInterfaceMD);
+
+ *ppDefaultMethod = NULL;
+ RETURN(FALSE);
}
}
#endif // DACCESS_COMPILE
//==========================================================================================
-DispatchSlot MethodTable::FindDispatchSlot(UINT32 typeID, UINT32 slotNumber)
+DispatchSlot MethodTable::FindDispatchSlot(UINT32 typeID, UINT32 slotNumber, BOOL throwOnConflict)
{
WRAPPER_NO_CONTRACT;
STATIC_CONTRACT_SO_TOLERANT;
DispatchSlot implSlot(NULL);
- FindDispatchImpl(typeID, slotNumber, &implSlot);
+ FindDispatchImpl(typeID, slotNumber, &implSlot, throwOnConflict);
return implSlot;
}
//==========================================================================================
-DispatchSlot MethodTable::FindDispatchSlot(DispatchToken tok)
+DispatchSlot MethodTable::FindDispatchSlot(DispatchToken tok, BOOL throwOnConflict)
{
CONTRACTL
{
MODE_ANY;
}
CONTRACTL_END;
- return FindDispatchSlot(tok.GetTypeID(), tok.GetSlotNumber());
+ return FindDispatchSlot(tok.GetTypeID(), tok.GetSlotNumber(), throwOnConflict);
}
#ifndef DACCESS_COMPILE
//==========================================================================================
-DispatchSlot MethodTable::FindDispatchSlotForInterfaceMD(MethodDesc *pMD)
+DispatchSlot MethodTable::FindDispatchSlotForInterfaceMD(MethodDesc *pMD, BOOL throwOnConflict)
{
WRAPPER_NO_CONTRACT;
CONSISTENCY_CHECK(CheckPointer(pMD));
CONSISTENCY_CHECK(pMD->IsInterface());
- return FindDispatchSlotForInterfaceMD(TypeHandle(pMD->GetMethodTable()), pMD);
+ return FindDispatchSlotForInterfaceMD(TypeHandle(pMD->GetMethodTable()), pMD, throwOnConflict);
}
//==========================================================================================
-DispatchSlot MethodTable::FindDispatchSlotForInterfaceMD(TypeHandle ownerType, MethodDesc *pMD)
+DispatchSlot MethodTable::FindDispatchSlotForInterfaceMD(TypeHandle ownerType, MethodDesc *pMD, BOOL throwOnConflict)
{
WRAPPER_NO_CONTRACT;
CONSISTENCY_CHECK(!ownerType.IsNull());
CONSISTENCY_CHECK(CheckPointer(pMD));
CONSISTENCY_CHECK(pMD->IsInterface());
- return FindDispatchSlot(ownerType.GetMethodTable()->GetTypeID(), pMD->GetSlot());
+ return FindDispatchSlot(ownerType.GetMethodTable()->GetTypeID(), pMD->GetSlot(), throwOnConflict);
}
//==========================================================================================
thInterfaceType.AsMethodTable()->GetCanonicalMethodTable())
{
cPotentialMatchingInterfaces++;
- pMD = pCanonMT->GetMethodDescForInterfaceMethod(thPotentialInterfaceType, pGenInterfaceMD);
+ pMD = pCanonMT->GetMethodDescForInterfaceMethod(thPotentialInterfaceType, pGenInterfaceMD, FALSE /* throwOnConflict */);
// See code:#TryResolveConstraintMethodApprox_DoNotReturnParentMethod
if ((pMD != NULL) && !pMD->GetMethodTable()->IsValueType())
if (this->CanCastToInterface(pInterfaceMT))
{
// We can resolve to exact method
- pMD = this->GetMethodDescForInterfaceMethod(pInterfaceMT, pInterfaceMD);
- _ASSERTE(pMD != NULL);
- fIsExactMethodResolved = TRUE;
+ pMD = this->GetMethodDescForInterfaceMethod(pInterfaceMT, pInterfaceMD, FALSE /* throwOnConflict */);
+ fIsExactMethodResolved = pMD != NULL;
}
}
// lookup at runtime, or when not sharing generic code).
if (pCanonMT->CanCastToInterface(thInterfaceType.GetMethodTable()))
{
- pMD = pCanonMT->GetMethodDescForInterfaceMethod(thInterfaceType, pGenInterfaceMD);
+ pMD = pCanonMT->GetMethodDescForInterfaceMethod(thInterfaceType, pGenInterfaceMD, FALSE /* throwOnConflict */);
if (pMD == NULL)
{
LOG((LF_JIT, LL_INFO10000, "TryResolveConstraintMethodApprox: failed to find method desc for interface method\n"));
BOOL ImplementsInterface(MethodTable *pInterface);
BOOL ImplementsEquivalentInterface(MethodTable *pInterface);
- MethodDesc *GetMethodDescForInterfaceMethod(TypeHandle ownerType, MethodDesc *pInterfaceMD);
- MethodDesc *GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceMD); // You can only use this one for non-generic interfaces
+ MethodDesc *GetMethodDescForInterfaceMethod(TypeHandle ownerType, MethodDesc *pInterfaceMD, BOOL throwOnConflict);
+ MethodDesc *GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceMD, BOOL throwOnConflict); // You can only use this one for non-generic interfaces
//-------------------------------------------------------------------
// INTERFACE MAP.
BOOL FindDispatchImpl(
UINT32 typeID,
UINT32 slotNumber,
- DispatchSlot * pImplSlot);
+ DispatchSlot * pImplSlot,
+ BOOL throwOnConflict);
#ifndef DACCESS_COMPILE
BOOL FindDefaultInterfaceImplementation(
MethodDesc *pInterfaceMD,
MethodTable *pObjectMT,
- MethodDesc **ppDefaultMethod);
+ MethodDesc **ppDefaultMethod,
+ BOOL throwOnConflict);
#endif // DACCESS_COMPILE
- DispatchSlot FindDispatchSlot(UINT32 typeID, UINT32 slotNumber);
+ DispatchSlot FindDispatchSlot(UINT32 typeID, UINT32 slotNumber, BOOL throwOnConflict);
- DispatchSlot FindDispatchSlot(DispatchToken tok);
+ DispatchSlot FindDispatchSlot(DispatchToken tok, BOOL throwOnConflict);
// You must use the second of these two if there is any chance the pMD is a method
// on a generic interface such as IComparable<T> (which it normally can be). The
// ownerType is used to provide an exact qualification in the case the pMD is
// a shared method descriptor.
- DispatchSlot FindDispatchSlotForInterfaceMD(MethodDesc *pMD);
- DispatchSlot FindDispatchSlotForInterfaceMD(TypeHandle ownerType, MethodDesc *pMD);
+ DispatchSlot FindDispatchSlotForInterfaceMD(MethodDesc *pMD, BOOL throwOnConflict);
+ DispatchSlot FindDispatchSlotForInterfaceMD(TypeHandle ownerType, MethodDesc *pMD, BOOL throwOnConflict);
MethodDesc *ReverseInterfaceMDLookup(UINT32 slotNumber);
// with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
//@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
//@TODO: be done faster - just need to make a function FindDispatchDecl.
- DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
+ DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD, TRUE /* throwOnConflict */));
if (!slot.IsNull())
pResult = slot.GetMethodDesc();
if (target == NULL)
{
CONSISTENCY_CHECK(stub == CALL_STUB_EMPTY_ENTRY);
- patch = Resolver(objectType, token, protectedObj, &target);
+ patch = Resolver(objectType, token, protectedObj, &target, TRUE /* throwOnConflict */);
#if defined(_DEBUG)
if ( !objectType->IsComObjectType() &&
MethodTable * pMT,
DispatchToken token,
OBJECTREF * protectedObj, // this one can actually be NULL, consider using pMT is you don't need the object itself
- PCODE * ppTarget)
+ PCODE * ppTarget,
+ BOOL throwOnConflict)
{
CONTRACTL {
THROWS;
if (token.IsTypedToken())
{
dbg_pTokenMT = GetThread()->GetDomain()->LookupType(token.GetTypeID());
- dbg_pTokenMD = dbg_pTokenMT->FindDispatchSlot(token.GetSlotNumber()).GetMethodDesc();
+ dbg_pTokenMD = dbg_pTokenMT->FindDispatchSlot(token.GetSlotNumber(), throwOnConflict).GetMethodDesc();
}
#endif // _DEBUG
MethodDesc * pMD = NULL;
BOOL fShouldPatch = FALSE;
- DispatchSlot implSlot(pMT->FindDispatchSlot(token));
+ DispatchSlot implSlot(pMT->FindDispatchSlot(token, throwOnConflict));
// If we found a target, then just figure out if we're allowed to create a stub around
// this target and backpatch the callsite.
else if (pMT->IsComObjectType() && IsInterfaceToken(token))
{
MethodTable * pItfMT = GetTypeFromToken(token);
- implSlot = pItfMT->FindDispatchSlot(token.GetSlotNumber());
+ implSlot = pItfMT->FindDispatchSlot(token.GetSlotNumber(), throwOnConflict);
if (pItfMT->HasInstantiation())
{
TypeHandle resulTypeHnd = resultTypeObj->GetType();
MethodTable *pResultMT = resulTypeHnd.GetMethodTable();
- return Resolver(pResultMT, token, protectedObj, ppTarget);
+ return Resolver(pResultMT, token, protectedObj, ppTarget, throwOnConflict);
}
#endif // FEATURE_ICASTABLE
if (token.IsTypedToken())
{
pTokenMT = GetThread()->GetDomain()->LookupType(token.GetTypeID());
- pTokenMD = pTokenMT->FindDispatchSlot(token.GetSlotNumber()).GetMethodDesc();
+ pTokenMD = pTokenMT->FindDispatchSlot(token.GetSlotNumber(), throwOnConflict).GetMethodDesc();
}
#ifdef FEATURE_COMINTEROP
}
else
#endif // FEATURE_COMINTEROP
+ if (!throwOnConflict)
+ {
+ // Assume we got null because there was a default interface method conflict
+ *ppTarget = NULL;
+ return FALSE;
+ }
+ else
{
// Method not found, and this should never happen for anything but equivalent types
CONSISTENCY_CHECK(!implSlot.IsNull() && "Valid method implementation was not found.");
PCODE
VirtualCallStubManager::GetTarget(
DispatchToken token,
- MethodTable * pMT)
+ MethodTable * pMT,
+ BOOL throwOnConflict)
{
CONTRACTL {
THROWS;
// TODO: passing NULL as protectedObj here can lead to incorrect behavior for ICastable objects
// We need to review if this is the case and refactor this code if we want ICastable to become officially supported
- fPatch = Resolver(pMT, token, NULL, &target);
- _ASSERTE(target != NULL);
+ fPatch = Resolver(pMT, token, NULL, &target, throwOnConflict);
+ _ASSERTE(!throwOnConflict || target != NULL);
#ifndef STUB_DISPATCH_PORTABLE
if (fPatch)
CONSISTENCY_CHECK(CheckPointer(pMT));
- DispatchSlot slot(pMT->FindDispatchSlot(token));
+ DispatchSlot slot(pMT->FindDispatchSlot(token, TRUE /* throwOnConflict */));
if (slot.IsNull() && IsInterfaceToken(token) && pMT->IsComObjectType())
{
MethodDesc * pItfMD = GetInterfaceMethodDescFromToken(token);
CONSISTENCY_CHECK(pItfMD->GetMethodTable()->GetSlot(pItfMD->GetSlot()) == pItfMD->GetMethodEntryPoint());
- slot = pItfMD->GetMethodTable()->FindDispatchSlot(pItfMD->GetSlot());
+ slot = pItfMD->GetMethodTable()->FindDispatchSlot(pItfMD->GetSlot(), TRUE /* throwOnConflict */);
}
return (StubManager::TraceStub(slot.GetTarget(), trace));
PCODE target = NULL;
// TODO: passing NULL as protectedObj here can lead to incorrect behavior for ICastable objects
// We need to review if this is the case and refactor this code if we want ICastable to become officially supported
- VirtualCallStubManager::Resolver(pMT, token, NULL, &target);
+ VirtualCallStubManager::Resolver(pMT, token, NULL, &target, TRUE /* throwOnConflict */);
return pMT->GetMethodDescForSlotAddress(target);
}
static BOOL Resolver(MethodTable * pMT,
DispatchToken token,
OBJECTREF * protectedObj,
- PCODE * ppTarget);
+ PCODE * ppTarget,
+ BOOL throwOnConflict);
// This can be used to find a target without needing the ability to throw
static BOOL TraceResolver(Object *pObj, DispatchToken token, TraceDestination *trace);
static PCODE CacheLookup(size_t token, UINT16 tokenHash, MethodTable *pMT);
// Full exhaustive lookup. THROWS, GC_TRIGGERS
- static PCODE GetTarget(DispatchToken token, MethodTable *pMT);
+ static PCODE GetTarget(DispatchToken token, MethodTable *pMT, BOOL throwOnConflict);
private:
// Given a dispatch token, return true if the token represents an interface, false if just a slot.
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+.assembly extern System.Runtime { }
+
+.assembly ambiguousconstraint { }
+
+.class interface private abstract auto ansi IFoo
+{
+ .method public hidebysig newslot abstract virtual instance void Frob() cil managed
+ {
+ }
+}
+
+.class interface private abstract auto ansi IBar
+ implements IFoo
+{
+ .method public hidebysig newslot virtual final instance void Frob() cil managed
+ {
+ .override IFoo::Frob
+ ret
+ }
+}
+
+.class interface private abstract auto ansi IBaz
+ implements IFoo
+{
+ .method public hidebysig newslot virtual final instance void Frob() cil managed
+ {
+ .override IFoo::Frob
+ ret
+ }
+}
+
+.class private auto ansi beforefieldinit Fooer
+ extends [System.Runtime]System.ValueType
+ implements IBar, IBaz
+{
+}
+
+.class private auto ansi beforefieldinit Gen`1<(IFoo) T>
+ extends [System.Runtime]System.Object
+{
+ .method public hidebysig static int32 Check(!T x) cil managed
+ {
+ .try
+ {
+ ldarga.s 0
+ constrained. !T
+ callvirt instance void IFoo::Frob()
+ leave.s Fail
+ }
+ catch [System.Runtime]System.NotSupportedException
+ {
+ pop
+ leave.s Success
+ }
+ Fail:
+ ldc.i4 -1
+ ret
+ Success:
+ ldc.i4 100
+ ret
+ }
+}
+
+.method public hidebysig static int32 Main() cil managed
+{
+ .entrypoint
+ .locals init (valuetype Fooer)
+ ldloc.0
+ call int32 class Gen`1<valuetype Fooer>::Check(!0)
+ ret
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{85DFC527-4DB1-595E-A7D7-E94EE1F8140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="ambiguousconstraint.il" />
+ </ItemGroup>
+
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
\ No newline at end of file