diff options
author | Eugene Zemtsov <Eugene.Zemtsov@microsoft.com> | 2015-03-18 14:40:26 -0700 |
---|---|---|
committer | Eugene Zemtsov <Eugene.Zemtsov@microsoft.com> | 2015-03-18 14:40:26 -0700 |
commit | d5f60bdffa5507359af953bed646d47f89929c18 (patch) | |
tree | 8bab64ed6d0eebc23cf3179e3fc83b015f8ba623 /src/vm/prestub.cpp | |
parent | 65843fdba94820ce3566396ececdeb8ffd00f09c (diff) | |
download | coreclr-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.cpp | 29 |
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 |