summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorLuqun Lou <luqunl@users.noreply.github.com>2018-03-27 14:20:09 -0700
committerJan Kotas <jkotas@microsoft.com>2018-03-27 14:20:09 -0700
commitd0833f90ed516b08871635a05c1d5657379b8053 (patch)
tree58b7943d065d14a238564c1bde4f7f38f635569e /src/vm
parentbfa1881ab5b65175f97119b74ef127e08de882e1 (diff)
downloadcoreclr-d0833f90ed516b08871635a05c1d5657379b8053.tar.gz
coreclr-d0833f90ed516b08871635a05c1d5657379b8053.tar.bz2
coreclr-d0833f90ed516b08871635a05c1d5657379b8053.zip
Enable reflection load ComImport assembly and Type.IsComObjectType (#16943)
* Enable reflection load ComImport assembly and Type.IsComObjectType * Update Enable reflection load ComImport assembly
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/ecall.cpp12
-rw-r--r--src/vm/interoputil.cpp97
-rw-r--r--src/vm/interoputil.h16
-rw-r--r--src/vm/methodtable.cpp4
-rw-r--r--src/vm/methodtable.h24
-rw-r--r--src/vm/methodtablebuilder.cpp26
-rw-r--r--src/vm/methodtablebuilder.h3
-rw-r--r--src/vm/runtimehandles.cpp12
8 files changed, 87 insertions, 107 deletions
diff --git a/src/vm/ecall.cpp b/src/vm/ecall.cpp
index dacec45787..3812ff1030 100644
--- a/src/vm/ecall.cpp
+++ b/src/vm/ecall.cpp
@@ -320,10 +320,14 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /*
return GetFCallImpl(MscorlibBinder::GetMethod(METHOD__DELEGATE__CONSTRUCT_DELEGATE));
}
-#ifdef FEATURE_COMINTEROP
// COM imported classes have special constructors
- if (pMT->IsComObjectType() && pMT != g_pBaseCOMObject && pMT != g_pBaseRuntimeClass)
+ if (pMT->IsComObjectType()
+#ifdef FEATURE_COMINTEROP
+ && pMT != g_pBaseCOMObject && pMT != g_pBaseRuntimeClass
+#endif // FEATURE_COMINTEROP
+ )
{
+#ifdef FEATURE_COMINTEROP
if (pfSharedOrDynamicFCallImpl)
*pfSharedOrDynamicFCallImpl = TRUE;
@@ -333,8 +337,10 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /*
// FCComCtor does not need to be in the fcall hashtable since it does not erect frame.
return GetEEFuncEntryPoint(FCComCtor);
- }
+#else
+ COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_COM);
#endif // FEATURE_COMINTEROP
+ }
if (!pMD->GetModule()->IsSystem())
COMPlusThrow(kSecurityException, BFA_ECALLS_MUST_BE_IN_SYS_MOD);
diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp
index d48163c075..630706bfc7 100644
--- a/src/vm/interoputil.cpp
+++ b/src/vm/interoputil.cpp
@@ -999,6 +999,7 @@ void GetCultureInfoForLCID(LCID lcid, OBJECTREF *pCultureObj)
COMPlusThrow(kNotSupportedException);
#endif
}
+
#endif // CROSSGEN_COMPILE
//---------------------------------------------------------------------------
@@ -1618,6 +1619,55 @@ BOOL CanCastComObject(OBJECTREF obj, MethodTable * pTargetMT)
}
}
+// Returns TRUE iff the argument represents the "__ComObject" type or
+// any type derived from it (i.e. typelib-imported RCWs).
+BOOL IsComWrapperClass(TypeHandle type)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ MethodTable* pMT = type.GetMethodTable();
+ if (pMT == NULL)
+ return FALSE;
+
+ return pMT->IsComObjectType();
+}
+
+// Returns TRUE iff the argument represents the "__ComObject" type.
+BOOL IsComObjectClass(TypeHandle type)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
+
+#ifdef FEATURE_COMINTEROP
+ if (!type.IsTypeDesc())
+ {
+ MethodTable *pMT = type.AsMethodTable();
+
+ if (pMT->IsComObjectType())
+ {
+ // May be __ComObject or typed RCW. __ComObject must have already been loaded
+ // if we see an MT marked like this so calling the *NoInit method is sufficient.
+
+ return pMT == g_pBaseCOMObject;
+ }
+ }
+#endif
+
+ return FALSE;
+}
+
VOID
ReadBestFitCustomAttribute(MethodDesc* pMD, BOOL* BestFit, BOOL* ThrowOnUnmappableChar)
{
@@ -6204,53 +6254,6 @@ MethodTable *WinRTDelegateRedirector::GetWinRTTypeForRedirectedDelegateIndex(Win
}
}
-// Returns TRUE iff the argument represents the "__ComObject" type or
-// any type derived from it (i.e. typelib-imported RCWs).
-BOOL IsComWrapperClass(TypeHandle type)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MethodTable* pMT = type.GetMethodTable();
- if (pMT == NULL)
- return FALSE;
-
- return pMT->IsComObjectType();
-}
-
-// Returns TRUE iff the argument represents the "__ComObject" type.
-BOOL IsComObjectClass(TypeHandle type)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (!type.IsTypeDesc())
- {
- MethodTable *pMT = type.AsMethodTable();
-
- if (pMT->IsComObjectType())
- {
- // May be __ComObject or typed RCW. __ComObject must have already been loaded
- // if we see an MT marked like this so calling the *NoInit method is sufficient.
- return (pMT == g_pBaseCOMObject);
- }
- }
-
- return FALSE;
-}
-
-
#ifndef CROSSGEN_COMPILE
#ifdef _DEBUG
diff --git a/src/vm/interoputil.h b/src/vm/interoputil.h
index 6762c80f92..a6896248c6 100644
--- a/src/vm/interoputil.h
+++ b/src/vm/interoputil.h
@@ -106,6 +106,13 @@ ULONG SafeReleasePreemp(IUnknown* pUnk, RCW* pRCW = NULL);
// Determines if a COM object can be cast to the specified type.
BOOL CanCastComObject(OBJECTREF obj, MethodTable * pTargetMT);
+// includes Types which hold a "ComObject" class
+// and types which are imported through typelib
+BOOL IsComWrapperClass(TypeHandle type);
+
+// includes Type which hold a "__ComObject" class
+BOOL IsComObjectClass(TypeHandle type);
+
//---------------------------------------------------------
// Read the BestFit custom attribute info from
// both assembly level and interface level
@@ -491,14 +498,6 @@ public:
static void ComputeGuidForGenericType(MethodTable *pMT, GUID *pGuid);
}; // class WinRTGuidGenerator
-
-// includes Types which hold a "ComObject" class
-// and types which are imported through typelib
-BOOL IsComWrapperClass(TypeHandle type);
-
-// includes Type which hold a "__ComObject" class
-BOOL IsComObjectClass(TypeHandle type);
-
IUnknown* MarshalObjectToInterface(OBJECTREF* ppObject, MethodTable* pItfMT, MethodTable* pClassMT, DWORD dwFlags);
void UnmarshalObjectFromInterface(OBJECTREF *ppObjectDest, IUnknown **ppUnkSrc, MethodTable *pItfMT, MethodTable *pClassMT, DWORD dwFlags);
@@ -508,7 +507,6 @@ class ICOMInterfaceMarshalerCallback;
void GetNativeWinRTFactoryObject(MethodTable *pMT, Thread *pThread, MethodTable *pFactoryIntfMT, BOOL bNeedUniqueRCW, ICOMInterfaceMarshalerCallback *pCallback, OBJECTREF *prefFactory);
#else // FEATURE_COMINTEROP
-
inline HRESULT EnsureComStartedNoThrow()
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index 710a81abf4..67656235ef 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -602,8 +602,6 @@ void MethodTable::SetIsRestored()
#endif
}
-#ifdef FEATURE_COMINTEROP
-
//==========================================================================================
// mark as COM object type (System.__ComObject and types deriving from it)
void MethodTable::SetComObjectType()
@@ -612,8 +610,6 @@ void MethodTable::SetComObjectType()
SetFlag(enum_flag_ComObject);
}
-#endif // FEATURE_COMINTEROP
-
#if defined(FEATURE_TYPEEQUIVALENCE)
void MethodTable::SetHasTypeEquivalence()
{
diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h
index 7bc2a83c54..e88fe16644 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -882,9 +882,6 @@ public:
BOOL IsExtensibleRCW();
- // mark the class type as COM object class
- void SetComObjectType();
-
#if defined(FEATURE_TYPEEQUIVALENCE)
// mark the type as opted into type equivalence
void SetHasTypeEquivalence();
@@ -894,12 +891,6 @@ public:
// the hierarchy
MethodTable* GetComPlusParentMethodTable();
- // class is a com object class
- BOOL IsComObjectType()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return GetFlag(enum_flag_ComObject);
- }
// class is a WinRT object class (is itself or derives from a ProjectedFromWinRT class)
BOOL IsWinRTObjectType();
@@ -943,11 +934,6 @@ public:
InteropMethodTableData *GetComInteropData();
#else // !FEATURE_COMINTEROP
- BOOL IsComObjectType()
- {
- SUPPORTS_DAC;
- return FALSE;
- }
BOOL IsWinRTObjectType()
{
LIMITED_METHOD_CONTRACT;
@@ -955,6 +941,16 @@ public:
}
#endif // !FEATURE_COMINTEROP
+ // class is a com object class
+ BOOL IsComObjectType()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return GetFlag(enum_flag_ComObject);
+ }
+
+ // mark the class type as COM object class
+ void SetComObjectType();
+
#ifdef FEATURE_ICASTABLE
void SetICastable();
#endif
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 6464e5849e..c57677b316 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -1536,12 +1536,11 @@ MethodTableBuilder::BuildMethodTableThrowing(
}
}
-#ifdef FEATURE_COMINTEROP
-
// Com Import classes are special. These types must derive from System.Object,
// and we then substitute the parent with System._ComObject.
if (IsComImport() && !IsEnum() && !IsInterface() && !IsValueClass() && !IsDelegate())
{
+#ifdef FEATURE_COMINTEROP
// ComImport classes must either extend from Object or be a WinRT class
// that extends from another WinRT class (and so form a chain of WinRT classes
// that ultimately extend from object).
@@ -1579,11 +1578,12 @@ MethodTableBuilder::BuildMethodTableThrowing(
bmtInternal->pType->SetParentType(CreateTypeChain(pCOMMT, Substitution()));
bmtInternal->pParentMT = pCOMMT;
}
-
+#endif
// if the current class is imported
bmtProp->fIsComObjectType = true;
}
+#ifdef FEATURE_COMINTEROP
if (GetHalfBakedClass()->IsProjectedFromWinRT() && IsValueClass() && !IsEnum())
{
// WinRT structures must have sequential layout
@@ -2865,12 +2865,10 @@ MethodTableBuilder::EnumerateClassMethods()
// RVA : 0
if (dwMethodRVA != 0)
{
-#ifdef FEATURE_COMINTEROP
if(fIsClassComImport)
{
BuildMethodTableThrowException(BFA_METHOD_WITH_NONZERO_RVA);
}
-#endif // FEATURE_COMINTEROP
if(IsMdAbstract(dwMemberAttrs))
{
BuildMethodTableThrowException(BFA_ABSTRACT_METHOD_WITH_RVA);
@@ -3066,14 +3064,12 @@ MethodTableBuilder::EnumerateClassMethods()
// The attribute is not present
if (hr == S_FALSE)
{
+#ifdef FEATURE_COMINTEROP
if (fIsClassComImport
-#ifdef FEATURE_COMINTEROP
|| GetHalfBakedClass()->IsProjectedFromWinRT()
|| bmtProp->fComEventItfType
-#endif //FEATURE_COMINTEROP
)
{
-#ifdef FEATURE_COMINTEROP
// ComImport classes have methods which are just used
// for implementing all interfaces the class supports
type = METHOD_TYPE_COMINTEROP;
@@ -3090,13 +3086,10 @@ MethodTableBuilder::EnumerateClassMethods()
type = METHOD_TYPE_FCALL;
}
}
-#else
- //If we don't support com interop, refuse to load interop methods. Otherwise we fail to
- //jit calls to them since the constuctor has no intrinsic ID.
- BuildMethodTableThrowException(hr, IDS_CLASSLOAD_GENERAL, tok);
-#endif // FEATURE_COMINTEROP
}
- else if (dwMethodRVA == 0)
+ else
+#endif //FEATURE_COMINTEROP
+ if (dwMethodRVA == 0)
{
type = METHOD_TYPE_FCALL;
}
@@ -10322,16 +10315,17 @@ MethodTableBuilder::SetupMethodTable2(
GetHalfBakedClass()->SetBaseSizePadding(baseSize - bmtFP->NumInstanceFieldBytes);
-#ifdef FEATURE_COMINTEROP
if (bmtProp->fIsComObjectType)
{ // Propagate the com specific info
pMT->SetComObjectType();
-
+#ifdef FEATURE_COMINTEROP
// COM objects need an optional field on the EEClass, so ensure this class instance has allocated
// the optional field descriptor.
EnsureOptionalFieldsAreAllocated(pClass, m_pAllocMemTracker, GetLoaderAllocator()->GetLowFrequencyHeap());
+#endif // FEATURE_COMINTEROP
}
+#ifdef FEATURE_COMINTEROP
if (pMT->GetAssembly()->IsManagedWinMD())
{
// We need to mark classes that are implementations of managed WinRT runtime classes with
diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h
index e64b72bb9d..3e267a2b23 100644
--- a/src/vm/methodtablebuilder.h
+++ b/src/vm/methodtablebuilder.h
@@ -1316,10 +1316,9 @@ private:
bool fNoSanityChecks;
bool fSparse; // Set to true if a sparse interface is being used.
-#ifdef FEATURE_COMINTEROP
// Com Interop, ComWrapper classes extend from ComObject
bool fIsComObjectType; // whether this class is an instance of ComObject class
-
+#ifdef FEATURE_COMINTEROP
bool fIsMngStandardItf; // Set to true if the interface is a manages standard interface.
bool fComEventItfType; // Set to true if the class is a special COM event interface.
bool fIsRedirectedInterface; // Set to true if the class is an interface redirected for WinRT
diff --git a/src/vm/runtimehandles.cpp b/src/vm/runtimehandles.cpp
index 723222e55b..de9505ae91 100644
--- a/src/vm/runtimehandles.cpp
+++ b/src/vm/runtimehandles.cpp
@@ -1012,7 +1012,6 @@ RuntimeTypeHandle::IsVisible(
} // RuntimeTypeHandle::IsVisible
FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
-#ifdef FEATURE_COMINTEROP
CONTRACTL {
FCALL_CHECK;
}
@@ -1037,17 +1036,6 @@ FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTy
HELPER_METHOD_FRAME_END();
FC_RETURN_BOOL(ret);
-#else
- CONTRACTL {
- DISABLED(NOTHROW);
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pTypeUNSAFE));
- }
- CONTRACTL_END;
- FCUnique(0x37);
- FC_RETURN_BOOL(FALSE);
-#endif
}
FCIMPLEND