Implement Type.IsByRefLike for CoreCLR (#13123)
authorAtsushi Kanamori <AtsushiKan@users.noreply.github.com>
Mon, 31 Jul 2017 15:28:04 +0000 (08:28 -0700)
committerJan Kotas <jkotas@microsoft.com>
Mon, 31 Jul 2017 15:28:04 +0000 (17:28 +0200)
Since this already exists in CoreRT and the
virtual method will get propagated to CoreCLR,
we might as well make it work here before an IsByRefLike
check finds its way into shared code and starts
throwing NotSupportedExceptions on CoreCLR.

src/mscorlib/shared/System/Reflection/TypeDelegator.cs
src/mscorlib/src/System/RtType.cs
src/mscorlib/src/System/RuntimeHandles.cs
src/vm/ecalllist.h
src/vm/runtimehandles.cpp
src/vm/runtimehandles.h
src/vm/typehandle.cpp
src/vm/typehandle.h

index bcbff05..1dba278 100644 (file)
@@ -108,6 +108,7 @@ namespace System.Reflection
         protected override bool IsPointerImpl() => typeImpl.IsPointer;
         protected override bool IsValueTypeImpl() => typeImpl.IsValueType;
         protected override bool IsCOMObjectImpl() => typeImpl.IsCOMObject;
+        public override bool IsByRefLike => typeImpl.IsByRefLike;
         public override bool IsConstructedGenericType => typeImpl.IsConstructedGenericType;
         public override Type GetElementType() => typeImpl.GetElementType();
         protected override bool HasElementTypeImpl() => typeImpl.HasElementType;
index 871a39d..5aeaa20 100644 (file)
@@ -3447,6 +3447,8 @@ namespace System
             return RuntimeTypeHandle.IsComObject(this, false);
         }
 
+        public sealed override bool IsByRefLike => RuntimeTypeHandle.IsByRefLike(this);
+
 #if FEATURE_COMINTEROP
         internal override bool IsWindowsRuntimeObjectImpl()
         {
index fca37dd..bfe7490 100644 (file)
@@ -377,6 +377,9 @@ namespace System
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         internal extern static bool IsInterface(RuntimeType type);
 
+        [MethodImplAttribute(MethodImplOptions.InternalCall)]
+        internal extern static bool IsByRefLike(RuntimeType type);
+
         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
         [SuppressUnmanagedCodeSecurity]
         [return: MarshalAs(UnmanagedType.Bool)]
index 5bac536..a76c647 100644 (file)
@@ -297,6 +297,7 @@ FCFuncStart(gCOMTypeHandleFuncs)
     FCFuncElement("IsComObject", RuntimeTypeHandle::IsComObject)
     FCFuncElement("IsValueType", RuntimeTypeHandle::IsValueType)
     FCFuncElement("IsInterface", RuntimeTypeHandle::IsInterface)
+    FCFuncElement("IsByRefLike", RuntimeTypeHandle::IsByRefLike)
     QCFuncElement("_IsVisible", RuntimeTypeHandle::IsVisible)
     QCFuncElement("ConstructName", RuntimeTypeHandle::ConstructName)
     FCFuncElement("CanCastTo", RuntimeTypeHandle::CanCastTo)
index d3dad5a..07dc7b6 100644 (file)
@@ -970,6 +970,24 @@ FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTy
 }
 FCIMPLEND;
 
+
+FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsByRefLike, ReflectClassBaseObject *pTypeUNSAFE)
+{
+    CONTRACTL {
+        FCALL_CHECK;
+    }
+    CONTRACTL_END;
+    
+    REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
+
+    _ASSERTE(refType != NULL);
+
+    TypeHandle typeHandle = refType->GetType();
+
+    FC_RETURN_BOOL(typeHandle.IsByRefLike());
+}
+FCIMPLEND
+
 BOOL 
 QCALLTYPE 
 RuntimeTypeHandle::IsVisible(
@@ -3115,3 +3133,4 @@ void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pS
 
     return;
 }
+
index fc18d6f..95742c4 100644 (file)
@@ -193,6 +193,7 @@ public:
     static FCDECL1(ReflectClassBaseObject*, GetDeclaringType, ReflectClassBaseObject* pType);
     static FCDECL1(FC_BOOL_RET, IsValueType, ReflectClassBaseObject* pType);
     static FCDECL1(FC_BOOL_RET, IsInterface, ReflectClassBaseObject* pType);
+    static FCDECL1(FC_BOOL_RET, IsByRefLike, ReflectClassBaseObject* pType);
     
     static 
     BOOL QCALLTYPE IsVisible(EnregisteredTypeHandle pTypeHandle);
index 32384cc..61a655f 100644 (file)
@@ -1546,6 +1546,14 @@ BOOL TypeHandle::IsByRef()  const
 
 }
 
+BOOL TypeHandle::IsByRefLike()  const
+{ 
+    LIMITED_METHOD_CONTRACT;
+
+    return(!IsTypeDesc() && AsMethodTable()->IsByRefLike());
+
+}
+
 BOOL TypeHandle::IsPointer()  const
 { 
     LIMITED_METHOD_CONTRACT;
index 72a5656..3a9bd70 100644 (file)
@@ -513,6 +513,9 @@ public:
     // BYREF
     BOOL IsByRef() const;
 
+    // BYREFLIKE (does not return TRUE for IsByRef types)
+    BOOL IsByRefLike() const;
+
     // PTR
     BOOL IsPointer() const;