diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 6c26e38587340a..9874eef6dc2292 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -572,105 +572,288 @@ internal static void ClearNative(IntPtr pUnk) } // class InterfaceMarshaler #endif // FEATURE_COMINTEROP - internal static class MngdNativeArrayMarshaler + internal static partial class MngdNativeArrayMarshaler { // Needs to match exactly with MngdNativeArrayMarshaler in ilmarshalers.h internal struct MarshalerState { -#pragma warning disable CA1823, IDE0044 // not used by managed code - private IntPtr m_pElementMT; - private IntPtr m_Array; - private IntPtr m_pManagedNativeArrayMarshaler; - private int m_NativeDataValid; - private int m_BestFitMap; - private int m_ThrowOnUnmappableChar; - private short m_vt; -#pragma warning restore CA1823 + internal IntPtr m_pElementMT; + internal TypeHandle m_Array; + internal IntPtr m_pManagedNativeArrayMarshaler; + internal int m_NativeDataValid; + internal int m_BestFitMap; + internal int m_ThrowOnUnmappableChar; + internal short m_vt; } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags, IntPtr pManagedMarshaler); + internal static unsafe void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags, bool nativeDataValid, IntPtr pManagedMarshaler) + { + MarshalerState* pState = (MarshalerState*)pMarshalState; + pState->m_pElementMT = pMT; + pState->m_Array = default; + pState->m_pManagedNativeArrayMarshaler = pManagedMarshaler; + pState->m_NativeDataValid = nativeDataValid ? 1 : 0; + pState->m_BestFitMap = (byte)(dwFlags >> 16); + pState->m_ThrowOnUnmappableChar = (byte)(dwFlags >> 24); + pState->m_vt = (short)dwFlags; + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static void ConvertSpaceToNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertSpaceToNative(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdNativeArrayMarshaler_ConvertSpaceToNative")] + private static partial void ConvertSpaceToNative(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, - int cElements); + internal static void ConvertContentsToNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertContentsToNative(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdNativeArrayMarshaler_ConvertContentsToNative")] + private static partial void ConvertContentsToNative(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, int cElements); + internal static void ConvertSpaceToManaged(IntPtr pMarshalState, ref object? pManagedHome, IntPtr pNativeHome, + int cElements) + { + object? managedHome = null; + ConvertSpaceToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome, cElements); + pManagedHome = managedHome; + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ClearNativeContents(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, int cElements); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdNativeArrayMarshaler_ConvertSpaceToManaged")] + private static partial void ConvertSpaceToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome, + int cElements); + + internal static void ConvertContentsToManaged(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertContentsToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdNativeArrayMarshaler_ConvertContentsToManaged")] + private static partial void ConvertContentsToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); + + internal static unsafe void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome, int cElements) + { + IntPtr nativeHome = *(IntPtr*)pNativeHome; + + if (nativeHome != IntPtr.Zero) + { + ClearNativeContents(pMarshalState, pNativeHome, cElements); + Marshal.FreeCoTaskMem(nativeHome); + } + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdNativeArrayMarshaler_ClearNativeContents")] + internal static partial void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements); } // class MngdNativeArrayMarshaler - internal static class MngdFixedArrayMarshaler + internal static partial class MngdFixedArrayMarshaler { - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags, int cElements, IntPtr pManagedMarshaler); + // Needs to match exactly with MngdFixedArrayMarshaler in ilmarshalers.h + private struct MarshalerState + { +#pragma warning disable CA1823, IDE0044 // not used by managed code + internal IntPtr m_pElementMT; + internal IntPtr m_pManagedElementMarshaler; + internal IntPtr m_Array; + internal int m_BestFitMap; + internal int m_ThrowOnUnmappableChar; + internal ushort m_vt; + internal uint m_cElements; +#pragma warning restore CA1823, IDE0044 + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static unsafe void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags, int cElements, IntPtr pManagedMarshaler) + { + MarshalerState* pState = (MarshalerState*)pMarshalState; + pState->m_pElementMT = pMT; + pState->m_Array = default; + pState->m_pManagedElementMarshaler = pManagedMarshaler; + pState->m_BestFitMap = (byte)(dwFlags >> 16); + pState->m_ThrowOnUnmappableChar = (byte)(dwFlags >> 24); + pState->m_vt = (ushort)dwFlags; + pState->m_cElements = (uint)cElements; + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static unsafe void ConvertSpaceToNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + // We don't actually need to allocate native space here as the space is inline in the native layout. + // However, we need to validate that we can fit the contents of the managed array in the native space. + Array arr = (Array)pManagedHome; + MarshalerState* pState = (MarshalerState*)pMarshalState; - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + if (arr is not null && (uint)arr.Length < pState->m_cElements) + { + throw new ArgumentException(SR.Argument_WrongSizeArrayInNativeStruct); + } + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static void ConvertContentsToNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertContentsToNative(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ClearNativeContents(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdFixedArrayMarshaler_ConvertContentsToNative")] + private static partial void ConvertContentsToNative(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); + + internal static void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertSpaceToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + pManagedHome = managedHome; + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdFixedArrayMarshaler_ConvertSpaceToManaged")] + private static partial void ConvertSpaceToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); + + internal static void ConvertContentsToManaged(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertContentsToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdFixedArrayMarshaler_ConvertContentsToManaged")] + private static partial void ConvertContentsToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); + +#pragma warning disable IDE0060 // Remove unused parameter. These APIs need to match a the shape of a "managed" marshaler. + internal static void ClearNativeContents(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + ClearNativeContents(pMarshalState, pNativeHome); + } +#pragma warning restore IDE0060 + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdFixedArrayMarshaler_ClearNativeContents")] + private static partial void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome); } // class MngdFixedArrayMarshaler #if FEATURE_COMINTEROP - internal static class MngdSafeArrayMarshaler + internal static partial class MngdSafeArrayMarshaler { - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int iRank, int dwFlags, IntPtr pManagedMarshaler); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_CreateMarshaler")] + [SuppressGCTransition] + internal static partial void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int iRank, int dwFlags, IntPtr pManagedMarshaler); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, object pOriginalManaged); + internal static void ConvertSpaceToNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertSpaceToNative(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ConvertSpaceToNative")] + private static partial void ConvertSpaceToNative(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static void ConvertContentsToNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome, object pOriginalManagedObject) + { + object managedHome = pManagedHome; + object originalManagedObject = pOriginalManagedObject; + ConvertContentsToNative(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome, ObjectHandleOnStack.Create(ref originalManagedObject)); + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ConvertContentsToNative")] + private static partial void ConvertContentsToNative(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome, ObjectHandleOnStack pOriginalManagedObject); + + internal static void ConvertSpaceToManaged(IntPtr pMarshalState, ref object? pManagedHome, IntPtr pNativeHome) + { + object? managedHome = null; + ConvertSpaceToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + pManagedHome = managedHome; + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ConvertSpaceToManaged")] + private static partial void ConvertSpaceToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); + + internal static void ConvertContentsToManaged(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + object managedHome = pManagedHome; + ConvertContentsToManaged(pMarshalState, ObjectHandleOnStack.Create(ref managedHome), pNativeHome); + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ConvertContentsToManaged")] + private static partial void ConvertContentsToManaged(IntPtr pMarshalState, ObjectHandleOnStack pManagedHome, IntPtr pNativeHome); + +#pragma warning disable IDE0060 // Remove unused parameter. These APIs need to match a the shape of a "managed" marshaler. + internal static void ClearNative(IntPtr pMarshalState, in object pManagedHome, IntPtr pNativeHome) + { + ClearNative(pMarshalState, pNativeHome); + } +#pragma warning restore IDE0060 + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ClearNative")] + private static partial void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome); } // class MngdSafeArrayMarshaler #endif // FEATURE_COMINTEROP - internal static class MngdRefCustomMarshaler + internal static unsafe partial class MngdRefCustomMarshaler { - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pCMHelper); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomMarshaler_GetMarshalerObject")] + private static partial void GetMarshaler(IntPtr pCMHelper, ObjectHandleOnStack retMarshaler); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static ICustomMarshaler GetMarshaler(IntPtr pCMHelper) + { + ICustomMarshaler? marshaler = null; + GetMarshaler(pCMHelper, ObjectHandleOnStack.Create(ref marshaler)); + return marshaler!; + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static unsafe void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome) + { + // COMPAT: We never pass null to MarshalManagedToNative. + if (pManagedHome is null) + { + return; + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome); + } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void ClearManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome); + internal static void ConvertContentsToManaged(ICustomMarshaler marshaler, ref object pManagedHome, IntPtr* pNativeHome) + { + // COMPAT: We never pass null to MarshalNativeToManaged. + if (*pNativeHome == IntPtr.Zero) + { + return; + } + + pManagedHome = marshaler.MarshalNativeToManaged(*pNativeHome); + } + +#pragma warning disable IDE0060 // Remove unused parameter. These APIs need to match a the shape of a "managed" marshaler. + internal static void ClearNative(ICustomMarshaler marshaler, ref object pManagedHome, IntPtr* pNativeHome) + { + // COMPAT: We never pass null to CleanUpNativeData. + if (*pNativeHome == IntPtr.Zero) + { + return; + } + + try + { + marshaler.CleanUpNativeData(*pNativeHome); + } + catch + { + // COMPAT: We need to swallow all exceptions thrown by CleanUpNativeData. + } + } + + internal static void ClearManaged(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome) + { + // COMPAT: We never pass null to CleanUpManagedData. + if (pManagedHome is null) + { + return; + } + + marshaler.CleanUpManagedData(pManagedHome); + } +#pragma warning restore IDE0060 } // class MngdRefCustomMarshaler internal struct AsAnyMarshaler @@ -775,6 +958,7 @@ private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) pvArrayMarshaler, IntPtr.Zero, // not needed as we marshal primitive VTs only dwArrayMarshalerFlags, + nativeDataValid: false, IntPtr.Zero); // not needed as we marshal primitive VTs only IntPtr pNativeHome; @@ -782,14 +966,14 @@ private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) MngdNativeArrayMarshaler.ConvertSpaceToNative( pvArrayMarshaler, - ref pManagedHome, + in pManagedHome, pNativeHomeAddr); if (IsIn(dwFlags)) { MngdNativeArrayMarshaler.ConvertContentsToNative( pvArrayMarshaler, - ref pManagedHome, + in pManagedHome, pNativeHomeAddr); } if (IsOut(dwFlags)) @@ -984,7 +1168,7 @@ internal unsafe void ConvertToManaged(object pManagedHome, IntPtr pNativeHome) { MngdNativeArrayMarshaler.ConvertContentsToManaged( pvArrayMarshaler, - ref pManagedHome, + in pManagedHome, new IntPtr(&pNativeHome)); break; } diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index 0765484c1ee112..eb48bb390d0934 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -393,7 +393,6 @@ BEGIN IDS_INVALID_PINVOKE_CALLCONV "Unsupported unmanaged calling convention." IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET "Could not load type '%1' from assembly '%2' because field '%3' was not given an explicit offset." - IDS_WRONGSIZEARRAY_IN_NSTRUCT "Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout." IDS_EE_INVALIDLCIDPARAM "The value of the LCID conversion attribute must not exceed the number of parameters." diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h index 1a1466b854a0a8..88473e27d10257 100644 --- a/src/coreclr/dlls/mscorrc/resource.h +++ b/src/coreclr/dlls/mscorrc/resource.h @@ -185,7 +185,6 @@ #define IDS_INVALID_PINVOKE_CALLCONV 0x17c4 #define IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET 0x17c7 #define IDS_EE_BADPINVOKEFIELD_NOTMARSHALABLE 0x17c9 -#define IDS_WRONGSIZEARRAY_IN_NSTRUCT 0x17ca #define IDS_EE_INVALIDLCIDPARAM 0x17cd #define IDS_EE_BADMARSHAL_NESTEDARRAY 0x17ce diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 2fc34d04372c5e..b35ca630b8c8b5 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1031,13 +1031,13 @@ DEFINE_METHOD(VBBYVALSTRMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, DEFINE_METHOD(VBBYVALSTRMARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RetVoid) DEFINE_CLASS(MNGD_NATIVE_ARRAY_MARSHALER, StubHelpers, MngdNativeArrayMarshaler) -DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CREATE_MARSHALER, CreateMarshaler, SM_IntPtr_IntPtr_Int_IntPtr_RetVoid) +DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CREATE_MARSHALER, CreateMarshaler, SM_IntPtr_IntPtr_Int_Bool_IntPtr_RetVoid) DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CONVERT_SPACE_TO_NATIVE, ConvertSpaceToNative, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertContentsToNative, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CONVERT_SPACE_TO_MANAGED, ConvertSpaceToManaged, SM_IntPtr_RefObj_IntPtr_Int_RetVoid) DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) -DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RefObj_IntPtr_Int_RetVoid) -DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CLEAR_NATIVE_CONTENTS, ClearNativeContents, SM_IntPtr_RefObj_IntPtr_Int_RetVoid) +DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_IntPtr_Int_RetVoid) +DEFINE_METHOD(MNGD_NATIVE_ARRAY_MARSHALER, CLEAR_NATIVE_CONTENTS, ClearNativeContents, SM_IntPtr_IntPtr_Int_RetVoid) DEFINE_CLASS(MNGD_FIXED_ARRAY_MARSHALER, StubHelpers, MngdFixedArrayMarshaler) DEFINE_METHOD(MNGD_FIXED_ARRAY_MARSHALER, CREATE_MARSHALER, CreateMarshaler, SM_IntPtr_IntPtr_Int_Int_IntPtr_RetVoid) @@ -1048,11 +1048,11 @@ DEFINE_METHOD(MNGD_FIXED_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertCo DEFINE_METHOD(MNGD_FIXED_ARRAY_MARSHALER, CLEAR_NATIVE_CONTENTS, ClearNativeContents, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_CLASS(MNGD_REF_CUSTOM_MARSHALER, StubHelpers, MngdRefCustomMarshaler) -DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CREATE_MARSHALER, CreateMarshaler, SM_IntPtr_IntPtr_RetVoid) -DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertContentsToNative, SM_IntPtr_RefObj_IntPtr_RetVoid) -DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) -DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RefObj_IntPtr_RetVoid) -DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_MANAGED, ClearManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) +DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertContentsToNative, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) +DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) +DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_NATIVE, ClearNative, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) +DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_MANAGED, ClearManaged, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) +DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, GET_MARSHALER, GetMarshaler, SM_IntPtr_RetICustomMarshaler) DEFINE_CLASS(ASANY_MARSHALER, StubHelpers, AsAnyMarshaler) DEFINE_METHOD(ASANY_MARSHALER, CTOR, .ctor, IM_IntPtr_RetVoid) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 5192b788fc42cf..81c4122512e65a 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -646,5 +646,13 @@ CustomMarshalerInfo *SharedCustomMarshalerHelper::GetCustomMarshalerInfo() return pMarshalingData->GetCustomMarshalerInfo(this); } +extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject) +{ + QCALL_CONTRACT; + BEGIN_QCALL; + GCX_COOP(); + retObject.Set(pCMHelper->GetCustomMarshalerInfo()->GetCustomMarshaler()); + END_QCALL; +} diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index a1502f8d242d30..802918dcd675f9 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -315,5 +315,6 @@ class SharedCustomMarshalerHelper : public CustomMarshalerHelper LPCUTF8 m_strCookie; }; +extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject); #endif // _CUSTOMMARSHALERINFO_H_ diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index e6b1ae38cd77bc..8966a8491e111e 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -488,44 +488,6 @@ FCFuncStart(gMethodTableFuncs) FCFuncElement("GetNumInstanceFieldBytes", MethodTableNative::GetNumInstanceFieldBytes) FCFuncEnd() -FCFuncStart(gMngdFixedArrayMarshalerFuncs) - FCFuncElement("CreateMarshaler", MngdFixedArrayMarshaler::CreateMarshaler) - FCFuncElement("ConvertSpaceToNative", MngdFixedArrayMarshaler::ConvertSpaceToNative) - FCFuncElement("ConvertContentsToNative", MngdFixedArrayMarshaler::ConvertContentsToNative) - FCFuncElement("ConvertSpaceToManaged", MngdFixedArrayMarshaler::ConvertSpaceToManaged) - FCFuncElement("ConvertContentsToManaged", MngdFixedArrayMarshaler::ConvertContentsToManaged) - FCFuncElement("ClearNativeContents", MngdFixedArrayMarshaler::ClearNativeContents) -FCFuncEnd() - -FCFuncStart(gMngdNativeArrayMarshalerFuncs) - FCFuncElement("CreateMarshaler", MngdNativeArrayMarshaler::CreateMarshaler) - FCFuncElement("ConvertSpaceToNative", MngdNativeArrayMarshaler::ConvertSpaceToNative) - FCFuncElement("ConvertContentsToNative", MngdNativeArrayMarshaler::ConvertContentsToNative) - FCFuncElement("ConvertSpaceToManaged", MngdNativeArrayMarshaler::ConvertSpaceToManaged) - FCFuncElement("ConvertContentsToManaged", MngdNativeArrayMarshaler::ConvertContentsToManaged) - FCFuncElement("ClearNative", MngdNativeArrayMarshaler::ClearNative) - FCFuncElement("ClearNativeContents", MngdNativeArrayMarshaler::ClearNativeContents) -FCFuncEnd() - -#ifdef FEATURE_COMINTEROP -FCFuncStart(gMngdSafeArrayMarshalerFuncs) - FCFuncElement("CreateMarshaler", MngdSafeArrayMarshaler::CreateMarshaler) - FCFuncElement("ConvertSpaceToNative", MngdSafeArrayMarshaler::ConvertSpaceToNative) - FCFuncElement("ConvertContentsToNative", MngdSafeArrayMarshaler::ConvertContentsToNative) - FCFuncElement("ConvertSpaceToManaged", MngdSafeArrayMarshaler::ConvertSpaceToManaged) - FCFuncElement("ConvertContentsToManaged", MngdSafeArrayMarshaler::ConvertContentsToManaged) - FCFuncElement("ClearNative", MngdSafeArrayMarshaler::ClearNative) -FCFuncEnd() -#endif // FEATURE_COMINTEROP - -FCFuncStart(gMngdRefCustomMarshalerFuncs) - FCFuncElement("CreateMarshaler", MngdRefCustomMarshaler::CreateMarshaler) - FCFuncElement("ConvertContentsToNative", MngdRefCustomMarshaler::ConvertContentsToNative) - FCFuncElement("ConvertContentsToManaged", MngdRefCustomMarshaler::ConvertContentsToManaged) - FCFuncElement("ClearNative", MngdRefCustomMarshaler::ClearNative) - FCFuncElement("ClearManaged", MngdRefCustomMarshaler::ClearManaged) -FCFuncEnd() - FCFuncStart(gStubHelperFuncs) FCFuncElement("GetDelegateTarget", StubHelpers::GetDelegateTarget) FCFuncElement("TryGetStringTrailByte", StubHelpers::TryGetStringTrailByte) @@ -636,12 +598,6 @@ FCClassElement("Math", "System", gMathFuncs) FCClassElement("MathF", "System", gMathFFuncs) FCClassElement("MetadataImport", "System.Reflection", gMetaDataImport) FCClassElement("MethodTable", "System.Runtime.CompilerServices", gMethodTableFuncs) -FCClassElement("MngdFixedArrayMarshaler", "System.StubHelpers", gMngdFixedArrayMarshalerFuncs) -FCClassElement("MngdNativeArrayMarshaler", "System.StubHelpers", gMngdNativeArrayMarshalerFuncs) -FCClassElement("MngdRefCustomMarshaler", "System.StubHelpers", gMngdRefCustomMarshalerFuncs) -#ifdef FEATURE_COMINTEROP -FCClassElement("MngdSafeArrayMarshaler", "System.StubHelpers", gMngdSafeArrayMarshalerFuncs) -#endif // FEATURE_COMINTEROP FCClassElement("ModuleHandle", "System", gCOMModuleHandleFuncs) FCClassElement("Monitor", "System.Threading", gMonitorFuncs) FCClassElement("Object", "System", gObjectFuncs) diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 1c87acac73685f..59bb7c9ebed2de 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -3786,8 +3786,7 @@ void ILAsAnyMarshalerBase::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(marshalerType); DWORD dwTmpLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I); - _ASSERTE(sizeof(MngdNativeArrayMarshaler) == sizeof(void*) * 3 + 16); - pslILEmit->EmitLDC(TARGET_POINTER_SIZE * 3 + 16); // sizeof(MngdNativeArrayMarshaler) + pslILEmit->EmitLDC(sizeof(MngdNativeArrayMarshaler)); pslILEmit->EmitLOCALLOC(); pslILEmit->EmitSTLOC(dwTmpLocalNum); @@ -3884,8 +3883,7 @@ void ILNativeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I); - _ASSERTE(sizeof(MngdNativeArrayMarshaler) == sizeof(void*) * 3 + 16); - pslILEmit->EmitLDC(TARGET_POINTER_SIZE * 3 + 16); // sizeof(MngdNativeArrayMarshaler) + pslILEmit->EmitLDC(sizeof(MngdNativeArrayMarshaler)); pslILEmit->EmitLOCALLOC(); pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum); @@ -3901,14 +3899,16 @@ void ILNativeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) dwFlags |= (((DWORD)mops.bestfitmapping) << 16); dwFlags |= (((DWORD)mops.throwonunmappablechar) << 24); + pslILEmit->EmitLDC(dwFlags); + if (!IsCLRToNative(m_dwMarshalFlags) && IsOut(m_dwMarshalFlags) && IsIn(m_dwMarshalFlags)) { - // Unmanaged->managed in/out is the only case where we expect the native buffer to contain valid data. - _ASSERTE((dwFlags & MngdNativeArrayMarshaler::FLAG_NATIVE_DATA_VALID) == 0); - dwFlags |= MngdNativeArrayMarshaler::FLAG_NATIVE_DATA_VALID; + pslILEmit->EmitLDC(1); // true + } + else + { + pslILEmit->EmitLDC(0); // false } - - pslILEmit->EmitLDC(dwFlags); if (mops.elementType == VT_RECORD && !mops.methodTable->IsBlittable()) { @@ -3919,7 +3919,7 @@ void ILNativeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) pslILEmit->EmitLoadNullPtr(); } - pslILEmit->EmitCALL(METHOD__MNGD_NATIVE_ARRAY_MARSHALER__CREATE_MARSHALER, 4, 0); + pslILEmit->EmitCALL(METHOD__MNGD_NATIVE_ARRAY_MARSHALER__CREATE_MARSHALER, 5, 0); } bool ILNativeArrayMarshaler::CanMarshalViaPinning() @@ -4236,7 +4236,6 @@ void ILNativeArrayMarshaler::EmitClearNative(ILCodeStream* pslILEmit) STANDARD_VM_CONTRACT; EmitLoadMngdMarshaler(pslILEmit); - EmitLoadManagedHomeAddr(pslILEmit); EmitLoadNativeHomeAddr(pslILEmit); EmitLoadNativeSize(pslILEmit); @@ -4271,7 +4270,6 @@ void ILNativeArrayMarshaler::EmitClearNativeContents(ILCodeStream* pslILEmit) STANDARD_VM_CONTRACT; EmitLoadMngdMarshaler(pslILEmit); - EmitLoadManagedHomeAddr(pslILEmit); EmitLoadNativeHomeAddr(pslILEmit); EmitLoadNativeSize(pslILEmit); @@ -4296,52 +4294,33 @@ void ILNativeArrayMarshaler::EmitNewSavedSizeArgLocal(ILCodeStream* pslILEmit) pslILEmit->EmitSTLOC(m_dwSavedSizeArg); } - -FCIMPL4(void, MngdNativeArrayMarshaler::CreateMarshaler, MngdNativeArrayMarshaler* pThis, MethodTable* pMT, UINT32 dwFlags, PCODE pManagedMarshaler) +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertSpaceToNative(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; - // Don't check whether the input values are negative - passing negative size-controlling - // arguments and compensating them with a positive SizeConst has always worked. - pThis->m_pElementMT = pMT; - pThis->m_vt = (VARTYPE)(dwFlags); - pThis->m_NativeDataValid = (BYTE)((dwFlags & FLAG_NATIVE_DATA_VALID) != 0); - dwFlags &= ~FLAG_NATIVE_DATA_VALID; - pThis->m_BestFitMap = (BYTE)(dwFlags >> 16); - pThis->m_ThrowOnUnmappableChar = (BYTE)(dwFlags >> 24); - pThis->m_Array = TypeHandle(); - pThis->m_pManagedMarshaler = pManagedMarshaler; -} -FCIMPLEND - -FCIMPL3(void, MngdNativeArrayMarshaler::ConvertSpaceToNative, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) -{ - FCALL_CONTRACT; + BEGIN_QCALL; - HELPER_METHOD_FRAME_BEGIN_0(); + GCX_COOP(); - BASEARRAYREF arrayRef = (BASEARRAYREF) *pManagedHome; - - if (arrayRef == NULL) + if (pManagedHome.Get() == NULL) { *pNativeHome = NULL; } else { - SIZE_T cElements = arrayRef->GetNumComponents(); + SIZE_T cElements = ((BASEARRAYREF)pManagedHome.Get())->GetNumComponents(); SIZE_T cbElement = OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT); if (cbElement == 0) COMPlusThrow(kArgumentException, IDS_EE_COM_UNSUPPORTED_SIG); + GCX_PREEMP(); + SIZE_T cbArray; if ( (!ClrSafeInt::multiply(cElements, cbElement, cbArray)) || cbArray > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); - { - GCX_PREEMP(); - *pNativeHome = CoTaskMemAlloc(cbArray); - } + *pNativeHome = CoTaskMemAlloc(cbArray); if (*pNativeHome == NULL) ThrowOutOfMemory(); @@ -4350,50 +4329,56 @@ FCIMPL3(void, MngdNativeArrayMarshaler::ConvertSpaceToNative, MngdNativeArrayMar FillMemory(*pNativeHome, cbArray, 0); } - HELPER_METHOD_FRAME_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdNativeArrayMarshaler::ConvertContentsToNative, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertContentsToNative(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; + + BEGIN_QCALL; - HELPER_METHOD_FRAME_BEGIN_0(); + GCX_COOP(); - BASEARRAYREF* pArrayRef = (BASEARRAYREF *) pManagedHome; + BASEARRAYREF arrayRef = NULL; + GCPROTECT_BEGIN(arrayRef); + arrayRef = (BASEARRAYREF)pManagedHome.Get(); - if (*pArrayRef != NULL) + if (arrayRef != NULL) { const OleVariant::Marshaler* pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, TRUE); - SIZE_T cElements = (*pArrayRef)->GetNumComponents(); + SIZE_T cElements = arrayRef->GetNumComponents(); if (pMarshaler == NULL || pMarshaler->ComToOleArray == NULL) { if ( (!ClrSafeInt::multiply(cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT), cElements)) || cElements > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); _ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers()); - memcpyNoGCRefs(*pNativeHome, (*pArrayRef)->GetDataPtr(), cElements); + memcpyNoGCRefs(*pNativeHome, arrayRef->GetDataPtr(), cElements); } else { - pMarshaler->ComToOleArray(pArrayRef, *pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap, + pMarshaler->ComToOleArray(&arrayRef, *pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap, pThis->m_ThrowOnUnmappableChar, pThis->m_NativeDataValid, cElements, pThis->m_pManagedMarshaler); } } - HELPER_METHOD_FRAME_END(); + + GCPROTECT_END(); + + END_QCALL; } -FCIMPLEND -FCIMPL4(void, MngdNativeArrayMarshaler::ConvertSpaceToManaged, MngdNativeArrayMarshaler* pThis, - OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements) +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertSpaceToManaged(MngdNativeArrayMarshaler* pThis, + QCall::ObjectHandleOnStack managedHome, void** pNativeHome, INT32 cElements) { - FCALL_CONTRACT; + QCALL_CONTRACT; - HELPER_METHOD_FRAME_BEGIN_0(); + BEGIN_QCALL; + GCX_COOP(); if (*pNativeHome == NULL) { - SetObjectReference(pManagedHome, NULL); + managedHome.Set(NULL); } else { @@ -4408,84 +4393,53 @@ FCIMPL4(void, MngdNativeArrayMarshaler::ConvertSpaceToManaged, MngdNativeArrayMa // // Allocate array // - SetObjectReference(pManagedHome, AllocateSzArray(pThis->m_Array, cElements)); + managedHome.Set(AllocateSzArray(pThis->m_Array, cElements)); } - HELPER_METHOD_FRAME_END(); + + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdNativeArrayMarshaler::ConvertContentsToManaged, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertContentsToManaged(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; + + BEGIN_QCALL; - HELPER_METHOD_FRAME_BEGIN_0(); + GCX_COOP(); + + BASEARRAYREF arrayRef = NULL; + GCPROTECT_BEGIN(arrayRef); + arrayRef = (BASEARRAYREF)pManagedHome.Get(); if (*pNativeHome != NULL) { const OleVariant::Marshaler *pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, TRUE); - BASEARRAYREF* pArrayRef = (BASEARRAYREF*) pManagedHome; - if (pMarshaler == NULL || pMarshaler->OleToComArray == NULL) { SIZE_T cElements; - if ( (!ClrSafeInt::multiply((*pArrayRef)->GetNumComponents(), OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT), cElements)) || cElements > MAX_SIZE_FOR_INTEROP) + if ( (!ClrSafeInt::multiply(arrayRef->GetNumComponents(), OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT), cElements)) || cElements > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); // If we are copying variants, strings, etc, we need to use write barrier _ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers()); - memcpyNoGCRefs((*pArrayRef)->GetDataPtr(), *pNativeHome, cElements); + memcpyNoGCRefs(arrayRef->GetDataPtr(), *pNativeHome, cElements); } else { - pMarshaler->OleToComArray(*pNativeHome, pArrayRef, pThis->m_pElementMT, pThis->m_pManagedMarshaler); + pMarshaler->OleToComArray(*pNativeHome, &arrayRef, pThis->m_pElementMT, pThis->m_pManagedMarshaler); } } - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - -FCIMPL4(void, MngdNativeArrayMarshaler::ClearNative, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements) -{ - FCALL_CONTRACT; - - HELPER_METHOD_FRAME_BEGIN_0(); - - if (*pNativeHome != NULL) - { - DoClearNativeContents(pThis, pManagedHome, pNativeHome, cElements); - { - GCX_PREEMP(); - CoTaskMemFree(*pNativeHome); - } - } - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - -FCIMPL4(void, MngdNativeArrayMarshaler::ClearNativeContents, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements) -{ - FCALL_CONTRACT; - - HELPER_METHOD_FRAME_BEGIN_0(); - - DoClearNativeContents(pThis, pManagedHome, pNativeHome, cElements); - - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND -void MngdNativeArrayMarshaler::DoClearNativeContents(MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements) +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ClearNativeContents(MngdNativeArrayMarshaler* pThis, void** pNativeHome, INT32 cElements) { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; + QCALL_CONTRACT; + BEGIN_QCALL; + GCX_COOP(); if (*pNativeHome != NULL) { @@ -4496,9 +4450,9 @@ void MngdNativeArrayMarshaler::DoClearNativeContents(MngdNativeArrayMarshaler* p pMarshaler->ClearOleArray(*pNativeHome, cElements, pThis->m_pElementMT, pThis->m_pManagedMarshaler); } } -} - + END_QCALL; +} void ILFixedArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) { @@ -4506,8 +4460,7 @@ void ILFixedArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I); - _ASSERTE(sizeof(MngdFixedArrayMarshaler) == sizeof(void*) * 4 + 16); - pslILEmit->EmitLDC(TARGET_POINTER_SIZE * 4 + 16); // sizeof(MngdFixedArrayMarshaler) + pslILEmit->EmitLDC(sizeof(MngdFixedArrayMarshaler)); pslILEmit->EmitLOCALLOC(); pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum); @@ -4539,49 +4492,16 @@ void ILFixedArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) pslILEmit->EmitCALL(METHOD__MNGD_FIXED_ARRAY_MARSHALER__CREATE_MARSHALER, 5, 0); } - -FCIMPL5(void, MngdFixedArrayMarshaler::CreateMarshaler, MngdFixedArrayMarshaler* pThis, MethodTable* pMT, UINT32 dwFlags, UINT32 cElements, PCODE pManagedElementMarshaler) -{ - FCALL_CONTRACT; - - // Don't check whether the input values are negative - passing negative size-controlling - // arguments and compensating them with a positive SizeConst has always worked. - pThis->m_pElementMT = pMT; - pThis->m_vt = (VARTYPE)(dwFlags); - pThis->m_NativeDataValid = (BYTE)((dwFlags & FLAG_NATIVE_DATA_VALID) != 0); - dwFlags &= ~FLAG_NATIVE_DATA_VALID; - pThis->m_BestFitMap = (BYTE)(dwFlags >> 16); - pThis->m_ThrowOnUnmappableChar = (BYTE)(dwFlags >> 24); - pThis->m_Array = TypeHandle(); - pThis->m_cElements = cElements; - pThis->m_pManagedElementMarshaler = pManagedElementMarshaler; -} -FCIMPLEND - -FCIMPL3(void, MngdFixedArrayMarshaler::ConvertSpaceToNative, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome) +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ConvertContentsToNative(MngdFixedArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void* pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; + BEGIN_QCALL; - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; + GCX_COOP(); - HELPER_METHOD_FRAME_BEGIN_1(arrayRef); - - if (arrayRef != NULL && arrayRef->GetNumComponents() < pThis->m_cElements) - { - COMPlusThrow(kArgumentException, IDS_WRONGSIZEARRAY_IN_NSTRUCT); - } - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - -FCIMPL3(void, MngdFixedArrayMarshaler::ConvertContentsToNative, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome) -{ - FCALL_CONTRACT; - - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; - - HELPER_METHOD_FRAME_BEGIN_1(arrayRef); + BASEARRAYREF arrayRef = NULL; + GCPROTECT_BEGIN(arrayRef); + arrayRef = (BASEARRAYREF)pManagedHome.Get(); if (pThis->m_vt == VTHACK_ANSICHAR) { @@ -4623,26 +4543,23 @@ FCIMPL3(void, MngdFixedArrayMarshaler::ConvertContentsToNative, MngdFixedArrayMa else { pMarshaler->ComToOleArray(&arrayRef, pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap, - pThis->m_ThrowOnUnmappableChar, pThis->m_NativeDataValid, pThis->m_cElements, pThis->m_pManagedElementMarshaler); + pThis->m_ThrowOnUnmappableChar, FALSE, pThis->m_cElements, pThis->m_pManagedElementMarshaler); } } } - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdFixedArrayMarshaler::ConvertSpaceToManaged, MngdFixedArrayMarshaler* pThis, - OBJECTREF* pManagedHome, void* pNativeHome) +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ConvertSpaceToManaged(MngdFixedArrayMarshaler* pThis, + QCall::ObjectHandleOnStack pManagedHome, void* pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; - HELPER_METHOD_FRAME_BEGIN_0(); + BEGIN_QCALL; - // In the field scenario, pManagedHome points to a field inside a struct/object. - // Since we are setting the value of this field with SetObjectReference, we need to - // make sure that pManagedHome is GC-protected. - GCPROTECT_BEGININTERIOR(pManagedHome); + GCX_COOP(); // @todo: lookup this class before marshal time if (pThis->m_Array.IsNull()) @@ -4657,21 +4574,22 @@ FCIMPL3(void, MngdFixedArrayMarshaler::ConvertSpaceToManaged, MngdFixedArrayMars // OBJECTREF arrayRef = AllocateSzArray(pThis->m_Array, pThis->m_cElements); - SetObjectReference(pManagedHome, arrayRef); - - GCPROTECT_END(); + pManagedHome.Set(arrayRef); - HELPER_METHOD_FRAME_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdFixedArrayMarshaler::ConvertContentsToManaged, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome) +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ConvertContentsToManaged(MngdFixedArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void* pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; + BEGIN_QCALL; - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; + GCX_COOP(); - HELPER_METHOD_FRAME_BEGIN_1(arrayRef); + BASEARRAYREF arrayRef = NULL; + + GCPROTECT_BEGIN(arrayRef); + arrayRef = (BASEARRAYREF)pManagedHome.Get(); if (pThis->m_vt == VTHACK_ANSICHAR) { @@ -4702,15 +4620,15 @@ FCIMPL3(void, MngdFixedArrayMarshaler::ConvertContentsToManaged, MngdFixedArrayM } } - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdFixedArrayMarshaler::ClearNativeContents, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome) +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ClearNativeContents(MngdFixedArrayMarshaler* pThis, void* pNativeHome) { - FCALL_CONTRACT; - - HELPER_METHOD_FRAME_BEGIN_0(); + QCALL_CONTRACT; + BEGIN_QCALL; + GCX_COOP(); const OleVariant::Marshaler* pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, FALSE); @@ -4719,11 +4637,8 @@ FCIMPL3(void, MngdFixedArrayMarshaler::ClearNativeContents, MngdFixedArrayMarsha pMarshaler->ClearOleArray(pNativeHome, pThis->m_cElements, pThis->m_pElementMT, pThis->m_pManagedElementMarshaler); } - HELPER_METHOD_FRAME_END(); + END_QCALL; } -FCIMPLEND - - #ifdef FEATURE_COMINTEROP void ILSafeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) @@ -4809,11 +4724,9 @@ void ILSafeArrayMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmi pslILEmit->EmitCALL(METHOD__MNGD_SAFE_ARRAY_MARSHALER__CONVERT_CONTENTS_TO_NATIVE, 4, 0); } - - -FCIMPL5(void, MngdSafeArrayMarshaler::CreateMarshaler, MngdSafeArrayMarshaler* pThis, MethodTable* pMT, UINT32 iRank, UINT32 dwFlags, PCODE pManagedMarshaler) +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_CreateMarshaler(MngdSafeArrayMarshaler* pThis, MethodTable* pMT, UINT32 iRank, UINT32 dwFlags, PCODE pManagedMarshaler) { - FCALL_CONTRACT; + QCALL_CONTRACT_NO_GC_TRANSITION; pThis->m_pElementMT = pMT; pThis->m_iRank = iRank; @@ -4822,30 +4735,29 @@ FCIMPL5(void, MngdSafeArrayMarshaler::CreateMarshaler, MngdSafeArrayMarshaler* p pThis->m_nolowerbounds = (BYTE)(dwFlags >> 24); pThis->m_pManagedMarshaler = pManagedMarshaler; } -FCIMPLEND -FCIMPL3(void, MngdSafeArrayMarshaler::ConvertSpaceToNative, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertSpaceToNative(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome) { - FCALL_CONTRACT; - - if (pThis->m_fStatic & SCSF_IsStatic) - return; - - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; - - HELPER_METHOD_FRAME_BEGIN_1(arrayRef); - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; + QCALL_CHECK; PRECONDITION(pThis->m_vt != VT_EMPTY); PRECONDITION(CheckPointer(pThis->m_pElementMT)); } CONTRACTL_END; - if (*pManagedHome != NULL) + if (pThis->m_fStatic & MngdSafeArrayMarshaler::SCSF_IsStatic) + return; + + BEGIN_QCALL; + + GCX_COOP(); + + BASEARRAYREF arrayRef = NULL; + GCPROTECT_BEGIN(arrayRef); + arrayRef = (BASEARRAYREF)pManagedHome.Get(); + + if (arrayRef != NULL) { *pNativeHome = (void *) OleVariant::CreateSafeArrayForArrayRef(&arrayRef, pThis->m_vt, pThis->m_pElementMT); } @@ -4854,60 +4766,67 @@ FCIMPL3(void, MngdSafeArrayMarshaler::ConvertSpaceToNative, MngdSafeArrayMarshal *pNativeHome = NULL; } - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + + END_QCALL; } -FCIMPLEND -FCIMPL4(void, MngdSafeArrayMarshaler::ConvertContentsToNative, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, Object* pOriginalManagedUNSAFE) +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertContentsToNative(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome, QCall::ObjectHandleOnStack pOriginalManaged) { CONTRACTL { - FCALL_CHECK; + QCALL_CHECK; PRECONDITION(pThis->m_vt != VT_EMPTY); PRECONDITION(CheckPointer(pThis->m_pElementMT)); } CONTRACTL_END; - OBJECTREF pOriginalManaged = ObjectToOBJECTREF(pOriginalManagedUNSAFE); - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; - HELPER_METHOD_FRAME_BEGIN_2(arrayRef, pOriginalManaged); + BEGIN_QCALL; + GCX_COOP(); - if ((pThis->m_fStatic & SCSF_IsStatic) && - (*pManagedHome != pOriginalManaged)) + struct + { + OBJECTREF originalManaged; + BASEARRAYREF arrayRef; + } gc = {NULL, NULL}; + + GCPROTECT_BEGIN(gc); + + gc.originalManaged = pOriginalManaged.Get(); + gc.arrayRef = (BASEARRAYREF)pManagedHome.Get(); + + if ((pThis->m_fStatic & MngdSafeArrayMarshaler::SCSF_IsStatic) && + (gc.arrayRef != gc.originalManaged)) { COMPlusThrow(kInvalidOperationException, IDS_INVALID_REDIM); } - if (*pManagedHome != NULL) + if (gc.arrayRef != NULL) { - OleVariant::MarshalSafeArrayForArrayRef(&arrayRef, + OleVariant::MarshalSafeArrayForArrayRef(&gc.arrayRef, (SAFEARRAY*)*pNativeHome, pThis->m_vt, pThis->m_pElementMT, pThis->m_pManagedMarshaler, - (pThis->m_fStatic & SCSF_NativeDataValid)); + (pThis->m_fStatic & MngdSafeArrayMarshaler::SCSF_NativeDataValid)); } - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdSafeArrayMarshaler::ConvertSpaceToManaged, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertSpaceToManaged(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome) { CONTRACTL { - FCALL_CHECK; + QCALL_CHECK; PRECONDITION(pThis->m_vt != VT_EMPTY); PRECONDITION(CheckPointer(pThis->m_pElementMT)); } CONTRACTL_END; - HELPER_METHOD_FRAME_BEGIN_0(); - - // In the field scenario, pManagedHome points to a field inside a struct/object. - // Since we are setting the value of this field with SetObjectReference, we need to - // make sure that pManagedHome is GC-protected. - GCPROTECT_BEGININTERIOR(pManagedHome); + BEGIN_QCALL; + GCX_COOP(); if (*pNativeHome != NULL) { @@ -4943,72 +4862,69 @@ FCIMPL3(void, MngdSafeArrayMarshaler::ConvertSpaceToManaged, MngdSafeArrayMarsha pThis->m_vt, pThis->m_pElementMT); - SetObjectReference(pManagedHome, arrayRef); + pManagedHome.Set(arrayRef); } else { - SetObjectReference(pManagedHome, NULL); + pManagedHome.Set(NULL); } - GCPROTECT_END(); - - HELPER_METHOD_FRAME_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdSafeArrayMarshaler::ConvertContentsToManaged, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertContentsToManaged(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome) { CONTRACTL { - FCALL_CHECK; + QCALL_CHECK; PRECONDITION(pThis->m_vt != VT_EMPTY); PRECONDITION(CheckPointer(pThis->m_pElementMT)); } CONTRACTL_END; + BEGIN_QCALL; + GCX_COOP(); + SAFEARRAY* pNative = *(SAFEARRAY**)pNativeHome; - BASEARRAYREF arrayRef = (BASEARRAYREF)*pManagedHome; - HELPER_METHOD_FRAME_BEGIN_1(arrayRef); + BASEARRAYREF arrayRef = NULL; + + GCPROTECT_BEGIN(arrayRef); + arrayRef = (BASEARRAYREF) pManagedHome.Get(); if (pNative && pNative->fFeatures & FADF_STATIC) { - pThis->m_fStatic |= SCSF_IsStatic; + pThis->m_fStatic |= MngdSafeArrayMarshaler::SCSF_IsStatic; } if (*pNativeHome != NULL) { - OleVariant::MarshalArrayRefForSafeArray((SAFEARRAY*)*pNativeHome, + OleVariant::MarshalArrayRefForSafeArray(pNative, &arrayRef, pThis->m_vt, pThis->m_pManagedMarshaler, pThis->m_pElementMT); } - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND -FCIMPL3(void, MngdSafeArrayMarshaler::ClearNative, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ClearNative(MngdSafeArrayMarshaler* pThis, void** pNativeHome) { - FCALL_CONTRACT; + QCALL_CONTRACT; - if (pThis->m_fStatic & SCSF_IsStatic) + if (pThis->m_fStatic & MngdSafeArrayMarshaler::SCSF_IsStatic) return; - HELPER_METHOD_FRAME_BEGIN_0(); + BEGIN_QCALL; if (*pNativeHome != NULL) { - GCX_PREEMP(); - _ASSERTE(GetModuleHandleA("oleaut32.dll") != NULL); - // SafeArray has been created. Oleaut32.dll must have been loaded. - CONTRACT_VIOLATION(ThrowsViolation); SafeArrayDestroy((SAFEARRAY*)*pNativeHome); } - HELPER_METHOD_FRAME_END(); + END_QCALL; } -FCIMPLEND #endif // FEATURE_COMINTEROP @@ -5022,17 +4938,10 @@ void ILReferenceCustomMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit CONTRACTL_END; // - // allocate space for marshaler + // allocate space for marshaler state // - m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(ELEMENT_TYPE_I); - - _ASSERTE(sizeof(MngdRefCustomMarshaler) == sizeof(void*)); - pslILEmit->EmitLDC(TARGET_POINTER_SIZE); // sizeof(MngdRefCustomMarshaler) - pslILEmit->EmitLOCALLOC(); - pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum); - - pslILEmit->EmitLDLOC(m_dwMngdMarshalerLocalNum); // arg to CreateMarshaler + m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); // // call CreateCustomMarshalerHelper @@ -5046,95 +4955,10 @@ void ILReferenceCustomMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(TypeHandle::FromPtr(m_pargs->rcm.m_hndManagedType))); pslILEmit->EmitCALL(METHOD__RT_TYPE_HANDLE__TO_INTPTR, 1, 1); - pslILEmit->EmitCALL(METHOD__STUBHELPERS__CREATE_CUSTOM_MARSHALER_HELPER, 3, 1); // arg to CreateMarshaler + pslILEmit->EmitCALL(METHOD__STUBHELPERS__CREATE_CUSTOM_MARSHALER_HELPER, 3, 1); // Create the CustomMarshalerHelper - // - // call MngdRefCustomMarshaler::CreateMarshaler - // + // Get the managed ICustomMarshaler object from the helper + pslILEmit->EmitCALL(METHOD__MNGD_REF_CUSTOM_MARSHALER__GET_MARSHALER, 1, 1); - pslILEmit->EmitCALL(METHOD__MNGD_REF_CUSTOM_MARSHALER__CREATE_MARSHALER, 2, 0); + pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum); // Store the ICustomMarshaler as our marshaler state } - - - -FCIMPL2(void, MngdRefCustomMarshaler::CreateMarshaler, MngdRefCustomMarshaler* pThis, void* pCMHelper) -{ - FCALL_CONTRACT; - - pThis->m_pCMHelper = (CustomMarshalerHelper*)pCMHelper; -} -FCIMPLEND - - -FCIMPL3(void, MngdRefCustomMarshaler::ConvertContentsToNative, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(CheckPointer(pManagedHome)); - } - CONTRACTL_END; - - HELPER_METHOD_FRAME_BEGIN_0(); - - *pNativeHome = pThis->m_pCMHelper->InvokeMarshalManagedToNativeMeth(*pManagedHome); - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - - -FCIMPL3(void, MngdRefCustomMarshaler::ConvertContentsToManaged, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(CheckPointer(pManagedHome)); - } - CONTRACTL_END; - - HELPER_METHOD_FRAME_BEGIN_0(); - - SetObjectReference(pManagedHome, pThis->m_pCMHelper->InvokeMarshalNativeToManagedMeth(*pNativeHome)); - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - -FCIMPL3(void, MngdRefCustomMarshaler::ClearNative, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) -{ - FCALL_CONTRACT; - - HELPER_METHOD_FRAME_BEGIN_0(); - - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - pThis->m_pCMHelper->InvokeCleanUpNativeMeth(*pNativeHome); - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - -FCIMPL3(void, MngdRefCustomMarshaler::ClearManaged, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(CheckPointer(pManagedHome)); - } - CONTRACTL_END; - - HELPER_METHOD_FRAME_BEGIN_0(); - - pThis->m_pCMHelper->InvokeCleanUpManagedMeth(*pManagedHome); - - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND - diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index 61ff10ac2b2b86..02589d44994fb5 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -3235,23 +3235,8 @@ private : DWORD m_dwSavedSizeArg; }; -class MngdNativeArrayMarshaler +struct MngdNativeArrayMarshaler { -public: - static FCDECL4(void, CreateMarshaler, MngdNativeArrayMarshaler* pThis, MethodTable* pMT, UINT32 dwFlags, PCODE pManagedMarshaler); - static FCDECL3(void, ConvertSpaceToNative, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL3(void, ConvertContentsToNative, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL4(void, ConvertSpaceToManaged, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements); - static FCDECL3(void, ConvertContentsToManaged, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL4(void, ClearNative, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements); - static FCDECL4(void, ClearNativeContents, MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements); - - static void DoClearNativeContents(MngdNativeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, INT32 cElements); - enum - { - FLAG_NATIVE_DATA_VALID = 0x40000000 - }; - MethodTable* m_pElementMT; TypeHandle m_Array; PCODE m_pManagedMarshaler; @@ -3261,6 +3246,12 @@ class MngdNativeArrayMarshaler VARTYPE m_vt; }; +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertSpaceToNative(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome); +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertContentsToNative(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome); +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertSpaceToManaged(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome, INT32 cElements); +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ConvertContentsToManaged(MngdNativeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome); +extern "C" void QCALLTYPE MngdNativeArrayMarshaler_ClearNativeContents(MngdNativeArrayMarshaler* pThis, void** pNativeHome, INT32 cElements); + class ILFixedArrayMarshaler : public ILMngdMarshaler { public: @@ -3301,31 +3292,22 @@ class ILFixedArrayMarshaler : public ILMngdMarshaler void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override; }; -class MngdFixedArrayMarshaler +struct MngdFixedArrayMarshaler { -public: - static FCDECL5(void, CreateMarshaler, MngdFixedArrayMarshaler* pThis, MethodTable* pMT, UINT32 dwFlags, UINT32 cElements, PCODE pManagedElementMarshaler); - static FCDECL3(void, ConvertSpaceToNative, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome); - static FCDECL3(void, ConvertContentsToNative, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome); - static FCDECL3(void, ConvertSpaceToManaged, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome); - static FCDECL3(void, ConvertContentsToManaged, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome); - static FCDECL3(void, ClearNativeContents, MngdFixedArrayMarshaler* pThis, OBJECTREF* pManagedHome, void* pNativeHome); - - enum - { - FLAG_NATIVE_DATA_VALID = 0x40000000 - }; - MethodTable* m_pElementMT; PCODE m_pManagedElementMarshaler; TypeHandle m_Array; - BOOL m_NativeDataValid; BOOL m_BestFitMap; BOOL m_ThrowOnUnmappableChar; VARTYPE m_vt; UINT32 m_cElements; }; +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ConvertContentsToNative(MngdFixedArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void* pNativeHome); +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ConvertSpaceToManaged(MngdFixedArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void* pNativeHome); +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ConvertContentsToManaged(MngdFixedArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void* pNativeHome); +extern "C" void QCALLTYPE MngdFixedArrayMarshaler_ClearNativeContents(MngdFixedArrayMarshaler* pThis, void* pNativeHome); + #ifdef FEATURE_COMINTEROP class ILSafeArrayMarshaler : public ILMngdMarshaler { @@ -3390,12 +3372,6 @@ class ILSafeArrayMarshaler : public ILMngdMarshaler class MngdSafeArrayMarshaler { public: - static FCDECL5(void, CreateMarshaler, MngdSafeArrayMarshaler* pThis, MethodTable* pMT, UINT32 iRank, UINT32 dwFlags, PCODE pManagedMarshaler); - static FCDECL3(void, ConvertSpaceToNative, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL4(void, ConvertContentsToNative, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome, Object* pOriginalManagedUNSAFE); - static FCDECL3(void, ConvertSpaceToManaged, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL3(void, ConvertContentsToManaged, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL3(void, ClearNative, MngdSafeArrayMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); enum StaticCheckStateFlags { @@ -3411,6 +3387,13 @@ class MngdSafeArrayMarshaler BYTE m_fStatic; // StaticCheckStateFlags BYTE m_nolowerbounds; }; + +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_CreateMarshaler(MngdSafeArrayMarshaler* pThis, MethodTable* pMT, UINT32 iRank, UINT32 dwFlags, PCODE pManagedMarshaler); +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertSpaceToNative(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome); +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertContentsToNative(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome, QCall::ObjectHandleOnStack pOriginalManaged); +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertSpaceToManaged(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome); +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ConvertContentsToManaged(MngdSafeArrayMarshaler* pThis, QCall::ObjectHandleOnStack pManagedHome, void** pNativeHome); +extern "C" void QCALLTYPE MngdSafeArrayMarshaler_ClearNative(MngdSafeArrayMarshaler* pThis, void** pNativeHome); #endif // FEATURE_COMINTEROP class ILReferenceCustomMarshaler : public ILMngdMarshaler @@ -3438,15 +3421,3 @@ class ILReferenceCustomMarshaler : public ILMngdMarshaler protected: void EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) override; }; - -class MngdRefCustomMarshaler -{ -public: - static FCDECL2(void, CreateMarshaler, MngdRefCustomMarshaler* pThis, void* pCMHelper); - static FCDECL3(void, ConvertContentsToNative, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL3(void, ConvertContentsToManaged, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL3(void, ClearNative, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - static FCDECL3(void, ClearManaged, MngdRefCustomMarshaler* pThis, OBJECTREF* pManagedHome, void** pNativeHome); - - CustomMarshalerHelper* m_pCMHelper; -}; diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index b86add72c6d8e0..45cb5700db5293 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -209,7 +209,7 @@ DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Obj_RetIntPtr, I I i j, I)) DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_RetVoid, I I I, v)) DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_UShrt_IntPtr_RetVoid, I I I H I, v)) DEFINE_METASIG(SM(IntPtr_Int_IntPtr_RetIntPtr, I i I, I)) -DEFINE_METASIG(SM(IntPtr_IntPtr_Int_IntPtr_RetVoid, I I i I, v)) +DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Bool_IntPtr_RetVoid, I I i F I, v)) DEFINE_METASIG(SM(IntPtr_IntPtr_Obj_RetVoid, I I j, v)) DEFINE_METASIG(SM(Obj_ArrObject_RetVoid, j a(j), v)) DEFINE_METASIG(SM(Obj_IntPtr_Obj_RetVoid, j I j, v)) @@ -241,6 +241,7 @@ DEFINE_METASIG(SM(PtrVoid_Byte_UInt_RetVoid, P(v) b K, v)) DEFINE_METASIG(SM(RefObj_IntPtr_RetVoid, r(j) I, v)) DEFINE_METASIG(SM(RefObj_RefIntPtr_RetVoid, r(j) r(I), v)) DEFINE_METASIG(SM(IntPtr_RefObj_IntPtr_RetVoid, I r(j) I, v)) +DEFINE_METASIG(SM(IntPtr_RefObj_PtrIntPtr_RetVoid, I r(j) P(I), v)) DEFINE_METASIG(SM(IntPtr_RefObj_IntPtr_Int_RetVoid, I r(j) I i,v)) DEFINE_METASIG(SM(IntPtr_Int_IntPtr_Int_Int_Int_RetVoid, I i I i i i, v)) DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Int_IntPtr_RetVoid, I I i i I, v)) @@ -248,6 +249,8 @@ DEFINE_METASIG(SM(IntPtr_RefObj_IntPtr_Obj_RetVoid, I r(j) I j, v)) DEFINE_METASIG(SM(Obj_Int_RetVoid, j i,v)) DEFINE_METASIG(SM(PtrVoid_Obj_RetObj, P(v) j, j)) DEFINE_METASIG(SM(PtrVoid_Obj_RetRefByte, P(v) j, r(b))) +DEFINE_METASIG_T(SM(ICustomMarshaler_RefObj_PtrIntPtr_RetVoid, C(ICUSTOM_MARSHALER) r(j) P(I), v)) +DEFINE_METASIG_T(SM(IntPtr_RetICustomMarshaler, I, C(ICUSTOM_MARSHALER))) DEFINE_METASIG(SM(Flt_RetFlt, f, f)) DEFINE_METASIG(SM(Dbl_RetDbl, d, d)) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 3a7264543a6716..8f7b09c36d318e 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -214,6 +214,7 @@ static const Entry s_QCall[] = DllImportEntry(MultiCoreJIT_InternalStartProfile) #endif DllImportEntry(LoaderAllocator_Destroy) + DllImportEntry(CustomMarshaler_GetMarshalerObject) DllImportEntry(String_Intern) DllImportEntry(String_IsInterned) DllImportEntry(AppDomain_CreateDynamicAssembly) @@ -294,7 +295,22 @@ static const Entry s_QCall[] = DllImportEntry(MarshalNative_GetEndComSlot) DllImportEntry(MarshalNative_ChangeWrapperHandleStrength) #endif + DllImportEntry(MngdNativeArrayMarshaler_ConvertSpaceToNative) + DllImportEntry(MngdNativeArrayMarshaler_ConvertContentsToNative) + DllImportEntry(MngdNativeArrayMarshaler_ConvertSpaceToManaged) + DllImportEntry(MngdNativeArrayMarshaler_ConvertContentsToManaged) + DllImportEntry(MngdNativeArrayMarshaler_ClearNativeContents) + DllImportEntry(MngdFixedArrayMarshaler_ConvertContentsToNative) + DllImportEntry(MngdFixedArrayMarshaler_ConvertSpaceToManaged) + DllImportEntry(MngdFixedArrayMarshaler_ConvertContentsToManaged) + DllImportEntry(MngdFixedArrayMarshaler_ClearNativeContents) #ifdef FEATURE_COMINTEROP + DllImportEntry(MngdSafeArrayMarshaler_CreateMarshaler) + DllImportEntry(MngdSafeArrayMarshaler_ConvertSpaceToNative) + DllImportEntry(MngdSafeArrayMarshaler_ConvertContentsToNative) + DllImportEntry(MngdSafeArrayMarshaler_ConvertSpaceToManaged) + DllImportEntry(MngdSafeArrayMarshaler_ConvertContentsToManaged) + DllImportEntry(MngdSafeArrayMarshaler_ClearNative) DllImportEntry(OAVariant_ChangeType) #endif // FEATURE_COMINTEROP DllImportEntry(NativeLibrary_LoadFromPath) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index f32b66df95e796..bbea00bccacb11 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1642,6 +1642,9 @@ The length of the name exceeds the maximum limit. + + Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout. + MethodOverride's body must be from this type. diff --git a/src/tests/Interop/ArrayMarshalling/SafeArray/SafeArrayTest.cs b/src/tests/Interop/ArrayMarshalling/SafeArray/SafeArrayTest.cs index b3504dd9b397ea..860dfefd2d58d1 100644 --- a/src/tests/Interop/ArrayMarshalling/SafeArray/SafeArrayTest.cs +++ b/src/tests/Interop/ArrayMarshalling/SafeArray/SafeArrayTest.cs @@ -117,11 +117,14 @@ public struct StructWithSafeArray public struct BlittableRecord { public int a; + + public override string ToString() => $"BlittableRecord: {a}"; } public struct NonBlittableRecord { public bool b; + public override string ToString() => $"NonBlittableRecord: {b}"; } [DllImport(nameof(SafeArrayNative))]