diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2018-11-15 14:08:27 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-15 14:08:27 +0100 |
commit | 4b01ac0d72d2b271a3f664d1fe3761287f5efc6a (patch) | |
tree | ce702363d5b1a61f3783f8fc1e27dc182f71f8d6 /src/vm/methodtable.cpp | |
parent | bf1a55fab3f07771632a76d52c6d9287a339bb79 (diff) | |
download | coreclr-4b01ac0d72d2b271a3f664d1fe3761287f5efc6a.tar.gz coreclr-4b01ac0d72d2b271a3f664d1fe3761287f5efc6a.tar.bz2 coreclr-4b01ac0d72d2b271a3f664d1fe3761287f5efc6a.zip |
Allow supressing exceptions in diamond inheritance cases (#20458)
Diffstat (limited to 'src/vm/methodtable.cpp')
-rw-r--r-- | src/vm/methodtable.cpp | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp index 57f24959fa..b80f1e886d 100644 --- a/src/vm/methodtable.cpp +++ b/src/vm/methodtable.cpp @@ -799,7 +799,7 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule TypeHandle resulTypeHnd = resultTypeObj->GetType(); MethodTable *pResultMT = resulTypeHnd.GetMethodTable(); - RETURN(pResultMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD)); + RETURN(pResultMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */)); } #endif @@ -820,7 +820,7 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule #endif // !FEATURE_COMINTEROP // Handle pure COM+ types. - RETURN (pServerMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD)); + RETURN (pServerMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */)); } #ifdef FEATURE_COMINTEROP @@ -858,7 +858,7 @@ MethodDesc *MethodTable::GetMethodDescForComInterfaceMethod(MethodDesc *pItfMD, // 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) { @@ -2076,7 +2076,7 @@ BOOL MethodTable::ImplementsEquivalentInterface(MethodTable *pInterface) } //========================================================================================== -MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceMD) +MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceMD, BOOL throwOnConflict) { CONTRACTL { @@ -2087,11 +2087,11 @@ MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(MethodDesc *pInterfaceM 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 { @@ -2109,17 +2109,27 @@ MethodDesc *MethodTable::GetMethodDescForInterfaceMethod(TypeHandle ownerType, M 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 @@ -6918,7 +6928,8 @@ BOOL MethodTable::FindDispatchImpl( UINT32 typeID, UINT32 slotNumber, - DispatchSlot * pImplSlot) + DispatchSlot * pImplSlot, + BOOL throwOnConflict) { CONTRACT (BOOL) { INSTANCE_CHECK; @@ -7001,7 +7012,8 @@ MethodTable::FindDispatchImpl( 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()); @@ -7080,7 +7092,8 @@ void ThrowExceptionForConflictingOverride( BOOL MethodTable::FindDefaultInterfaceImplementation( MethodDesc *pInterfaceMD, MethodTable *pInterfaceMT, - MethodDesc **ppDefaultMethod + MethodDesc **ppDefaultMethod, + BOOL throwOnConflict ) { CONTRACT(BOOL) { @@ -7313,7 +7326,11 @@ BOOL MethodTable::FindDefaultInterfaceImplementation( } else if (pBestCandidateMT != candidates[i].pMT) { - ThrowExceptionForConflictingOverride(this, pInterfaceMT, pInterfaceMD); + if (throwOnConflict) + ThrowExceptionForConflictingOverride(this, pInterfaceMT, pInterfaceMD); + + *ppDefaultMethod = NULL; + RETURN(FALSE); } } @@ -7331,17 +7348,17 @@ BOOL MethodTable::FindDefaultInterfaceImplementation( #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 { @@ -7351,28 +7368,28 @@ DispatchSlot MethodTable::FindDispatchSlot(DispatchToken tok) 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); } //========================================================================================== @@ -9859,7 +9876,7 @@ MethodTable::TryResolveConstraintMethodApprox( 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()) @@ -9890,9 +9907,8 @@ MethodTable::TryResolveConstraintMethodApprox( 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; } } @@ -9910,7 +9926,7 @@ MethodTable::TryResolveConstraintMethodApprox( // 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")); |