diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 042a34158eaa9b..28caf306f70b10 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1501,8 +1501,79 @@ 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] + [RequiresUnsafe] + 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] + [RequiresUnsafe] + 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; + } + } + [SupportedOSPlatform("windows")] [UnmanagedCallersOnly] + [RequiresUnsafe] + private static unsafe void InvokeConnectionPointProviderMethod( + object* pProvider, + delegate * providerMethodEntryPoint, + object* pDelegate, + delegate* delegateCtorMethodEntryPoint, + object* pSubscriber, + IntPtr pEventMethodCodePtr, + Exception* pException) + { + try + { + // Construct the delegate before invoking the provider method. + delegateCtorMethodEntryPoint(*pDelegate, *pSubscriber, pEventMethodCodePtr); + + providerMethodEntryPoint(*pProvider, *pDelegate); + } + catch (Exception ex) + { + *pException = ex; + } + } + + [SupportedOSPlatform("windows")] + [UnmanagedCallersOnly] + [RequiresUnsafe] private static unsafe void GetIEnumeratorToEnumVariantMarshaler(object* pResult, Exception* pException) { try @@ -1693,6 +1764,7 @@ internal static void MulticastDebuggerTraceHelper(object o, int count) internal static class CultureInfoMarshaler { [UnmanagedCallersOnly] + [RequiresUnsafe] internal static unsafe void GetCurrentCulture(bool bUICulture, object* pResult, Exception* pException) { try @@ -1708,6 +1780,7 @@ internal static unsafe void GetCurrentCulture(bool bUICulture, object* pResult, } [UnmanagedCallersOnly] + [RequiresUnsafe] internal static unsafe void SetCurrentCulture(bool bUICulture, Globalization.CultureInfo* pValue, Exception* pException) { try @@ -1724,6 +1797,7 @@ internal static unsafe void SetCurrentCulture(bool bUICulture, Globalization.Cul } [UnmanagedCallersOnly] + [RequiresUnsafe] internal static unsafe void CreateCultureInfo(int culture, object* pResult, Exception* pException) { try @@ -1769,6 +1843,7 @@ internal static int ConvertToNative(object? managedColor) } [UnmanagedCallersOnly] + [RequiresUnsafe] internal static unsafe void ConvertToManaged(int oleColor, object* pResult, Exception* pException) { try @@ -1782,6 +1857,7 @@ internal static unsafe void ConvertToManaged(int oleColor, object* pResult, Exce } [UnmanagedCallersOnly] + [RequiresUnsafe] internal static unsafe void ConvertToNative(object* pSrcObj, int* pResult, Exception* pException) { try 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/comcallablewrapper.cpp b/src/coreclr/vm/comcallablewrapper.cpp index 1b0c6eea5a4e45..504a701132cd1b 100644 --- a/src/coreclr/vm/comcallablewrapper.cpp +++ b/src/coreclr/vm/comcallablewrapper.cpp @@ -2314,52 +2314,6 @@ IUnknown* ComCallWrapper::GetBasicIP(bool inspectionOnly) RETURN ((cbRef != 0xbadf00d) ? pIntf : NULL); } -struct InvokeICustomQueryInterfaceGetInterfaceArgs -{ - ComCallWrapper *pWrap; - GUID *pGuid; - IUnknown **ppUnk; - CustomQueryInterfaceResult *pRetVal; -}; - -VOID __stdcall InvokeICustomQueryInterfaceGetInterface_CallBack(LPVOID ptr) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(ptr)); - } - CONTRACTL_END; - InvokeICustomQueryInterfaceGetInterfaceArgs *pArgs = (InvokeICustomQueryInterfaceGetInterfaceArgs*)ptr; - - { - GCX_COOP(); - OBJECTREF pObj = pArgs->pWrap->GetObjectRef(); - - GCPROTECT_BEGIN(pObj); - - // 1. Get MD - MethodDesc *pMD = pArgs->pWrap->GetSimpleWrapper()->GetComCallWrapperTemplate()->GetICustomQueryInterfaceGetInterfaceMD(); - - // 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); - GCPROTECT_END(); - } -} - //-------------------------------------------------------------------------- // check if the interface is supported, return a index into the IMap // returns -1, if pIntfMT is not supported @@ -2601,9 +2555,21 @@ static bool GetComIPFromCCW_HandleCustomQI( guid = riid; } - InvokeICustomQueryInterfaceGetInterfaceArgs args = {pWrap, &guid, ppUnkOut, &retVal}; + { + GCX_COOP(); + OBJECTREF pObj = pWrap->GetObjectRef(); - InvokeICustomQueryInterfaceGetInterface_CallBack(&args); + GCPROTECT_BEGIN(pObj); + + INT_PTR queriedInterface = reinterpret_cast(*ppUnkOut); + INT32 result = static_cast(CustomQueryInterfaceResult::NotHandled); + UnmanagedCallersOnlyCaller callICustomQueryInterface(METHOD__STUBHELPERS__CALL_ICUSTOM_QUERY_INTERFACE); + callICustomQueryInterface.InvokeThrowing(&pObj, &guid, &queriedInterface, &result); + + *ppUnkOut = reinterpret_cast(queriedInterface); + retVal = static_cast(result); + GCPROTECT_END(); + } // return if user already handle the QI if (retVal == Handled) @@ -4674,7 +4640,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 +4759,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 +4892,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..904dc7c30784d7 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->GetSingleCallableAddrOfCode(), + &pDelegate, + (INT_PTR)pDlgCtorMD->GetSingleCallableAddrOfCode(), + &pSubscriber, + (INT_PTR)pEventMethodDesc->GetSingleCallableAddrOfCode(), + CLR_BOOL_ARG(useUIntPtrCtor)); } GCPROTECT_END(); } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 3d58d3bf98c82d..78f5569670f35d 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1053,6 +1053,9 @@ 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) #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 0ff156f0883adc..415a7ccafc2ffb 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)) 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 db58879480b80a..dd484dc5b87f67 100644 --- a/src/coreclr/vm/runtimecallablewrapper.cpp +++ b/src/coreclr/vm/runtimecallablewrapper.cpp @@ -282,9 +282,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; @@ -295,68 +292,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) |