summaryrefslogtreecommitdiff
path: root/src/vm/prestub.cpp
diff options
context:
space:
mode:
authorEugene Zemtsov <Eugene.Zemtsov@microsoft.com>2015-03-18 14:40:26 -0700
committerEugene Zemtsov <Eugene.Zemtsov@microsoft.com>2015-03-18 14:40:26 -0700
commitd5f60bdffa5507359af953bed646d47f89929c18 (patch)
tree8bab64ed6d0eebc23cf3179e3fc83b015f8ba623 /src/vm/prestub.cpp
parent65843fdba94820ce3566396ececdeb8ffd00f09c (diff)
downloadcoreclr-d5f60bdffa5507359af953bed646d47f89929c18.tar.gz
coreclr-d5f60bdffa5507359af953bed646d47f89929c18.tar.bz2
coreclr-d5f60bdffa5507359af953bed646d47f89929c18.zip
Implement runtime support for ICastable interface
The goal of this change is to facilitate an alternative (MCG based) way of doing COM interop, we're going to use it on Unix platforms. New ICastable interface allows objects to pretend at runtime that they support an interface and to provide an alternative type that is used to resolve actual calls to interface methods. BE VERY CAREFUL: This is a very dangerous feature, and at this stage it can easily lead to memory corruption without any native code involved. Reviewers: Yi Zhang, Noah Falk, Jan Kotas. DDR clean. [tfs-changeset: 1435198]
Diffstat (limited to 'src/vm/prestub.cpp')
-rw-r--r--src/vm/prestub.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index a2e6fd3b37..79c34d27da 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -984,6 +984,26 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, Metho
{
pDispatchingMT = curobj->GetTrueMethodTable();
+#ifdef FEATURE_ICASTABLE
+ if (pDispatchingMT->IsICastable())
+ {
+ MethodTable *pMDMT = pMD->GetMethodTable();
+ TypeHandle objectType(pDispatchingMT);
+ TypeHandle methodType(pMDMT);
+
+ GCStress<cfg_any>::MaybeTrigger();
+ INDEBUG(curobj = NULL); // curobj is unprotected and CanCastTo() can trigger GC
+ if (!objectType.CanCastTo(methodType))
+ {
+ // Apperantly ICastable magic was involved when we chose this method to be called
+ // that's why we better stick to the MethodTable it belongs to, otherwise
+ // DoPrestub() will fail not being able to find implementation for pMD in pDispatchingMT.
+
+ pDispatchingMT = pMDMT;
+ }
+ }
+#endif // FEATURE_ICASTABLE
+
// For value types, the only virtual methods are interface implementations.
// Thus pDispatching == pMT because there
// is no inheritance in value types. Note the BoxedEntryPointStubs are shared
@@ -1958,13 +1978,14 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl
else
token = DispatchToken::CreateDispatchToken(slot);
- OBJECTREF pObj = pEMFrame->GetThis();
- if (pObj == NULL) {
+ OBJECTREF *protectedObj = pEMFrame->GetThisPtr();
+ _ASSERTE(protectedObj != NULL);
+ if (*protectedObj == NULL) {
COMPlusThrow(kNullReferenceException);
}
-
+
StubCallSite callSite(pIndirection, pEMFrame->GetReturnAddress());
- pCode = pMgr->ResolveWorker(&callSite, pObj, token, VirtualCallStubManager::SK_LOOKUP);
+ pCode = pMgr->ResolveWorker(&callSite, protectedObj, token, VirtualCallStubManager::SK_LOOKUP);
_ASSERTE(pCode != NULL);
}
else