From ee1212f30ad96beec5bf7d27c20bb82237f28ea7 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 28 Apr 2022 19:39:07 -0700 Subject: [PATCH 1/8] Relax argument checks on pinned GCHandles Relax argument checks on pinned GCHandles to allow any objects without references for consistency with DisableRuntimeMarshalling. Fixes #68686 --- .../InteropServices/Marshal.CoreCLR.cs | 5 +- src/coreclr/dlls/mscorrc/mscorrc.rc | 5 +- src/coreclr/inc/corerror.xml | 6 -- src/coreclr/pal/prebuilt/corerror/mscorurt.rc | 1 - src/coreclr/pal/prebuilt/inc/corerror.h | 1 - src/coreclr/utilcode/ex.cpp | 1 - src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/marshalnative.cpp | 62 +------------------ src/coreclr/vm/marshalnative.h | 2 - .../src/Resources/Strings.resx | 2 +- 10 files changed, 7 insertions(+), 79 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 3837e5c7f1efb9..cece82384ffc5a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -251,8 +251,9 @@ private static void PrelinkCore(MethodInfo m) [EditorBrowsable(EditorBrowsableState.Never)] public static extern void DestroyStructure(IntPtr ptr, Type structuretype); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool IsPinnable(object? obj); + // Note: Callers are required to keep obj alive + internal static unsafe bool IsPinnable(object? obj) + => (obj == null) || !RuntimeHelpers.GetMethodTable(obj)->ContainsGCPointers; #if TARGET_WINDOWS internal static bool IsBuiltInComSupported { get; } = IsBuiltInComSupportedInternal(); diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index 5632603fb0c813..785539b7713f1a 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -408,15 +408,12 @@ BEGIN IDS_EE_CANNOTCASTSAME "[A]%1 cannot be cast to [B]%2. %3. %4." IDS_EE_CANNOTCAST_HELPER_PATH "Type %s originates from '%s' in the context '%s' at location '%s'" IDS_EE_CANNOTCAST_HELPER_BYTE "Type %s originates from '%s' in the context '%s' in a byte array" - IDS_EE_NOTISOMORPHIC "Object contains non-primitive or non-blittable data." + IDS_EE_NOTISOMORPHIC "Object contains references." IDS_EE_INVALID_VT_FOR_CUSTOM_MARHALER "Type of the VARIANT specified for a parameter with a custom marshaler is not supported by the custom marshaler." IDS_EE_BAD_COMEXTENDS_CLASS "Types extending from COM objects should override all methods of an interface implemented by the base COM class." IDS_EE_INTERFACE_NOT_DISPATCH_BASED "The interface does not support late bound calls since it does not derive from IDispatch." IDS_EE_MARSHAL_UNMAPPABLE_CHAR "Cannot marshal: Encountered unmappable character." - // Errors associated with parsing security custom attributes at compile time. - CORSECATTR_E_BAD_ACTION "Security custom attribute has invalid SecurityAction." - IDS_EE_NOCUSTOMMARSHALER "A call to GetInstance() for custom marshaler '%1' returned null, which is not allowed." IDS_EE_SIZECONTROLOUTOFRANGE "Array size control parameter index is out of range." IDS_EE_SIZECONTROLBADTYPE "Array size control parameter type not supported." diff --git a/src/coreclr/inc/corerror.xml b/src/coreclr/inc/corerror.xml index 42cc0ff036b54b..34a6b1d4b9a5d5 100644 --- a/src/coreclr/inc/corerror.xml +++ b/src/coreclr/inc/corerror.xml @@ -1248,12 +1248,6 @@ generic CryptographicUnexpectedOperationException - - CORSECATTR_E_BAD_ACTION - "Invalid security action code." - Invalid security action code - - COR_E_EXCEPTION "General Exception" diff --git a/src/coreclr/pal/prebuilt/corerror/mscorurt.rc b/src/coreclr/pal/prebuilt/corerror/mscorurt.rc index e5fed902b04354..fc0fb702d7fb77 100644 --- a/src/coreclr/pal/prebuilt/corerror/mscorurt.rc +++ b/src/coreclr/pal/prebuilt/corerror/mscorurt.rc @@ -158,7 +158,6 @@ BEGIN MSG_FOR_URT_HR(CORSEC_E_SIGNATURE_MISMATCH) "Signature size mismatch." MSG_FOR_URT_HR(CORSEC_E_CRYPTO) "Failure during Cryptographic operation." MSG_FOR_URT_HR(CORSEC_E_CRYPTO_UNEX_OPER) "Unexpected Cryptographic operation." - MSG_FOR_URT_HR(CORSECATTR_E_BAD_ACTION) "Invalid security action code." MSG_FOR_URT_HR(COR_E_EXCEPTION) "General Exception" MSG_FOR_URT_HR(COR_E_SYSTEM) "System.Exception" MSG_FOR_URT_HR(COR_E_ARGUMENTOUTOFRANGE) "An argument was out of its legal range." diff --git a/src/coreclr/pal/prebuilt/inc/corerror.h b/src/coreclr/pal/prebuilt/inc/corerror.h index 3832b48c2e4c6f..498e6701be150f 100644 --- a/src/coreclr/pal/prebuilt/inc/corerror.h +++ b/src/coreclr/pal/prebuilt/inc/corerror.h @@ -225,7 +225,6 @@ #define CORSEC_E_SIGNATURE_MISMATCH EMAKEHR(0x1420) #define CORSEC_E_CRYPTO EMAKEHR(0x1430) #define CORSEC_E_CRYPTO_UNEX_OPER EMAKEHR(0x1431) -#define CORSECATTR_E_BAD_ACTION EMAKEHR(0x1442) #define COR_E_EXCEPTION EMAKEHR(0x1500) #define COR_E_SYSTEM EMAKEHR(0x1501) #define COR_E_ARGUMENTOUTOFRANGE EMAKEHR(0x1502) diff --git a/src/coreclr/utilcode/ex.cpp b/src/coreclr/utilcode/ex.cpp index e0f8a37e7ef18b..97591ecb5c91cc 100644 --- a/src/coreclr/utilcode/ex.cpp +++ b/src/coreclr/utilcode/ex.cpp @@ -687,7 +687,6 @@ LPCSTR Exception::GetHRSymbolicName(HRESULT hr) CASE_HRESULT(CORSEC_E_INVALID_IMAGE_FORMAT) CASE_HRESULT(CORSEC_E_CRYPTO) CASE_HRESULT(CORSEC_E_CRYPTO_UNEX_OPER) - CASE_HRESULT(CORSECATTR_E_BAD_ACTION) CASE_HRESULT(COR_E_APPLICATION) CASE_HRESULT(COR_E_ARGUMENTOUTOFRANGE) CASE_HRESULT(COR_E_ARITHMETIC) diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 1ad3228acd0caf..593284165f1651 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -503,7 +503,6 @@ FCFuncStart(gInteropMarshalFuncs) FCFuncElement("StructureToPtr", MarshalNative::StructureToPtr) FCFuncElement("PtrToStructureHelper", MarshalNative::PtrToStructureHelper) FCFuncElement("DestroyStructure", MarshalNative::DestroyStructure) - FCFuncElement("IsPinnable", MarshalNative::IsPinnable) FCFuncElement("GetExceptionCode", ExceptionNative::GetExceptionCode) FCFuncElement("GetExceptionPointers", ExceptionNative::GetExceptionPointers) diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp index 6aa5cefb9f6a43..9ecc4b2b95ea0c 100644 --- a/src/coreclr/vm/marshalnative.cpp +++ b/src/coreclr/vm/marshalnative.cpp @@ -245,39 +245,6 @@ FCIMPL2(VOID, MarshalNative::DestroyStructure, LPVOID ptr, ReflectClassBaseObjec } FCIMPLEND -FCIMPL1(FC_BOOL_RET, MarshalNative::IsPinnable, Object* obj) -{ - FCALL_CONTRACT; - - VALIDATEOBJECT(obj); - - if (obj == NULL) - FC_RETURN_BOOL(TRUE); - - if (obj->GetMethodTable() == g_pStringClass) - FC_RETURN_BOOL(TRUE); - - if (obj->GetMethodTable()->IsArray()) - { - BASEARRAYREF asArray = (BASEARRAYREF)ObjectToOBJECTREF(obj); - if (CorTypeInfo::IsPrimitiveType(asArray->GetArrayElementType())) - FC_RETURN_BOOL(TRUE); - - TypeHandle th = asArray->GetArrayElementTypeHandle(); - if (!th.IsTypeDesc()) - { - MethodTable *pMT = th.AsMethodTable(); - if (pMT->IsValueType() && pMT->IsBlittable()) - FC_RETURN_BOOL(TRUE); - } - - FC_RETURN_BOOL(FALSE); - } - - FC_RETURN_BOOL(obj->GetMethodTable()->IsBlittable()); -} -FCIMPLEND - /************************************************************************ * PInvoke.SizeOf(Class) */ @@ -488,33 +455,8 @@ void ValidatePinnedObject(OBJECTREF obj) } CONTRACTL_END; - // NULL is fine. - if (obj == NULL) - return; - - if (obj->GetMethodTable() == g_pStringClass) - return; - - if (obj->GetMethodTable()->IsArray()) - { - BASEARRAYREF asArray = (BASEARRAYREF) obj; - if (CorTypeInfo::IsPrimitiveType(asArray->GetArrayElementType())) - return; - - TypeHandle th = asArray->GetArrayElementTypeHandle(); - if (!th.IsTypeDesc()) - { - MethodTable *pMT = th.AsMethodTable(); - if (pMT->IsValueType() && pMT->IsBlittable()) - return; - } - } - else if (obj->GetMethodTable()->IsBlittable()) - { - return; - } - - COMPlusThrow(kArgumentException, IDS_EE_NOTISOMORPHIC); + if (obj != NULL && obj->GetMethodTable()->ContainsPointers()) + COMPlusThrow(kArgumentException, IDS_EE_NOTISOMORPHIC); } NOINLINE static OBJECTHANDLE FCDiagCreateHandle(OBJECTREF objRef, int type) diff --git a/src/coreclr/vm/marshalnative.h b/src/coreclr/vm/marshalnative.h index 33f6fd5dc374b0..034ea1f4acf154 100644 --- a/src/coreclr/vm/marshalnative.h +++ b/src/coreclr/vm/marshalnative.h @@ -36,8 +36,6 @@ class MarshalNative static FCDECL3(VOID, PtrToStructureHelper, LPVOID ptr, Object* pObjIn, CLR_BOOL allowValueClasses); static FCDECL2(VOID, DestroyStructure, LPVOID ptr, ReflectClassBaseObject* refClassUNSAFE); - static FCDECL1(FC_BOOL_RET, IsPinnable, Object* obj); - static FCDECL2(LPVOID, GCHandleInternalAlloc, Object *obj, int type); static FCDECL1(VOID, GCHandleInternalFree, OBJECTHANDLE handle); static FCDECL1(LPVOID, GCHandleInternalGet, OBJECTHANDLE handle); diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 78c5cc4fec2e4c..007e7ca07da06c 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1538,7 +1538,7 @@ The object is not an array with the same number of elements as the array to compare it to. - Object contains non-primitive or non-blittable data. + Object contains references. Argument must be of type {0}. From f516f2fd58c385938ce43f2863f7e7c6b4f68f68 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 28 Apr 2022 23:11:35 -0700 Subject: [PATCH 2/8] Add test --- .../System/Runtime/InteropServices/GCHandleTests.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs index 8a79b7a66db456..1c1a3300835701 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs @@ -53,6 +53,8 @@ public static IEnumerable Alloc_Type_TestData() yield return new object[] { new Blittable(), GCHandleType.Pinned }; yield return new object[] { new Blittable(), GCHandleType.Pinned }; yield return new object[] { new Blittable[0], GCHandleType.Pinned }; + yield return new object[] { new Unmanaged(), GCHandleType.Pinned }; + yield return new object[] { new Unmanaged[0], GCHandleType.Pinned }; } [Theory] @@ -189,6 +191,11 @@ public struct Blittable public int Object { get; set; } } + public struct Unmanaged + { + public char Object { get; set; } + } + public struct NonBlittable { public List Object { get; set; } From 46bc8103e353c7261daf31a115f86a38831b9fbf Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 28 Apr 2022 23:16:54 -0700 Subject: [PATCH 3/8] Fix Mono --- src/mono/mono/metadata/marshal.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index d7f24a1e8d2f99..66cebbd09e1c13 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -5427,14 +5427,8 @@ MonoBoolean ves_icall_System_Runtime_InteropServices_Marshal_IsPinnableType (MonoQCallTypeHandle type_handle) { MonoClass *klass = mono_class_from_mono_type_internal (type_handle.type); - - if (m_class_get_rank (klass)) { - MonoClass *eklass = m_class_get_element_class (klass); - if (m_class_is_primitive (eklass)) - return TRUE; - return eklass != mono_defaults.object_class && m_class_is_blittable (eklass); - } else - return m_class_is_blittable (klass); + mono_class_init_internal (klass); + return m_class_has_references (klass); } /** From de011ac99fc90ed246f52d0ae75567a07b9a588a Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 29 Apr 2022 08:54:19 -0700 Subject: [PATCH 4/8] CR feedback --- .../src/System/Runtime/InteropServices/Marshal.CoreRT.cs | 2 +- .../src/System/Runtime/InteropServices/Marshal.Mono.cs | 7 +------ src/mono/mono/metadata/icall-decl.h | 2 -- src/mono/mono/metadata/icall-def.h | 1 - src/mono/mono/metadata/marshal.c | 8 -------- 5 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreRT.cs index 7c8a46f03a1e19..01bdf6fa5e55c2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreRT.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreRT.cs @@ -207,7 +207,7 @@ public static void SetLastPInvokeError(int error) internal static bool IsPinnable(object o) { - return (o == null) || o.GetEETypePtr().MightBeBlittable(); + return (o == null) || !o.GetEETypePtr().HasPointers; } [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs index 710eca1f53651a..c887bf66f23abe 100644 --- a/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs @@ -44,17 +44,12 @@ public partial class Marshal [EditorBrowsable(EditorBrowsableState.Never)] public static extern void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern bool IsPinnableType(QCallTypeHandle type); - internal static bool IsPinnable(object? obj) { if (obj == null || obj is string) return true; var type = (obj.GetType() as RuntimeType)!; - return IsPinnableType(new QCallTypeHandle(ref type)); - //Type type = obj.GetType (); - //return !type.IsValueType || RuntimeTypeHandle.HasReferences (type as RuntimeType); + return RuntimeTypeHandle.HasReferences (type); } private static void PrelinkCore(MethodInfo m) diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index 52adcd9733507f..ded4fb18faa0e0 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -197,6 +197,4 @@ ICALL_EXPORT gint32 ves_icall_RuntimeType_GetGenericParameterPosition (MonoQCall ICALL_EXPORT int ves_icall_System_Enum_InternalGetCorElementType (MonoQCallTypeHandle type_handle); -ICALL_EXPORT MonoBoolean ves_icall_System_Runtime_InteropServices_Marshal_IsPinnableType (MonoQCallTypeHandle type_handle); - #endif // __MONO_METADATA_ICALL_DECL_H__ diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index d9ce17336ab907..181396cccc2b33 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -436,7 +436,6 @@ HANDLES(MARSHAL_4, "DestroyStructure", ves_icall_System_Runtime_InteropServices_ HANDLES(MARSHAL_9, "GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal, void, 3, (MonoQCallTypeHandle, gpointer, MonoObjectHandleOnStack)) HANDLES(MARSHAL_10, "GetFunctionPointerForDelegateInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetFunctionPointerForDelegateInternal, gpointer, 1, (MonoDelegate)) NOHANDLES(ICALL(MARSHAL_11, "GetLastPInvokeError", ves_icall_System_Runtime_InteropServices_Marshal_GetLastPInvokeError)) -NOHANDLES(ICALL(MARSHAL_48a, "IsPinnableType", ves_icall_System_Runtime_InteropServices_Marshal_IsPinnableType)) HANDLES(MARSHAL_12, "OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf, int, 2, (MonoReflectionType, MonoString)) HANDLES(MARSHAL_13, "PrelinkInternal", ves_icall_System_Runtime_InteropServices_Marshal_Prelink, void, 1, (MonoReflectionMethod)) HANDLES(MARSHAL_20, "PtrToStructureInternal", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructureInternal, void, 3, (gconstpointer, MonoObject, MonoBoolean)) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 66cebbd09e1c13..c0f1d70ba65f43 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -5423,14 +5423,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_GetFunctionPointerForDelegateIn return mono_delegate_to_ftnptr_impl (delegate, error); } -MonoBoolean -ves_icall_System_Runtime_InteropServices_Marshal_IsPinnableType (MonoQCallTypeHandle type_handle) -{ - MonoClass *klass = mono_class_from_mono_type_internal (type_handle.type); - mono_class_init_internal (klass); - return m_class_has_references (klass); -} - /** * mono_marshal_is_loading_type_info: * From c3492fcaa4c47660c4afb1688ef58eedfd14fea7 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 29 Apr 2022 08:58:41 -0700 Subject: [PATCH 5/8] Update src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs Co-authored-by: Aaron Robinson --- .../System/Runtime/InteropServices/GCHandleTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs index 1c1a3300835701..2c22428e514ee1 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs @@ -194,6 +194,7 @@ public struct Blittable public struct Unmanaged { public char Object { get; set; } + public bool Object2 { get; set; } } public struct NonBlittable From 4bf5514e69d11d126358aad84e7aacb75712d690 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 29 Apr 2022 08:59:07 -0700 Subject: [PATCH 6/8] Update src/coreclr/vm/marshalnative.cpp Co-authored-by: Aaron Robinson --- src/coreclr/vm/marshalnative.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp index 9ecc4b2b95ea0c..ad9bc0fa3feb04 100644 --- a/src/coreclr/vm/marshalnative.cpp +++ b/src/coreclr/vm/marshalnative.cpp @@ -455,6 +455,7 @@ void ValidatePinnedObject(OBJECTREF obj) } CONTRACTL_END; + // Identical logic exists in managed code for Marshal.IsPinnable() if (obj != NULL && obj->GetMethodTable()->ContainsPointers()) COMPlusThrow(kArgumentException, IDS_EE_NOTISOMORPHIC); } From 07a848f486cb120d64df2a647f5be32dc20fe3c5 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 29 Apr 2022 09:12:49 -0700 Subject: [PATCH 7/8] Update src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleksey Kliger (λgeek) --- .../src/System/Runtime/InteropServices/Marshal.Mono.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs index c887bf66f23abe..8f3dca0db13bed 100644 --- a/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs @@ -49,7 +49,7 @@ internal static bool IsPinnable(object? obj) if (obj == null || obj is string) return true; var type = (obj.GetType() as RuntimeType)!; - return RuntimeTypeHandle.HasReferences (type); + return !RuntimeTypeHandle.HasReferences (type); } private static void PrelinkCore(MethodInfo m) From 78c3412c9a1c83c8b79e41c7e56473512d043a42 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 29 Apr 2022 09:34:13 -0700 Subject: [PATCH 8/8] More tests --- .../Runtime/InteropServices/GCHandleTests.cs | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs index 2c22428e514ee1..ace27b84d44e33 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GCHandleTests.cs @@ -50,11 +50,13 @@ public static IEnumerable Alloc_Type_TestData() yield return new object[] { null, GCHandleType.Pinned }; yield return new object[] { "", GCHandleType.Pinned }; yield return new object[] { 1, GCHandleType.Pinned }; + yield return new object[] { new object(), GCHandleType.Pinned }; yield return new object[] { new Blittable(), GCHandleType.Pinned }; yield return new object[] { new Blittable(), GCHandleType.Pinned }; yield return new object[] { new Blittable[0], GCHandleType.Pinned }; - yield return new object[] { new Unmanaged(), GCHandleType.Pinned }; - yield return new object[] { new Unmanaged[0], GCHandleType.Pinned }; + yield return new object[] { new UnmanagedNonBlittable(), GCHandleType.Pinned }; + yield return new object[] { new UnmanagedNonBlittable[0], GCHandleType.Pinned }; + yield return new object[] { new ClassWithoutReferences(), GCHandleType.Pinned }; } [Theory] @@ -68,8 +70,10 @@ public static void Alloc_Type_ReturnsExpected(object value, GCHandleType type) public static IEnumerable InvalidPinnedObject_TestData() { yield return new object[] { new NonBlittable() }; + yield return new object[] { new ClassWithReferences() }; yield return new object[] { new object[0] }; yield return new object[] { new NonBlittable[0] }; + yield return new object[] { new ClassWithoutReferences[0] }; } [Theory] @@ -188,18 +192,28 @@ private static void ValidateGCHandle(GCHandle handle, GCHandleType type, object public struct Blittable { - public int Object { get; set; } + public int _field; } - public struct Unmanaged + public class ClassWithoutReferences { - public char Object { get; set; } - public bool Object2 { get; set; } + public int _field; + } + + public struct UnmanagedNonBlittable + { + public char _field1; + public bool _field2; } public struct NonBlittable { - public List Object { get; set; } + public string _field; + } + + public class ClassWithReferences + { + public string _field; } } }