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/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/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..ad9bc0fa3feb04 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,9 @@ 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); + // Identical logic exists in managed code for Marshal.IsPinnable() + 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}. 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..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,9 +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 UnmanagedNonBlittable(), GCHandleType.Pinned }; + yield return new object[] { new UnmanagedNonBlittable[0], GCHandleType.Pinned }; + yield return new object[] { new ClassWithoutReferences(), GCHandleType.Pinned }; } [Theory] @@ -66,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] @@ -186,12 +192,28 @@ private static void ValidateGCHandle(GCHandle handle, GCHandleType type, object public struct Blittable { - public int Object { get; set; } + public int _field; + } + + public class ClassWithoutReferences + { + 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; } } } 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..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 @@ -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 d7f24a1e8d2f99..c0f1d70ba65f43 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -5423,20 +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); - - 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_marshal_is_loading_type_info: *