diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index a913fca431da0a..902cf48c558728 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1492,6 +1492,156 @@ internal static void SetPendingExceptionObject(Exception? exception) [SupportedOSPlatform("windows")] internal static object GetIEnumeratorToEnumVariantMarshaler() => EnumeratorToEnumVariantMarshaler.GetInstance(string.Empty); + private const int DispatchExPropertyCanRead = 1; + private const int DispatchExPropertyCanWrite = 2; + + [SupportedOSPlatform("windows")] + [UnmanagedCallersOnly] + private static unsafe void GetDispatchExPropertyFlags(PropertyInfo* pMemberInfo, int* pResult, Exception* pException) + { + try + { + int result = 0; + PropertyInfo property = *pMemberInfo; + if (property.CanRead) + { + result |= DispatchExPropertyCanRead; + } + + if (property.CanWrite) + { + result |= DispatchExPropertyCanWrite; + } + + *pResult = result; + } + catch (Exception ex) + { + *pException = ex; + } + } + + [SupportedOSPlatform("windows")] + [UnmanagedCallersOnly] + private static unsafe void CallICustomQueryInterface(ICustomQueryInterface* pObject, Guid* pIid, IntPtr* ppObject, int* pResult, Exception* pException) + { + try + { + *pResult = (int)pObject->GetInterface(ref *pIid, out *ppObject); + } + catch (Exception ex) + { + *pException = ex; + } + } + + private static unsafe ulong InvokeArgSlotMethodWithOneArg(object target, RuntimeMethodHandle methodHandle, nint methodEntryPoint, object? arg0) + { + IRuntimeMethodInfo methodInfo = methodHandle.GetMethodInfo(); + Signature signature = new(methodInfo, RuntimeMethodHandle.GetDeclaringType(methodInfo)); + RuntimeType returnType = signature.ReturnType; + Debug.Assert(methodEntryPoint != 0); + + if (returnType == typeof(void)) + { + ((delegate*)methodEntryPoint)(target, arg0); + return 0; + } + + if (returnType == typeof(bool)) + { + return ((delegate*)methodEntryPoint)(target, arg0) ? 1UL : 0UL; + } + + if (returnType == typeof(int)) + { + return unchecked((ulong)((delegate*)methodEntryPoint)(target, arg0)); + } + + if (returnType == typeof(uint)) + { + return ((delegate*)methodEntryPoint)(target, arg0); + } + + if (returnType == typeof(long)) + { + return unchecked((ulong)((delegate*)methodEntryPoint)(target, arg0)); + } + + if (returnType == typeof(ulong)) + { + return ((delegate*)methodEntryPoint)(target, arg0); + } + + if (returnType == typeof(IntPtr)) + { + return (ulong)(nuint)((delegate*)methodEntryPoint)(target, arg0); + } + + if (returnType == typeof(UIntPtr)) + { + return (ulong)((delegate*)methodEntryPoint)(target, arg0); + } + + throw new NotSupportedException(); + } + + [SupportedOSPlatform("windows")] + [UnmanagedCallersOnly] + private static unsafe void InvokeConnectionPointProviderMethod( + object* pProvider, + IntPtr pProviderMethodPtr, + object* pDelegate, + IntPtr pDelegateCtorMethodPtr, + object* pSubscriber, + IntPtr pEventMethodCodePtr, + bool useUIntPtrCtor, + Exception* pException) + { + try + { + nint delegateCtorMethodEntryPoint = (nint)pDelegateCtorMethodPtr; + Debug.Assert(delegateCtorMethodEntryPoint != 0); + + // Construct the delegate before invoking the provider method. + if (useUIntPtrCtor) + { + ((delegate*)delegateCtorMethodEntryPoint)(*pDelegate, *pSubscriber, (nuint)pEventMethodCodePtr); + } + else + { + ((delegate*)delegateCtorMethodEntryPoint)(*pDelegate, *pSubscriber, (nint)pEventMethodCodePtr); + } + + nint providerMethodEntryPoint = (nint)pProviderMethodPtr; + Debug.Assert(providerMethodEntryPoint != 0); + ((delegate*)providerMethodEntryPoint)(*pProvider, *pDelegate); + } + catch (Exception ex) + { + *pException = ex; + } + } + + [SupportedOSPlatform("windows")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2062:Value passed to parameter cannot be statically determined", Justification = "The runtime passes a RuntimeType describing the COM event provider. The dynamic constructor access requirements are enforced by runtime callsite semantics.")] + [UnmanagedCallersOnly] + // pResult is an unmanaged ARG_SLOT* (see vm/callhelpers.h). ARG_SLOT is always 8 bytes, + // so we use ulong purely as a fixed-width bit container, not for numeric semantics. + private static unsafe void InvokeClrToComEventProviderMethod(__ComObject* pComObject, RuntimeType* pProviderType, IntPtr pMethodDesc, IntPtr pMethodEntryPoint, Delegate* pEventHandler, ulong* pResult, Exception* pException) + { + try + { + object eventProvider = pComObject->GetEventProvider(*pProviderType); + RuntimeMethodHandle methodHandle = RuntimeMethodHandle.FromIntPtr(pMethodDesc); + *pResult = InvokeArgSlotMethodWithOneArg(eventProvider, methodHandle, (nint)pMethodEntryPoint, *pEventHandler); + } + catch (Exception ex) + { + *pException = ex; + } + } + [SupportedOSPlatform("windows")] [UnmanagedCallersOnly] private static unsafe void GetIEnumeratorToEnumVariantMarshaler(object* pResult, Exception* pException) diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h index 9894f59da8f482..13d1ee37a8d3cd 100644 --- a/src/coreclr/vm/class.h +++ b/src/coreclr/vm/class.h @@ -1468,16 +1468,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! GetOptionalFields()->m_pCoClassForIntf = th; } - OBJECTHANDLE GetOHDelegate() - { - LIMITED_METHOD_CONTRACT; - return m_ohDelegate; - } - void SetOHDelegate (OBJECTHANDLE _ohDelegate) - { - LIMITED_METHOD_CONTRACT; - m_ohDelegate = _ohDelegate; - } // Set the COM interface type. CorIfaceAttr GetComInterfaceType() { @@ -1688,16 +1678,8 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! PTR_MethodDescChunk m_pChunks; #ifdef FEATURE_COMINTEROP - union - { - // For CLR wrapper objects that extend an unmanaged class, this field - // may contain a delegate to be called to allocate the aggregated - // unmanaged class (instead of using CoCreateInstance). - OBJECTHANDLE m_ohDelegate; - - // For interfaces this contains the COM interface type. - CorIfaceAttr m_ComInterfaceType; - }; + // For interfaces this contains the COM interface type. + CorIfaceAttr m_ComInterfaceType; ComCallWrapperTemplate *m_pccwTemplate; // points to interop data structures used when this type is exposed to COM #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/vm/clrtocomcall.cpp b/src/coreclr/vm/clrtocomcall.cpp index 3a2373b8e8735b..a6e3f0a4c07b55 100644 --- a/src/coreclr/vm/clrtocomcall.cpp +++ b/src/coreclr/vm/clrtocomcall.cpp @@ -297,11 +297,9 @@ UINT32 CLRToCOMEventCallWorker(CLRToCOMMethodFrame* pFrame, CLRToCOMCallMethodDe struct { OBJECTREF EventProviderTypeObj; - OBJECTREF EventProviderObj; OBJECTREF ThisObj; } gc; gc.EventProviderTypeObj = NULL; - gc.EventProviderObj = NULL; gc.ThisObj = NULL; LOG((LF_STUBS, LL_INFO1000, "Calling CLRToCOMEventCallWorker %s::%s \n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); @@ -316,32 +314,28 @@ UINT32 CLRToCOMEventCallWorker(CLRToCOMMethodFrame* pFrame, CLRToCOMCallMethodDe gc.EventProviderTypeObj = pEvProvMT->GetManagedClassObject(); gc.ThisObj = pFrame->GetThis(); - UnmanagedCallersOnlyCaller getEventProvider(METHOD__COM_OBJECT__GET_EVENT_PROVIDER); - - // Retrieve the event provider for the event interface type. - getEventProvider.InvokeThrowing(&gc.ThisObj, &gc.EventProviderTypeObj, &gc.EventProviderObj); - // Set up an arg iterator to retrieve the arguments from the frame. MetaSig mSig(pMD); ArgIterator ArgItr(&mSig); - // Make the call on the event provider method desc. - MethodDescCallSite eventProvider(pEvProvMD, &gc.EventProviderObj); - // Retrieve the event handler passed in. OBJECTREF EventHandlerObj = ObjectToOBJECTREF(*(Object**)(pFrame->GetTransitionBlock() + ArgItr.GetNextOffset())); - ARG_SLOT EventMethArgs[] = - { - ObjToArgSlot(gc.EventProviderObj), - ObjToArgSlot(EventHandlerObj) - }; + ARG_SLOT eventProviderResult = 0; + UnmanagedCallersOnlyCaller invokeClrToComEventProviderMethod(METHOD__STUBHELPERS__INVOKE_CLR_TO_COM_EVENT_PROVIDER_METHOD); + invokeClrToComEventProviderMethod.InvokeThrowing( + &gc.ThisObj, + &gc.EventProviderTypeObj, + (INT_PTR)pEvProvMD, + (INT_PTR)pEvProvMD->GetMultiCallableAddrOfCode(), + &EventHandlerObj, + &eventProviderResult); // // If this can ever return something bigger than an INT64 byval // then this code is broken. Currently, however, it cannot. // - *(ARG_SLOT *)(pFrame->GetReturnValuePtr()) = eventProvider.Call_RetArgSlot(EventMethArgs); + *(ARG_SLOT *)(pFrame->GetReturnValuePtr()) = eventProviderResult; // The COM event call worker does not support value returned in // floating point registers. diff --git a/src/coreclr/vm/comcallablewrapper.cpp b/src/coreclr/vm/comcallablewrapper.cpp index 1b0c6eea5a4e45..dfb83a20d95d75 100644 --- a/src/coreclr/vm/comcallablewrapper.cpp +++ b/src/coreclr/vm/comcallablewrapper.cpp @@ -2340,22 +2340,13 @@ VOID __stdcall InvokeICustomQueryInterfaceGetInterface_CallBack(LPVOID ptr) GCPROTECT_BEGIN(pObj); - // 1. Get MD - MethodDesc *pMD = pArgs->pWrap->GetSimpleWrapper()->GetComCallWrapperTemplate()->GetICustomQueryInterfaceGetInterfaceMD(); + INT_PTR queriedInterface = reinterpret_cast(*pArgs->ppUnk); + INT32 result = static_cast(CustomQueryInterfaceResult::NotHandled); + UnmanagedCallersOnlyCaller callICustomQueryInterface(METHOD__STUBHELPERS__CALL_ICUSTOM_QUERY_INTERFACE); + callICustomQueryInterface.InvokeThrowing(&pObj, pArgs->pGuid, &queriedInterface, &result); - // 2. Get Object Handle - OBJECTHANDLE hndCustomQueryInterface = pArgs->pWrap->GetObjectHandle(); - - // 3 construct the MethodDescCallSite - MethodDescCallSite GetInterface(pMD, hndCustomQueryInterface); - - ARG_SLOT Args[] = { - ObjToArgSlot(pObj), - PtrToArgSlot(pArgs->pGuid), - PtrToArgSlot(pArgs->ppUnk), - }; - - *(pArgs->pRetVal) = (CustomQueryInterfaceResult)GetInterface.Call_RetArgSlot(Args); + *pArgs->ppUnk = reinterpret_cast(queriedInterface); + *(pArgs->pRetVal) = (CustomQueryInterfaceResult)result; GCPROTECT_END(); } } @@ -4674,7 +4665,6 @@ ComCallWrapperTemplate* ComCallWrapperTemplate::CreateTemplate(TypeHandle thClas pTemplate->m_pClassComMT = NULL; // Defer setting this up. pTemplate->m_pBasicComMT = NULL; pTemplate->m_pDefaultItf = NULL; - pTemplate->m_pICustomQueryInterfaceGetInterfaceMD = NULL; pTemplate->m_flags = 0; // Determine the COM visibility of classes in our hierarchy. @@ -4794,7 +4784,6 @@ ComCallWrapperTemplate *ComCallWrapperTemplate::CreateTemplateForInterface(Metho pTemplate->m_pClassComMT = NULL; pTemplate->m_pBasicComMT = NULL; pTemplate->m_pDefaultItf = pItfMT; - pTemplate->m_pICustomQueryInterfaceGetInterfaceMD = NULL; pTemplate->m_flags = enum_RepresentsVariantInterface; // Initialize the one ComMethodTable @@ -4928,24 +4917,6 @@ ComMethodTable *ComCallWrapperTemplate::SetupComMethodTableForClass(MethodTable } -MethodDesc * ComCallWrapperTemplate::GetICustomQueryInterfaceGetInterfaceMD() -{ - CONTRACT (MethodDesc*) - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(m_flags & enum_ImplementsICustomQueryInterface); - } - CONTRACT_END; - - if (m_pICustomQueryInterfaceGetInterfaceMD == NULL) - m_pICustomQueryInterfaceGetInterfaceMD = m_thClass.GetMethodTable()->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_QUERYINTERFACE__GET_INTERFACE), - TRUE /* throwOnConflict */); - RETURN m_pICustomQueryInterfaceGetInterfaceMD; -} - //-------------------------------------------------------------------------- // Module* ComCallMethodDesc::GetModule() // Get Module diff --git a/src/coreclr/vm/comcallablewrapper.h b/src/coreclr/vm/comcallablewrapper.h index 64292714243b37..9b0b4bb93ee7f1 100644 --- a/src/coreclr/vm/comcallablewrapper.h +++ b/src/coreclr/vm/comcallablewrapper.h @@ -235,8 +235,6 @@ class ComCallWrapperTemplate // Sets up the class method table for the IClassX and also lays it out. static ComMethodTable *SetupComMethodTableForClass(MethodTable *pMT, BOOL bLayOutComMT); - MethodDesc * GetICustomQueryInterfaceGetInterfaceMD(); - BOOL HasInvisibleParent() { LIMITED_METHOD_CONTRACT; @@ -328,7 +326,6 @@ class ComCallWrapperTemplate enum_IsSafeTypeForMarshalling = 0x2000, // The class can be safely marshalled out of process via DCOM }; DWORD m_flags; - MethodDesc* m_pICustomQueryInterfaceGetInterfaceMD; ULONG m_cbInterfaces; SLOT* m_rgpIPtr[1]; }; diff --git a/src/coreclr/vm/comconnectionpoints.cpp b/src/coreclr/vm/comconnectionpoints.cpp index 6442c534436567..b90147c64efdc3 100644 --- a/src/coreclr/vm/comconnectionpoints.cpp +++ b/src/coreclr/vm/comconnectionpoints.cpp @@ -539,7 +539,23 @@ void ConnectionPoint::InvokeProviderMethod( OBJECTREF pProvider, OBJECTREF pSubs // Retrieve the EE class representing the argument. MethodTable *pDelegateCls = MethodSig.GetLastTypeHandleThrowing().GetMethodTable(); - // Make sure we activate the assembly containing the target method desc + // Initialize the delegate using the arguments structure. + // Generics: ensure we get the right MethodDesc here and in similar places + // Accept both void (object, native int) and void (object, native uint) + MethodDesc *pDlgCtorMD = MemberLoader::FindConstructor(pDelegateCls, &gsig_IM_Obj_IntPtr_RetVoid); + BOOL useUIntPtrCtor = FALSE; + if (pDlgCtorMD == NULL) + { + pDlgCtorMD = MemberLoader::FindConstructor(pDelegateCls, &gsig_IM_Obj_UIntPtr_RetVoid); + useUIntPtrCtor = TRUE; + } + + // The loader is responsible for only accepting well-formed delegate classes. + _ASSERTE(pDlgCtorMD); + + // Make sure we activate assemblies containing target method descs. + pProvMethodDesc->EnsureActive(); + pDlgCtorMD->EnsureActive(); pEventMethodDesc->EnsureActive(); // Allocate an object based on the method table of the delegate class. @@ -547,29 +563,17 @@ void ConnectionPoint::InvokeProviderMethod( OBJECTREF pProvider, OBJECTREF pSubs GCPROTECT_BEGIN( pDelegate ); { - // Initialize the delegate using the arguments structure. - // Generics: ensure we get the right MethodDesc here and in similar places - // Accept both void (object, native int) and void (object, native uint) - MethodDesc *pDlgCtorMD = MemberLoader::FindConstructor(pDelegateCls, &gsig_IM_Obj_IntPtr_RetVoid); - if (pDlgCtorMD == NULL) - pDlgCtorMD = MemberLoader::FindConstructor(pDelegateCls, &gsig_IM_Obj_UIntPtr_RetVoid); - - // The loader is responsible for only accepting well-formed delegate classes. - _ASSERTE(pDlgCtorMD); - - MethodDescCallSite dlgCtor(pDlgCtorMD); - - ARG_SLOT CtorArgs[3] = { ObjToArgSlot(pDelegate), - ObjToArgSlot(pSubscriber), - (ARG_SLOT)pEventMethodDesc->GetMultiCallableAddrOfCode() - }; - dlgCtor.Call(CtorArgs); - - MethodDescCallSite prov(pProvMethodDesc, &pProvider); - - // Do the actual invocation of the method method. - ARG_SLOT Args[2] = { ObjToArgSlot( pProvider ), ObjToArgSlot( pDelegate ) }; - prov.Call(Args); + UnmanagedCallersOnlyCaller invokeConnectionPointProviderMethod(METHOD__STUBHELPERS__INVOKE_CONNECTION_POINT_PROVIDER_METHOD); + + // Construct the delegate and invoke the provider method in one helper. + invokeConnectionPointProviderMethod.InvokeThrowing( + &pProvider, + (INT_PTR)pProvMethodDesc->GetMultiCallableAddrOfCode(), + &pDelegate, + (INT_PTR)pDlgCtorMD->GetMultiCallableAddrOfCode(), + &pSubscriber, + (INT_PTR)pEventMethodDesc->GetMultiCallableAddrOfCode(), + CLR_BOOL_ARG(useUIntPtrCtor)); } GCPROTECT_END(); } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 04042375bb9496..ff05596ee2e635 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1047,6 +1047,10 @@ DEFINE_METHOD(STUBHELPERS, GET_PENDING_EXCEPTION_OBJECT, GetPendingExce DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER, CreateCustomMarshaler, SM_IntPtr_Int_IntPtr_RetObj) #ifdef FEATURE_COMINTEROP DEFINE_METHOD(STUBHELPERS, GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER, GetIEnumeratorToEnumVariantMarshaler, SM_PtrObj_PtrException_RetVoid) +DEFINE_METHOD(STUBHELPERS, GET_DISPATCH_EX_PROPERTY_FLAGS, GetDispatchExPropertyFlags, SM_PtrPropertyInfo_PtrInt_PtrException_RetVoid) +DEFINE_METHOD(STUBHELPERS, CALL_ICUSTOM_QUERY_INTERFACE, CallICustomQueryInterface, SM_PtrICustomQueryInterface_PtrGuid_PtrIntPtr_PtrInt_PtrException_RetVoid) +DEFINE_METHOD(STUBHELPERS, INVOKE_CONNECTION_POINT_PROVIDER_METHOD, InvokeConnectionPointProviderMethod, SM_PtrObj_IntPtr_PtrObj_IntPtr_PtrObj_IntPtr_Bool_PtrException_RetVoid) +DEFINE_METHOD(STUBHELPERS, INVOKE_CLR_TO_COM_EVENT_PROVIDER_METHOD, InvokeClrToComEventProviderMethod, SM_PtrComObject_PtrClass_IntPtr_IntPtr_PtrDelegate_PtrULong_PtrException_RetVoid) #endif // FEATURE_COMINTEROP DEFINE_METHOD(STUBHELPERS, CHECK_STRING_LENGTH, CheckStringLength, SM_Int_RetVoid) diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 1f7c410c9d083b..294e7cbbceb472 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -214,6 +214,11 @@ DEFINE_METASIG(SM(RefByte_RefByte_UIntPtr_RetVoid, r(b) r(b) U, v)) DEFINE_METASIG(SM(RefByte_Byte_UIntPtr_RetVoid, r(b) b U, v)) DEFINE_METASIG(SM(RefByte_UIntPtr_RetVoid, r(b) U, v)) DEFINE_METASIG(SM(PtrVoid_Byte_UInt_RetVoid, P(v) b K, v)) +#ifdef FEATURE_COMINTEROP +DEFINE_METASIG_T(SM(PtrICustomQueryInterface_PtrGuid_PtrIntPtr_PtrInt_PtrException_RetVoid, P(C(ICUSTOM_QUERYINTERFACE)) P(g(GUID)) P(I) P(i) P(C(EXCEPTION)), v)) +#endif // FEATURE_COMINTEROP +DEFINE_METASIG_T(SM(PtrObj_IntPtr_PtrObj_IntPtr_PtrObj_IntPtr_Bool_PtrException_RetVoid, P(j) I P(j) I P(j) I F P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrPropertyInfo_PtrInt_PtrException_RetVoid, P(C(PROPERTY_INFO)) P(i) P(C(EXCEPTION)), v)) DEFINE_METASIG(SM(IntPtr_RefObj_IntPtr_RetVoid, I r(j) I, v)) DEFINE_METASIG(SM(IntPtr_RefObj_IntPtr_Int_RetVoid, I r(j) I i,v)) DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Int_IntPtr_RetVoid, I I i i I, v)) @@ -431,6 +436,8 @@ DEFINE_METASIG_T(SM(PtrResolver_Int_PtrStr_PtrException_RetVoid, P(C(RESOLVER)) #ifdef FEATURE_COMINTEROP DEFINE_METASIG_T(SM(PtrClass_PtrStr_Int_PtrObj_PtrArrObj_PtrArrBool_PtrArrInt_PtrArrType_PtrType_PtrObj_PtrException_RetVoid, P(C(CLASS)) P(s) i P(j) P(a(j)) P(a(F)) P(a(i)) P(a(C(TYPE))) P(C(TYPE)) P(j) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrComObject_PtrClass_PtrObj_PtrException_RetVoid, P(C(COM_OBJECT)) P(C(CLASS)) P(j) P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrComObject_PtrClass_IntPtr_PtrDelegate_PtrULong_PtrException_RetVoid, P(C(COM_OBJECT)) P(C(CLASS)) I P(C(DELEGATE)) P(L) P(C(EXCEPTION)), v)) +DEFINE_METASIG_T(SM(PtrComObject_PtrClass_IntPtr_IntPtr_PtrDelegate_PtrULong_PtrException_RetVoid, P(C(COM_OBJECT)) P(C(CLASS)) I I P(C(DELEGATE)) P(L) P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrLicenseInteropProxy_IntPtr_PtrException_RetVoid, P(C(LICENSE_INTEROP_PROXY)) I P(C(EXCEPTION)), v)) DEFINE_METASIG_T(SM(PtrLicenseInteropProxy_PtrType_PtrBool_PtrIntPtr_PtrException_RetVoid, P(C(LICENSE_INTEROP_PROXY)) P(C(TYPE)) P(F) P(I) P(C(EXCEPTION)), v)) #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 9d609123829ca0..0234a880c986fe 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -708,44 +708,6 @@ MethodTable* CreateMinimalMethodTable(Module* pContainingModule, return pMT; } - -#ifdef FEATURE_COMINTEROP -//========================================================================================== -OBJECTREF MethodTable::GetObjCreateDelegate() -{ - CONTRACTL - { - MODE_COOPERATIVE; - GC_NOTRIGGER; - NOTHROW; - } - CONTRACTL_END; - _ASSERT(!IsInterface()); - if (GetOHDelegate()) - return ObjectFromHandle(GetOHDelegate()); - else - return NULL; -} - -//========================================================================================== -void MethodTable::SetObjCreateDelegate(OBJECTREF orDelegate) -{ - CONTRACTL - { - MODE_COOPERATIVE; - GC_NOTRIGGER; - THROWS; // From CreateHandle - } - CONTRACTL_END; - - if (GetOHDelegate()) - StoreObjectInHandle(GetOHDelegate(), orDelegate); - else - SetOHDelegate (GetAppDomain()->CreateHandle(orDelegate)); -} -#endif // FEATURE_COMINTEROP - - //========================================================================================== void MethodTable::SetInterfaceMap(WORD wNumInterfaces, InterfaceInfo_t* iMap) { @@ -4888,22 +4850,6 @@ BOOL MethodTable::IsExtensibleRCW() return IsComObjectType() && !GetClass()->IsComImport(); } -//========================================================================================== -OBJECTHANDLE MethodTable::GetOHDelegate() -{ - WRAPPER_NO_CONTRACT; - _ASSERTE(GetClass()); - return GetClass()->GetOHDelegate(); -} - -//========================================================================================== -void MethodTable::SetOHDelegate (OBJECTHANDLE _ohDelegate) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(GetClass()); - GetClass()->SetOHDelegate(_ohDelegate); -} - //========================================================================================== // Helper to skip over COM class in the hierarchy MethodTable* MethodTable::GetComPlusParentMethodTable() diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index b99dcb293337be..23cc148a09fe57 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -1027,9 +1027,6 @@ class MethodTable CorIfaceAttr GetComInterfaceType(); void SetComInterfaceType(CorIfaceAttr ItfType); - OBJECTHANDLE GetOHDelegate(); - void SetOHDelegate (OBJECTHANDLE _ohDelegate); - CorClassIfaceAttr GetComClassInterfaceType(); TypeHandle GetDefItfForComClassItf(); @@ -1062,9 +1059,6 @@ class MethodTable BOOL SetComClassFactory(ClassFactoryBase *pFactory); #endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION - OBJECTREF GetObjCreateDelegate(); - void SetObjCreateDelegate(OBJECTREF orDelegate); - private: // This is for COM Interop backwards compatibility BOOL InsertComInteropData(InteropMethodTableData *pData); diff --git a/src/coreclr/vm/runtimecallablewrapper.cpp b/src/coreclr/vm/runtimecallablewrapper.cpp index 076a4a043fa7af..24d621a5dc37de 100644 --- a/src/coreclr/vm/runtimecallablewrapper.cpp +++ b/src/coreclr/vm/runtimecallablewrapper.cpp @@ -276,9 +276,6 @@ OBJECTREF ComClassFactory::CreateAggregatedInstance(MethodTable* pMTClass, BOOL HRESULT hr = S_OK; NewRCWHolder pNewRCW; - BOOL bUseDelegate = FALSE; - - MethodTable *pCallbackMT = NULL; OBJECTREF oref = NULL; COMOBJECTREF cref = NULL; @@ -289,68 +286,14 @@ OBJECTREF ComClassFactory::CreateAggregatedInstance(MethodTable* pMTClass, BOOL //get wrapper for the object, this could enable GC CCWHolder pComWrap = ComCallWrapper::InlineGetWrapper((OBJECTREF *)&cref); - // Make sure the ClassInitializer has run, since the user might have - // wanted to set up a COM object creation callback. - pMTClass->CheckRunClassInitThrowing(); - - // If the user is going to use a delegate to allocate the COM object - // (rather than CoCreateInstance), we need to know now, before we enable - // preemptive GC mode (since we touch object references in the - // determination). - // We don't just check the current class to see if it has a cllabck - // registered, we check up the class chain to see if any of our parents - // did. - - pCallbackMT = pMTClass; - while ((pCallbackMT != NULL) && - (pCallbackMT->GetObjCreateDelegate() == NULL) && - !pCallbackMT->IsComImport()) - { - pCallbackMT = pCallbackMT->GetParentMethodTable(); - } - - if (pCallbackMT && !pCallbackMT->IsComImport()) - bUseDelegate = TRUE; - DebuggerExitFrame __def; // get the IUnknown interface for the managed object pOuter = ComCallWrapper::GetComIPFromCCW(pComWrap, IID_IUnknown, NULL); _ASSERTE(pOuter != NULL); - // If the user has set a delegate to allocate the COM object, use it. - // Otherwise we just CoCreateInstance it. - if (bUseDelegate) - { - ARG_SLOT args[2]; - - OBJECTREF orDelegate = pCallbackMT->GetObjCreateDelegate(); - MethodDesc *pMeth = COMDelegate::GetMethodDesc(orDelegate); - - GCPROTECT_BEGIN(orDelegate) - { - _ASSERTE(pMeth); - MethodDescCallSite delegateMethod(pMeth, &orDelegate); - - // Get the OR on which we are going to invoke the method and set it - // as the first parameter in arg above. - args[0] = (ARG_SLOT)OBJECTREFToObject(COMDelegate::GetTargetObject(orDelegate)); - - // Pass the IUnknown of the aggregator as the second argument. - args[1] = (ARG_SLOT)(IUnknown*)pOuter; - - // Call the method... - pUnk = (IUnknown *)delegateMethod.Call_RetArgSlot(args); - if (!pUnk) - COMPlusThrowHR(E_FAIL); - } - GCPROTECT_END(); - } - else - { - _ASSERTE(m_pClassMT); - pUnk = CreateInstanceInternal(pOuter, &fDidContainment); - } + _ASSERTE(m_pClassMT); + pUnk = CreateInstanceInternal(pOuter, &fDidContainment); __def.Pop(); diff --git a/src/coreclr/vm/stdinterfaces.cpp b/src/coreclr/vm/stdinterfaces.cpp index 50b39ed1eb3921..1e386956ab8a36 100644 --- a/src/coreclr/vm/stdinterfaces.cpp +++ b/src/coreclr/vm/stdinterfaces.cpp @@ -1887,34 +1887,18 @@ HRESULT __stdcall DispatchEx_GetMemberProperties ( case Property: { - BOOL bCanRead = FALSE; - BOOL bCanWrite = FALSE; - - // Find the MethodDesc's for the CanRead property. - MethodDesc *pCanReadMD = MemberLoader::FindPropertyMethod(MemberInfoObj->GetMethodTable(), PROPERTY_INFO_CAN_READ_PROP, PropertyGet); - _ASSERTE_MSG((pCanReadMD != NULL), "Unable to find getter method for property PropertyInfo::CanRead"); - MethodDescCallSite canRead(pCanReadMD, &MemberInfoObj); - - // Find the MethodDesc's for the CanWrite property. - MethodDesc *pCanWriteMD = MemberLoader::FindPropertyMethod(MemberInfoObj->GetMethodTable(), PROPERTY_INFO_CAN_WRITE_PROP, PropertyGet); - _ASSERTE_MSG((pCanWriteMD != NULL), "Unable to find setter method for property PropertyInfo::CanWrite"); - MethodDescCallSite canWrite(pCanWriteMD, &MemberInfoObj); - - // Check to see if the property can be read. - ARG_SLOT CanReadArgs[] = + enum : INT32 { - ObjToArgSlot(MemberInfoObj) + DispatchExPropertyCanRead = 1, + DispatchExPropertyCanWrite = 2, }; - bCanRead = canRead.Call_RetBool(CanReadArgs); - - // Check to see if the property can be written to. - ARG_SLOT CanWriteArgs[] = - { - ObjToArgSlot(MemberInfoObj) - }; + INT32 propertyFlags = 0; + UnmanagedCallersOnlyCaller getDispatchExPropertyFlags(METHOD__STUBHELPERS__GET_DISPATCH_EX_PROPERTY_FLAGS); + getDispatchExPropertyFlags.InvokeThrowing(&MemberInfoObj, &propertyFlags); - bCanWrite = canWrite.Call_RetBool(CanWriteArgs); + bool bCanRead = (propertyFlags & DispatchExPropertyCanRead) != 0; + bool bCanWrite = (propertyFlags & DispatchExPropertyCanWrite) != 0; *pgrfdex = (bCanRead ? fdexPropCanGet : fdexPropCannotGet) | (bCanWrite ? fdexPropCanPut : fdexPropCannotPut) |