summaryrefslogtreecommitdiff
path: root/src/vm/comdelegate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/comdelegate.cpp')
-rw-r--r--src/vm/comdelegate.cpp275
1 files changed, 49 insertions, 226 deletions
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp
index 4c85a0216e..2682c2d32a 100644
--- a/src/vm/comdelegate.cpp
+++ b/src/vm/comdelegate.cpp
@@ -18,9 +18,6 @@
#include "field.h"
#include "dllimportcallback.h"
#include "dllimport.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeconfig.h"
#include "mdaassistants.h"
#include "cgensys.h"
@@ -280,7 +277,14 @@ VOID GenerateShuffleArray(MethodDesc* pInvoke, MethodDesc *pTargetMeth, SArray<S
COMPlusThrow(kVerificationException);
}
- UINT stackSizeDelta = stackSizeSrc - stackSizeDst;
+ UINT stackSizeDelta;
+
+#ifdef UNIX_X86_ABI
+ // Stack does not shrink as UNIX_X86_ABI uses CDECL (instead of STDCALL).
+ stackSizeDelta = 0;
+#else
+ stackSizeDelta = stackSizeSrc - stackSizeDst;
+#endif
INT ofsSrc, ofsDst;
@@ -919,28 +923,11 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis,
{
_ASSERTE(pRefFirstArg == NULL || *pRefFirstArg == NULL);
-#ifdef FEATURE_REMOTING
- if (!pTargetMethod->IsStatic())
- {
- // Open-instance delegate may have remoted target if the method is declared by
- // an interface, by a type deriving from MarshalByRefObject, or by System.Object.
- // The following condition is necessary but not sufficient as it's always possible
- // to invoke the delegate on a local instance. Precise check would require doing
- // the check at invocation time. We are secure because we demand MemberAccess when
- // there is a possibility that the invocation will be remote.
- //
- MethodTable *pMT = pTargetMethod->GetMethodTable();
- targetPossiblyRemoted = (pMT == g_pObjectClass || pMT->IsInterface() || pMT->IsMarshaledByRef());
- }
-#endif // FEATURE_REMOTING
}
else
{
// closed-static is OK and we can check the target in the closed-instance case
pInstanceMT = (*pRefFirstArg == NULL ? NULL : (*pRefFirstArg)->GetMethodTable());
-#ifdef FEATURE_REMOTING
- targetPossiblyRemoted = InvokeUtil::IsTargetRemoted(pTargetMethod, pInstanceMT);
-#endif
}
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetPossiblyRemoted));
@@ -1098,7 +1085,6 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis,
GCPROTECT_END();
}
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we don't allow non-fulltrust delegates to be marshaled out (or created: CorHost::CreateDelegate ensures that)
// This helper function checks if we have a full-trust delegate with AllowReversePInvokeCallsAttribute targets.
BOOL COMDelegate::IsFullTrustDelegate(DELEGATEREF pDelegate)
@@ -1218,7 +1204,6 @@ BOOL COMDelegate::IsMethodAllowedToSinkReversePInvoke(MethodDesc *pMD)
NULL));
#endif // FEATURE_WINDOWSPHONE
}
-#endif // FEATURE_CORECLR
// Marshals a managed method to an unmanaged callback provided the
// managed method is static and it's parameters require no marshalling.
@@ -1312,7 +1297,6 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj)
MethodTable* pMT = pDelegate->GetMethodTable();
DelegateEEClass* pClass = (DelegateEEClass*)(pMT->GetClass());
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate(pDelegate))
{
@@ -1320,7 +1304,6 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj)
TypeString::AppendType(strDelegateType, pMT, TypeString::FormatNamespace | TypeString::FormatAngleBrackets| TypeString::FormatSignature);
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_1, strDelegateType.GetUnicode());
}
-#endif
if (pMT->HasInstantiation())
COMPlusThrowArgumentException(W("delegate"), W("Argument_NeedNonGenericType"));
@@ -1502,13 +1485,11 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
if (pUMEntryThunk->GetDomainId() != GetAppDomain()->GetId())
COMPlusThrow(kNotSupportedException, W("NotSupported_DelegateMarshalToWrongDomain"));
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate((DELEGATEREF)pDelegate))
{
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_2);
}
-#endif
GCPROTECT_END();
return pDelegate;
@@ -1590,13 +1571,6 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
MethodDesc *pStubMD = pClass->m_pForwardStubMD;
_ASSERTE(pStubMD != NULL && pStubMD->IsILStub());
-#ifndef FEATURE_CORECLR
- if (pStubMD->AsDynamicMethodDesc()->HasCopyCtorArgs())
- {
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-#endif // !FEATURE_CORECLR
#ifdef MDA_SUPPORTED
if (MDA_GET_ASSISTANT(PInvokeStackImbalance))
@@ -1605,16 +1579,6 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
}
#endif // MDA_SUPPORTED
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled() && CallNeedsHostHook((size_t)pCallback))
- {
- pInterceptStub = GenerateStubForHost(
- pMD,
- pStubMD,
- pCallback,
- pInterceptStub);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
@@ -1630,13 +1594,11 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
GCPROTECT_END();
#endif // defined(_TARGET_X86_)
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate(delObj))
{
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_2);
}
-#endif
return delObj;
}
@@ -2182,17 +2144,6 @@ void COMDelegate::DoUnmanagedCodeAccessCheck(MethodDesc* pMeth)
{
// Check whether this is actually a SuppressUnmanagedCodePermission attribute and
// if so, don't do a demand
-#ifndef FEATURE_CORECLR
- MethodTable* pMTMeth = pMeth->GetMethodTable();
- if (pMTMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMethodTable()->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMTMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK)
-#endif
{
return;
}
@@ -2443,29 +2394,8 @@ PCODE COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
ret = COMDelegate::TheDelegateInvokeStub();
}
-#ifdef FEATURE_REMOTING
- else if (pMD == pClass->m_pBeginInvokeMethod)
- {
- CRemotingServices::EnsureRemotingStarted();
-
- if (!ValidateBeginInvoke(pClass))
- COMPlusThrow(kInvalidProgramException);
-
- ret = CTPMethodTable::GetDelegateStubEntryPoint();
- }
- else if (pMD == pClass->m_pEndInvokeMethod)
- {
- CRemotingServices::EnsureRemotingStarted();
-
- if (!ValidateEndInvoke(pClass))
- COMPlusThrow(kInvalidProgramException);
-
- ret = CTPMethodTable::GetDelegateStubEntryPoint();
- }
-#endif // FEATURE_REMOTING
else
{
-#ifndef FEATURE_REMOTING
// Since we do not support asynchronous delegates in CoreCLR, we much ensure that it was indeed a async delegate call
// and not an invalid-delegate-layout condition.
@@ -2476,7 +2406,6 @@ PCODE COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
COMPlusThrow(kPlatformNotSupportedException);
}
-#endif //FEATURE_REMOTING
_ASSERTE(!"Bad Delegate layout");
COMPlusThrow(kInvalidProgramException);
@@ -2555,38 +2484,7 @@ BOOL COMDelegate::NeedsSecureDelegate(MethodDesc* pCreatorMethod, AppDomain *pCr
}
CONTRACTL_END;
-#ifndef FEATURE_CAS_POLICY
return FALSE;
-#else
- if (pCreatorMethod)
- {
- Assembly* pTargetAssembly = pTargetMD->GetAssembly();
- Assembly* pCreatorAssembly = pCreatorMethod->GetAssembly();
- if (pCreatorAssembly != pTargetAssembly)
- {
- // We don't need secure delegate is everything in the AppDomain is full trust.
- if (!pCreatorDomain->GetSecurityDescriptor()->DomainMayContainPartialTrustCode())
- return FALSE;
-
- IAssemblySecurityDescriptor *pCreatorAsd = pCreatorAssembly->GetSecurityDescriptor(pCreatorDomain);
-
- // We should also create secure delegates for anonymously hosted dynamic methods which
- // are themselves full trust (although transparent) yet can be created from partial trust.
- if (!pCreatorAsd->IsFullyTrusted() ||
- pCreatorAssembly->GetDomainAssembly(pCreatorDomain) == pCreatorDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- return TRUE;
- }
-
- // Note that if we begin to support using an NGEN image which is not fully trusted, we may need
- // to force on secure delegates as the grant set of the image may not match between NGEN time
- // and runtime.
- }
- }
-
- return FALSE;
-
-#endif // FEATURE_CAS_POLICY
}
BOOL COMDelegate::NeedsWrapperDelegate(MethodDesc* pTargetMD)
@@ -2928,9 +2826,6 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
}
CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
-#error GetSecureInvoke not implemented
-#else
MethodTable * pDelegateMT = pMD->GetMethodTable();
DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
@@ -2986,7 +2881,6 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
}
return pStub->GetEntryPoint();
-#endif
}
#else // FEATURE_STUBS_AS_IL
PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
@@ -3800,7 +3694,6 @@ BOOL COMDelegate::ValidateSecurityTransparency(MethodDesc *pFtn, MethodTable *pd
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CORECLR
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
return TRUE;
@@ -3811,9 +3704,6 @@ BOOL COMDelegate::ValidateSecurityTransparency(MethodDesc *pFtn, MethodTable *pd
// 1. the delegate is critical and the target method is critical, or
// 2. the delegate is transparent/safecritical and the target method is transparent/safecritical
return (fCriticalDelegate == fCriticalTarget);
-#else
- return TRUE;
-#endif // !FEATURE_CORECLR
}
@@ -4029,13 +3919,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate,
EX_TRY
{
- // We have used both the FEATURE_ defines here since without CSE feature,
- // this aspect of notification feature is pointless. And skipping
- // FEATURE_EXCEPTION_NOTIFICATIONS with only FEATURE_CORRUPTING_EXCEPTIONS
- // specified would enable this change for builds that dont support
- // FEATURE_EXCEPTION_NOTIFICATIONS, like CoreCLR. We dont want that to happen
- // as well.
-#if defined(FEATURE_CORRUPTING_EXCEPTIONS) && defined(FEATURE_EXCEPTION_NOTIFICATIONS)
+#if defined(FEATURE_CORRUPTING_EXCEPTIONS)
BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy();
if (!fCanMethodHandleException)
{
@@ -4067,7 +3951,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate,
}
if (fCanMethodHandleException)
-#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS) && defined(FEATURE_EXCEPTION_NOTIFICATIONS)
+#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS)
{
// We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc,
// as part of wiring up a reliable event sink. Deliver the notification.
@@ -4083,55 +3967,12 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate,
}
-// cannot combine SEH & C++ exceptions in one method. Split out from InvokeNotify.
-static void InvokeNotifyInner(OBJECTREF *pDelegate, OBJECTREF *pDomain)
-{
- // static contract, since we use SEH.
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_MODE_COOPERATIVE;
-
- _ASSERTE(pDelegate != NULL && IsProtectedByGCFrame(pDelegate));
- _ASSERTE(pDomain != NULL && IsProtectedByGCFrame(pDomain));
-
- struct Param : ThreadBaseExceptionFilterParam
- {
- OBJECTREF *pDelegate;
- OBJECTREF *pDomain;
- } param;
- param.location = SystemNotification;
- param.pDelegate = pDelegate;
- param.pDomain = pDomain;
-
- PAL_TRY(Param *, pParam, &param)
- {
- PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(DELEGATEREF(*pParam->pDelegate)->GetMethodPtr());
-
- DECLARE_ARGHOLDER_ARRAY(args, 3);
-
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(DELEGATEREF(*pParam->pDelegate)->GetTarget());
- args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*pParam->pDomain);
- args[ARGNUM_2] = NULL;
-
- CALL_MANAGED_METHOD_NORET(args);
- }
- PAL_EXCEPT_FILTER(ThreadBaseExceptionFilter)
- {
- _ASSERTE(!"ThreadBaseExceptionFilter returned EXECUTE_HANDLER.");
- }
- PAL_ENDTRY;
-}
-
-
-
-// Helper to dispatch a single event notification. If anything goes wrong, we cause
-// an unhandled exception notification to occur out of our first pass, and then we
-// swallow and continue.
+// Helper to dispatch a single event notification.
static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain)
{
CONTRACTL
{
- NOTHROW;
+ THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
@@ -4153,19 +3994,15 @@ static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain)
_ASSERTE(!pThread->HasCriticalRegion());
_ASSERTE(!pThread->HasThreadAffinity());
- EX_TRY
- {
- InvokeNotifyInner(pDelegate, pDomain);
- }
- EX_CATCH
- {
- // It's not even worth asserting, because these aren't our bugs. At
- // some point, a MDA may be warranted.
- // This is an early check for condition that we assert in Thread::InternalReset called from DoOneFinalization later.
- _ASSERTE(!pThread->HasCriticalRegion());
- _ASSERTE(!pThread->HasThreadAffinity());
- }
- EX_END_CATCH(SwallowAllExceptions)
+ PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(DELEGATEREF(*pDelegate)->GetMethodPtr());
+
+ DECLARE_ARGHOLDER_ARRAY(args, 3);
+
+ args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(DELEGATEREF(*pDelegate)->GetTarget());
+ args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*pDomain);
+ args[ARGNUM_2] = NULL;
+
+ CALL_MANAGED_METHOD_NORET(args);
// This is an early check for condition that we assert in Thread::InternalReset called from DoOneFinalization later.
_ASSERTE(!pThread->HasCriticalRegion());
@@ -4173,16 +4010,11 @@ static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain)
}
-// For critical system events, ensure that each handler gets a notification --
-// even if prior handlers in the chain have thrown an exception. Also, try
-// to deliver an unhandled exception event if we ever swallow an exception
-// out of a reliable notification. Note that the add_ event handers are
-// responsible for any reliable preparation of the target, like eager JITting.
-void DistributeEventReliably(OBJECTREF *pDelegate, OBJECTREF *pDomain)
+void DistributeEvent(OBJECTREF *pDelegate, OBJECTREF *pDomain)
{
CONTRACTL
{
- NOTHROW;
+ THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
@@ -4193,51 +4025,42 @@ void DistributeEventReliably(OBJECTREF *pDelegate, OBJECTREF *pDomain)
Thread *pThread = GetThread();
- EX_TRY
+ struct _gc
{
- struct _gc
- {
- PTRARRAYREF Array;
- OBJECTREF InnerDelegate;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
+ PTRARRAYREF Array;
+ OBJECTREF InnerDelegate;
+ } gc;
+ ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
+ GCPROTECT_BEGIN(gc);
- gc.Array = (PTRARRAYREF) ((DELEGATEREF)(*pDelegate))->GetInvocationList();
- if (gc.Array == NULL || !gc.Array->GetMethodTable()->IsArray())
- {
- InvokeNotify(pDelegate, pDomain);
- }
- else
- {
- // The _invocationCount could be less than the array size, if we are sharing
- // immutable arrays cleverly.
- INT_PTR invocationCount = ((DELEGATEREF)(*pDelegate))->GetInvocationCount();
+ gc.Array = (PTRARRAYREF) ((DELEGATEREF)(*pDelegate))->GetInvocationList();
+ if (gc.Array == NULL || !gc.Array->GetMethodTable()->IsArray())
+ {
+ InvokeNotify(pDelegate, pDomain);
+ }
+ else
+ {
+ // The _invocationCount could be less than the array size, if we are sharing
+ // immutable arrays cleverly.
+ INT_PTR invocationCount = ((DELEGATEREF)(*pDelegate))->GetInvocationCount();
- _ASSERTE(FitsInU4(invocationCount));
- DWORD cnt = static_cast<DWORD>(invocationCount);
+ _ASSERTE(FitsInU4(invocationCount));
+ DWORD cnt = static_cast<DWORD>(invocationCount);
- _ASSERTE(cnt <= gc.Array->GetNumComponents());
+ _ASSERTE(cnt <= gc.Array->GetNumComponents());
- for (DWORD i=0; i<cnt; i++)
+ for (DWORD i=0; i<cnt; i++)
+ {
+ gc.InnerDelegate = gc.Array->m_Array[i];
+ InvokeNotify(&gc.InnerDelegate, pDomain);
+ if (pThread->IsAbortRequested())
{
- gc.InnerDelegate = gc.Array->m_Array[i];
- InvokeNotify(&gc.InnerDelegate, pDomain);
- if (pThread->IsAbortRequested())
- {
- pThread->UnmarkThreadForAbort(Thread::TAR_Thread);
- }
+ pThread->UnmarkThreadForAbort(Thread::TAR_Thread);
}
}
- GCPROTECT_END();
}
- EX_CATCH
- {
- // It's not even worth asserting, because these aren't our bugs. At
- // some point, a MDA may be warranted.
- }
- EX_END_CATCH(SwallowAllExceptions)
+ GCPROTECT_END();
}
// The unhandled exception event is a little easier to distribute, because