diff --git a/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs b/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs index 81c480c4d951de..bf6952f333ec07 100644 --- a/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs +++ b/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs @@ -20,6 +20,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; +using System.StubHelpers; namespace Microsoft.Win32 { @@ -73,8 +74,7 @@ internal static unsafe partial class OAVariantLib if (source is int || source is uint) { uint sourceData = source is int ? (uint)(int)source : (uint)source; - // Int32/UInt32 can be converted to System.Drawing.Color - Variant.ConvertOleColorToSystemColor(ObjectHandleOnStack.Create(ref result), sourceData, targetClass.TypeHandle.Value); + result = ColorMarshaler.ConvertToManaged((int)sourceData); Debug.Assert(result != null); return result; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index e689e2d114e4e1..33d9c6ef28765b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -2,9 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#if FEATURE_COMINTEROP +using System.Runtime.InteropServices.CustomMarshalers; +#endif using System.Runtime.InteropServices.Marshalling; +using System.Runtime.Versioning; using System.Text; namespace System.StubHelpers @@ -792,16 +797,6 @@ internal static void ClearNative(IntPtr pMarshalState, in object pManagedHome, I internal static unsafe partial class MngdRefCustomMarshaler { - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomMarshaler_GetMarshalerObject")] - private static partial void GetMarshaler(IntPtr pCMHelper, ObjectHandleOnStack retMarshaler); - - internal static ICustomMarshaler GetMarshaler(IntPtr pCMHelper) - { - ICustomMarshaler? marshaler = null; - GetMarshaler(pCMHelper, ObjectHandleOnStack.Create(ref marshaler)); - return marshaler!; - } - internal static unsafe void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome) { // COMPAT: We never pass null to MarshalManagedToNative. @@ -1395,8 +1390,28 @@ internal static void SetPendingExceptionObject(Exception? exception) s_pendingExceptionObject = exception; } - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshalerHelper")] - internal static partial IntPtr CreateCustomMarshalerHelper(IntPtr pMD, int paramToken, IntPtr hndManagedType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshaler")] + internal static partial void CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType, ObjectHandleOnStack customMarshaler); + +#if FEATURE_COMINTEROP + [SupportedOSPlatform("windows")] + internal static object GetIEnumeratorToEnumVariantMarshaler() => EnumeratorToEnumVariantMarshaler.GetInstance(string.Empty); +#endif + + internal static object CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType) + { +#if FEATURE_COMINTEROP + if (OperatingSystem.IsWindows() + && hndManagedType == typeof(System.Collections.IEnumerator).TypeHandle.Value) + { + return GetIEnumeratorToEnumVariantMarshaler(); + } +#endif + + object? retVal = null; + CreateCustomMarshaler(pMD, paramToken, hndManagedType, ObjectHandleOnStack.Create(ref retVal)); + return retVal!; + } //------------------------------------------------------- // SafeHandle Helpers @@ -1575,4 +1590,37 @@ internal static void ValidateObject(object obj, IntPtr pMD) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IntPtr NextCallReturnAddress(); } // class StubHelpers + +#if FEATURE_COMINTEROP + internal static class ColorMarshaler + { + private static readonly MethodInvoker s_oleColorToDrawingColorMethod; + private static readonly MethodInvoker s_drawingColorToOleColorMethod; + + internal static readonly IntPtr s_colorType; + +#pragma warning disable CA1810 // explicit static cctor + static ColorMarshaler() + { + Type colorTranslatorType = Type.GetType("System.Drawing.ColorTranslator, System.Drawing.Primitives", throwOnError: true)!; + Type colorType = Type.GetType("System.Drawing.Color, System.Drawing.Primitives", throwOnError: true)!; + + s_colorType = colorType.TypeHandle.Value; + + s_oleColorToDrawingColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("FromOle", [typeof(int)])!); + s_drawingColorToOleColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("ToOle", [colorType])!); + } +#pragma warning restore CA1810 // explicit static cctor + + internal static object ConvertToManaged(int managedColor) + { + return s_oleColorToDrawingColorMethod.Invoke(null, managedColor)!; + } + + internal static int ConvertToNative(object? managedColor) + { + return (int)s_drawingColorToOleColorMethod.Invoke(null, managedColor)!; + } + } +#endif } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Variant.cs b/src/coreclr/System.Private.CoreLib/src/System/Variant.cs index 35052c0f9feb85..3e8d4f662046cd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Variant.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Variant.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; +using System.StubHelpers; #pragma warning disable CA1416 // COM interop is only supported on Windows @@ -17,12 +18,6 @@ internal static partial class Variant { internal static bool IsSystemDrawingColor(Type type) => type.FullName == "System.Drawing.Color"; // Matches the behavior of IsTypeRefOrDef - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertSystemColorToOleColor")] - internal static partial uint ConvertSystemColorToOleColor(ObjectHandleOnStack obj); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertOleColorToSystemColor")] - internal static partial void ConvertOleColorToSystemColor(ObjectHandleOnStack objret, uint value, IntPtr pMT); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertValueTypeToRecord")] private static partial void ConvertValueTypeToRecord(ObjectHandleOnStack obj, out ComVariant pOle); @@ -163,7 +158,7 @@ internal static void MarshalHelperConvertObjectToVariant(object? o, out ComVaria case { } when IsSystemDrawingColor(o.GetType()): // System.Drawing.Color is converted to UInt32 - pOle = ComVariant.Create(ConvertSystemColorToOleColor(ObjectHandleOnStack.Create(ref o))); + pOle = ComVariant.Create((uint)ColorMarshaler.ConvertToNative(o)); break; // DateTime, decimal handled by IConvertible case diff --git a/src/coreclr/classlibnative/bcltype/variant.cpp b/src/coreclr/classlibnative/bcltype/variant.cpp index 74baf2b62087c5..2b7202854f6c1d 100644 --- a/src/coreclr/classlibnative/bcltype/variant.cpp +++ b/src/coreclr/classlibnative/bcltype/variant.cpp @@ -18,40 +18,6 @@ #include "vars.hpp" #include "variant.h" -extern "C" uint32_t QCALLTYPE Variant_ConvertSystemColorToOleColor(QCall::ObjectHandleOnStack obj) -{ - QCALL_CONTRACT; - - uint32_t ret = 0; - - BEGIN_QCALL; - - GCX_COOP(); - OBJECTREF srcObj = obj.Get(); - - GCPROTECT_BEGIN(srcObj); - ret = ConvertSystemColorToOleColor(&srcObj); - GCPROTECT_END(); - - END_QCALL; - - return ret; -} - -extern "C" void QCALLTYPE Variant_ConvertOleColorToSystemColor(QCall::ObjectHandleOnStack objRet, uint32_t oleColor, MethodTable* pMT) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - GCX_COOP(); - SYSTEMCOLOR systemColor{}; - ConvertOleColorToSystemColor(oleColor, &systemColor); - objRet.Set(pMT->Box(&systemColor)); - - END_QCALL; -} - extern "C" void QCALLTYPE Variant_ConvertValueTypeToRecord(QCall::ObjectHandleOnStack obj, VARIANT * pOle) { QCALL_CONTRACT; diff --git a/src/coreclr/classlibnative/bcltype/variant.h b/src/coreclr/classlibnative/bcltype/variant.h index 597cf76d720881..fc4c7f5771a9dc 100644 --- a/src/coreclr/classlibnative/bcltype/variant.h +++ b/src/coreclr/classlibnative/bcltype/variant.h @@ -20,8 +20,6 @@ #include #include "olevariant.h" -extern "C" uint32_t QCALLTYPE Variant_ConvertSystemColorToOleColor(QCall::ObjectHandleOnStack obj); -extern "C" void QCALLTYPE Variant_ConvertOleColorToSystemColor(QCall::ObjectHandleOnStack objRet, uint32_t oleColor, MethodTable* pMT); extern "C" void QCALLTYPE Variant_ConvertValueTypeToRecord(QCall::ObjectHandleOnStack obj, VARIANT* pOle); #endif // _VARIANT_H_ diff --git a/src/coreclr/pal/inc/rt/palrt.h b/src/coreclr/pal/inc/rt/palrt.h index 18e25222c5db8e..13bbc7d250c321 100644 --- a/src/coreclr/pal/inc/rt/palrt.h +++ b/src/coreclr/pal/inc/rt/palrt.h @@ -716,8 +716,6 @@ typename std::remove_reference::type&& move( T&& t ); #define __RPC__inout #define __RPC__deref_out_ecount_full_opt(x) -typedef DWORD OLE_COLOR; - typedef HANDLE HWND; typedef struct _LIST_ENTRY { diff --git a/src/coreclr/vm/callhelpers.h b/src/coreclr/vm/callhelpers.h index b39586d82c341f..0e7f16dc0210cb 100644 --- a/src/coreclr/vm/callhelpers.h +++ b/src/coreclr/vm/callhelpers.h @@ -473,7 +473,6 @@ class MethodDescCallSite MDCALLDEF_VOID( CallWithValueTypes, TRUE) MDCALLDEF_ARGSLOT( CallWithValueTypes, _RetArgSlot) MDCALLDEF_REFTYPE( CallWithValueTypes, TRUE, _RetOBJECTREF, Object*, OBJECTREF) - MDCALLDEF( CallWithValueTypes, TRUE, _RetOleColor, OLE_COLOR, OTHER_ELEMENT_TYPE) #undef OTHER_ELEMENT_TYPE #undef MDCALL_ARG_SIG_STD_RETTYPES #undef MDCALLDEF diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 38a05866ff3e2c..e50b50cd14d470 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -384,11 +384,6 @@ DEFINE_CLASS(ICUSTOM_ATTR_PROVIDER, Reflection, ICustomAttributeProv DEFINE_METHOD(ICUSTOM_ATTR_PROVIDER,GET_CUSTOM_ATTRIBUTES, GetCustomAttributes, IM_Type_RetArrObj) DEFINE_CLASS(ICUSTOM_MARSHALER, Interop, ICustomMarshaler) -DEFINE_METHOD(ICUSTOM_MARSHALER, MARSHAL_NATIVE_TO_MANAGED,MarshalNativeToManaged, IM_IntPtr_RetObj) -DEFINE_METHOD(ICUSTOM_MARSHALER, MARSHAL_MANAGED_TO_NATIVE,MarshalManagedToNative, IM_Obj_RetIntPtr) -DEFINE_METHOD(ICUSTOM_MARSHALER, CLEANUP_NATIVE_DATA, CleanUpNativeData, IM_IntPtr_RetVoid) -DEFINE_METHOD(ICUSTOM_MARSHALER, CLEANUP_MANAGED_DATA, CleanUpManagedData, IM_Obj_RetVoid) -DEFINE_METHOD(ICUSTOM_MARSHALER, GET_NATIVE_DATA_SIZE, GetNativeDataSize, IM_RetInt) DEFINE_CLASS(ICUSTOMADAPTER, Interop, ICustomAdapter) @@ -929,7 +924,10 @@ DEFINE_METHOD(STUBHELPERS, KEEP_ALIVE_VIA_CLEANUP_LIST, KeepAliveVia DEFINE_METHOD(STUBHELPERS, DESTROY_CLEANUP_LIST, DestroyCleanupList, SM_RefCleanupWorkListElement_RetVoid) DEFINE_METHOD(STUBHELPERS, GET_HR_EXCEPTION_OBJECT, GetHRExceptionObject, SM_Int_RetException) DEFINE_METHOD(STUBHELPERS, GET_PENDING_EXCEPTION_OBJECT, GetPendingExceptionObject, SM_RetException) -DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER_HELPER, CreateCustomMarshalerHelper, SM_IntPtr_Int_IntPtr_RetIntPtr) +DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER, CreateCustomMarshaler, SM_IntPtr_Int_IntPtr_RetObj) +#ifdef FEATURE_COMINTEROP +DEFINE_METHOD(STUBHELPERS, GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER, GetIEnumeratorToEnumVariantMarshaler, SM_RetObj) +#endif // FEATURE_COMINTEROP DEFINE_METHOD(STUBHELPERS, CHECK_STRING_LENGTH, CheckStringLength, SM_Int_RetVoid) @@ -1001,6 +999,11 @@ DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertCon DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_SPACE_TO_MANAGED, ConvertSpaceToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RefObj_IntPtr_RetVoid) + +DEFINE_CLASS(COLORMARSHALER, StubHelpers, ColorMarshaler) +DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Obj_RetInt) +DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Int_RetObj) +DEFINE_FIELD(COLORMARSHALER, COLOR_TYPE, s_colorType) #endif // FEATURE_COMINTEROP END_ILLINK_FEATURE_SWITCH() @@ -1035,7 +1038,6 @@ DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertCon 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 4c7a93441fcf38..c505be13232019 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -17,20 +17,60 @@ #include "mlinfo.h" #include "sigbuilder.h" +namespace +{ + MethodDesc * FindGetInstanceMethod(TypeHandle hndCustomMarshalerType) + { + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + + MethodTable *pMT = hndCustomMarshalerType.AsMethodTable(); + + MethodDesc *pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); + if (!pMD) + { + DefineFullyQualifiedNameForClassW() + COMPlusThrow(kApplicationException, + IDS_EE_GETINSTANCENOTIMPL, + GetFullyQualifiedNameForClassW(pMT)); + }; + + // If the GetInstance method is generic, get an instantiating stub for it - + // the CallDescr infrastructure doesn't know how to pass secret generic arguments. + if (pMD->RequiresInstMethodTableArg()) + { + pMD = MethodDesc::FindOrCreateAssociatedMethodDesc( + pMD, + pMT, + FALSE, // forceBoxedEntryPoint + Instantiation(), // methodInst + FALSE, // allowInstParam + FALSE); // forceRemotableMethod + + _ASSERTE(!pMD->RequiresInstMethodTableArg()); + } + + // Ensure that the value types in the signature are loaded. + MetaSig::EnsureSigValueTypesLoaded(pMD); + + // Return the specified method desc. + return pMD; + } +} + //========================================================================== // Implementation of the custom marshaler info class. //========================================================================== CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) -: m_NativeSize(0) -, m_hndManagedType(hndManagedType) -, m_pLoaderAllocator(pLoaderAllocator) +: m_pLoaderAllocator(pLoaderAllocator) , m_hndCustomMarshaler{} -, m_pMarshalNativeToManagedMD(NULL) -, m_pMarshalManagedToNativeMD(NULL) -, m_pCleanUpNativeDataMD(NULL) -, m_pCleanUpManagedDataMD(NULL) -, m_bDataIsByValue(FALSE) { CONTRACTL { @@ -51,37 +91,19 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); } - // Determine if this type is a value class. - m_bDataIsByValue = m_hndManagedType.GetMethodTable()->IsValueType(); - - // Custom marshalling of value classes is not currently supported. - if (m_bDataIsByValue) + // Custom marshalling of value classes is not supported. + if (hndManagedType.GetMethodTable()->IsValueType()) COMPlusThrow(kNotSupportedException, W("NotSupported_ValueClassCM")); // Run the on the marshaler since it might not have run yet. hndCustomMarshalerType.GetMethodTable()->EnsureInstanceActive(); hndCustomMarshalerType.GetMethodTable()->CheckRunClassInitThrowing(); - // Create a COM+ string that will contain the string cookie. + // Create a .NET string that will contain the string cookie. STRINGREF CookieStringObj = StringObject::NewString(strCookie, cCookieStrBytes); GCPROTECT_BEGIN(CookieStringObj); // Load the method desc for the static method to retrieve the instance. - MethodDesc *pGetCustomMarshalerMD = GetCustomMarshalerMD(CustomMarshalerMethods_GetInstance, hndCustomMarshalerType); - - // If the GetInstance method is generic, get an instantiating stub for it - - // the CallDescr infrastructure doesn't know how to pass secret generic arguments. - if (pGetCustomMarshalerMD->RequiresInstMethodTableArg()) - { - pGetCustomMarshalerMD = MethodDesc::FindOrCreateAssociatedMethodDesc( - pGetCustomMarshalerMD, - hndCustomMarshalerType.GetMethodTable(), - FALSE, // forceBoxedEntryPoint - Instantiation(), // methodInst - FALSE, // allowInstParam - FALSE); // forceRemotableMethod - - _ASSERTE(!pGetCustomMarshalerMD->RequiresInstMethodTableArg()); - } + MethodDesc *pGetCustomMarshalerMD = FindGetInstanceMethod(hndCustomMarshalerType); MethodDescCallSite getCustomMarshaler(pGetCustomMarshalerMD, (OBJECTREF*)&CookieStringObj); @@ -103,28 +125,9 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type IDS_EE_NOCUSTOMMARSHALER, GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); } - // Load the method desc's for all the methods in the ICustomMarshaler interface based on the type of the marshaler object. - TypeHandle customMarshalerObjType = CustomMarshalerObj->GetMethodTable(); - - m_pMarshalNativeToManagedMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalNativeToManaged, customMarshalerObjType); - m_pMarshalManagedToNativeMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalManagedToNative, customMarshalerObjType); - m_pCleanUpNativeDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpNativeData, customMarshalerObjType); - m_pCleanUpManagedDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpManagedData, customMarshalerObjType); m_hndCustomMarshaler = pLoaderAllocator->AllocateHandle(CustomMarshalerObj); GCPROTECT_END(); - - // Retrieve the size of the native data. - if (m_bDataIsByValue) - { - // @TODO(DM): Call GetNativeDataSize() to retrieve the size of the native data. - _ASSERTE(!"Value classes are not yet supported by the custom marshaler!"); - } - else - { - m_NativeSize = sizeof(void *); - } - GCPROTECT_END(); } @@ -166,202 +169,39 @@ void CustomMarshalerInfo::operator delete(void *pMem) LIMITED_METHOD_CONTRACT; } -OBJECTREF CustomMarshalerInfo::InvokeMarshalNativeToManagedMeth(void *pNative) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pNative, NULL_OK)); - } - CONTRACTL_END; - - if (!pNative) - return NULL; - - OBJECTREF managedObject; - - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite marshalNativeToManaged(m_pMarshalNativeToManagedMD, &customMarshaler); - - ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - PtrToArgSlot(pNative) - }; - - managedObject = marshalNativeToManaged.Call_RetOBJECTREF(Args); - GCPROTECT_END (); - - return managedObject; -} - - -void *CustomMarshalerInfo::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) +#ifdef FEATURE_COMINTEROP +CustomMarshalerInfo* CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(LoaderHeap* pHeap, LoaderAllocator* pLoaderAllocator) { CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pHeap)); + PRECONDITION(CheckPointer(pLoaderAllocator)); } CONTRACTL_END; - void *RetVal = NULL; - - if (!MngObj) - return NULL; - - GCPROTECT_BEGIN (MngObj); - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite marshalManagedToNative(m_pMarshalManagedToNativeMD, &customMarshaler); - - ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - ObjToArgSlot(MngObj) - }; - - RetVal = marshalManagedToNative.Call_RetLPVOID(Args); - GCPROTECT_END (); - GCPROTECT_END (); - - return RetVal; -} - + CustomMarshalerInfo* pInfo = nullptr; + OBJECTREF IEnumeratorMarshalerObj = nullptr; -void CustomMarshalerInfo::InvokeCleanUpNativeMeth(void *pNative) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pNative, NULL_OK)); - } - CONTRACTL_END; - - if (!pNative) - return; + GCX_COOP(); + GCPROTECT_BEGIN(IEnumeratorMarshalerObj); - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite cleanUpNativeData(m_pCleanUpNativeDataMD, &customMarshaler); + MethodDescCallSite getMarshaler(METHOD__STUBHELPERS__GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER); + IEnumeratorMarshalerObj = getMarshaler.Call_RetOBJECTREF(NULL); - ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - PtrToArgSlot(pNative) - }; + pInfo = new (pHeap) CustomMarshalerInfo(pLoaderAllocator, pLoaderAllocator->AllocateHandle(IEnumeratorMarshalerObj)); - cleanUpNativeData.Call(Args); GCPROTECT_END(); -} - -void CustomMarshalerInfo::InvokeCleanUpManagedMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - if (!MngObj) - return; - - GCPROTECT_BEGIN (MngObj); - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite cleanUpManagedData(m_pCleanUpManagedDataMD, &customMarshaler); - - ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - ObjToArgSlot(MngObj) - }; - - cleanUpManagedData.Call(Args); - GCPROTECT_END (); - GCPROTECT_END (); + return pInfo; } - -MethodDesc *CustomMarshalerInfo::GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - - MethodTable *pMT = hndCustomMarshalertype.AsMethodTable(); - - _ASSERTE(pMT->CanCastToInterface(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); - - MethodDesc *pMD = NULL; - - switch (Method) - { - case CustomMarshalerMethods_MarshalNativeToManaged: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_MarshalManagedToNative: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_CleanUpNativeData: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA), - TRUE /* throwOnConflict */); - break; - - case CustomMarshalerMethods_CleanUpManagedData: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_GetNativeDataSize: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_GetInstance: - // Must look this up by name since it's static - pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); - if (!pMD) - { - DefineFullyQualifiedNameForClassW() - COMPlusThrow(kApplicationException, - IDS_EE_GETINSTANCENOTIMPL, - GetFullyQualifiedNameForClassW(pMT)); - } - break; - default: - _ASSERTE(!"Unknown custom marshaler method"); - } - - _ASSERTE(pMD && "Unable to find specified CustomMarshaler method"); - - // Ensure that the value types in the signature are loaded. - MetaSig::EnsureSigValueTypesLoaded(pMD); - - // Return the specified method desc. - return pMD; -} - +#endif //========================================================================== // Implementation of the custom marshaler hashtable helper. //========================================================================== -EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey *pKey, BOOL bDeepCopy, void* pHeap) +EEHashEntry_t * EECMInfoHashtableHelper::AllocateEntry(EECMInfoHashtableKey *pKey, BOOL bDeepCopy, void* pHeap) { CONTRACTL { @@ -376,11 +216,11 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey if (bDeepCopy) { - S_SIZE_T cbEntry = S_SIZE_T(sizeof(EEHashEntry) - 1 + sizeof(EECMHelperHashtableKey)); + S_SIZE_T cbEntry = S_SIZE_T(sizeof(EEHashEntry) - 1 + sizeof(EECMInfoHashtableKey)); cbEntry += S_SIZE_T(pKey->GetMarshalerTypeNameByteCount()); cbEntry += S_SIZE_T(pKey->GetCookieStringByteCount()); cbEntry += S_SIZE_T(pKey->GetMarshalerInstantiation().GetNumArgs()) * S_SIZE_T(sizeof(LPVOID)); - cbEntry += S_SIZE_T(sizeof(LPVOID)); // For EECMHelperHashtableKey::m_invokingAssembly + cbEntry += S_SIZE_T(sizeof(LPVOID)); // For EECMInfoHashtableKey::m_invokingAssembly if (cbEntry.IsOverflow()) return NULL; @@ -389,11 +229,11 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey if (!pEntry) return NULL; - EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; + EECMInfoHashtableKey *pEntryKey = (EECMInfoHashtableKey *) pEntry->Key; pEntryKey->m_cMarshalerTypeNameBytes = pKey->GetMarshalerTypeNameByteCount(); - pEntryKey->m_strMarshalerTypeName = (LPSTR) pEntry->Key + sizeof(EECMHelperHashtableKey); + pEntryKey->m_strMarshalerTypeName = (LPSTR) pEntry->Key + sizeof(EECMInfoHashtableKey); pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); - pEntryKey->m_strCookie = (LPSTR) pEntry->Key + sizeof(EECMHelperHashtableKey) + pEntryKey->m_cMarshalerTypeNameBytes; + pEntryKey->m_strCookie = (LPSTR) pEntry->Key + sizeof(EECMInfoHashtableKey) + pEntryKey->m_cMarshalerTypeNameBytes; pEntryKey->m_Instantiation = Instantiation( (TypeHandle *) (pEntryKey->m_strCookie + pEntryKey->m_cCookieStrBytes), pKey->GetMarshalerInstantiation().GetNumArgs()); @@ -406,11 +246,11 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey else { pEntry = (EEHashEntry_t *) - new (nothrow) BYTE[sizeof(EEHashEntry) - 1 + sizeof(EECMHelperHashtableKey)]; + new (nothrow) BYTE[sizeof(EEHashEntry) - 1 + sizeof(EECMInfoHashtableKey)]; if (!pEntry) return NULL; - EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; + EECMInfoHashtableKey *pEntryKey = (EECMInfoHashtableKey *) pEntry->Key; pEntryKey->m_cMarshalerTypeNameBytes = pKey->GetMarshalerTypeNameByteCount(); pEntryKey->m_strMarshalerTypeName = pKey->GetMarshalerTypeName(); pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); @@ -423,7 +263,7 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey } -void EECMHelperHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) +void EECMInfoHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) { CONTRACTL { @@ -434,11 +274,15 @@ void EECMHelperHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) } CONTRACTL_END; + CustomMarshalerInfo* pInfo = reinterpret_cast(pEntry->Data); + + delete pInfo; + delete[] (BYTE*)pEntry; } -BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHashtableKey *pKey) +BOOL EECMInfoHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMInfoHashtableKey *pKey) { CONTRACTL { @@ -450,7 +294,7 @@ BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHas } CONTRACTL_END; - EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; + EECMInfoHashtableKey *pEntryKey = (EECMInfoHashtableKey *) pEntry->Key; if (pEntryKey->GetMarshalerTypeNameByteCount() != pKey->GetMarshalerTypeNameByteCount()) return FALSE; @@ -481,7 +325,7 @@ BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHas } -DWORD EECMHelperHashtableHelper::Hash(EECMHelperHashtableKey *pKey) +DWORD EECMInfoHashtableHelper::Hash(EECMInfoHashtableKey *pKey) { WRAPPER_NO_CONTRACT; @@ -490,169 +334,3 @@ DWORD EECMHelperHashtableHelper::Hash(EECMHelperHashtableKey *pKey) HashBytes((const BYTE *) pKey->GetCookieString(), pKey->GetCookieStringByteCount()) + HashBytes((const BYTE *) pKey->GetMarshalerInstantiation().GetRawArgs(), pKey->GetMarshalerInstantiation().GetNumArgs() * sizeof(LPVOID))); } - - -OBJECTREF CustomMarshalerHelper::InvokeMarshalNativeToManagedMeth(void *pNative) -{ - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->InvokeMarshalNativeToManagedMeth(pNative); -} - - -void *CustomMarshalerHelper::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - void *RetVal = NULL; - - GCPROTECT_BEGIN(MngObj) - { - CustomMarshalerInfo *pCMInfo = GetCustomMarshalerInfo(); - RetVal = pCMInfo->InvokeMarshalManagedToNativeMeth(MngObj); - } - GCPROTECT_END(); - - return RetVal; -} - - -void CustomMarshalerHelper::InvokeCleanUpNativeMeth(void *pNative) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - OBJECTREF ExceptionObj = NULL; - GCPROTECT_BEGIN(ExceptionObj) - { - EX_TRY - { - GetCustomMarshalerInfo()->InvokeCleanUpNativeMeth(pNative); - } - EX_CATCH - { - ExceptionObj = GET_THROWABLE(); - } - EX_END_CATCH(SwallowAllExceptions); - } - GCPROTECT_END(); -} - - -void CustomMarshalerHelper::InvokeCleanUpManagedMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - GCPROTECT_BEGIN(MngObj) - { - CustomMarshalerInfo *pCMInfo = GetCustomMarshalerInfo(); - pCMInfo->InvokeCleanUpManagedMeth(MngObj); - } - GCPROTECT_END(); -} - - -void *NonSharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pHeap)); - } - CONTRACTL_END; - - return pHeap->AllocMem(S_SIZE_T(sizeof(NonSharedCustomMarshalerHelper))); -} - - -void NonSharedCustomMarshalerHelper::operator delete(void *pMem) -{ - // Instances of this class are always allocated on the loader heap so - // the delete operator has nothing to do. - LIMITED_METHOD_CONTRACT; -} - - -SharedCustomMarshalerHelper::SharedCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) -: m_pAssembly(pAssembly) -, m_hndManagedType(hndManagedType) -, m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) -, m_strMarshalerTypeName(strMarshalerTypeName) -, m_cCookieStrBytes(cCookieStrBytes) -, m_strCookie(strCookie) -{ - WRAPPER_NO_CONTRACT; -} - - -void *SharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pHeap)); - } - CONTRACTL_END; - - return pHeap->AllocMem(S_SIZE_T(sizeof(SharedCustomMarshalerHelper))); -} - - -void SharedCustomMarshalerHelper::operator delete(void *pMem) -{ - // Instances of this class are always allocated on the loader heap so - // the delete operator has nothing to do. - LIMITED_METHOD_CONTRACT; -} - - -CustomMarshalerInfo *SharedCustomMarshalerHelper::GetCustomMarshalerInfo() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // Retrieve the marshalling data for the current app domain. - EEMarshalingData *pMarshalingData = AppDomain::GetCurrentDomain()->GetLoaderAllocator()->GetMarshalingData(); - - // Retrieve the custom marshaling information for the current shared custom - // marshaling helper. - 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 802918dcd675f9..98dd71858a0a9b 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -17,21 +17,7 @@ #include "vars.hpp" #include "slist.h" - -// This enumeration is used to retrieve a method desc from CustomMarshalerInfo::GetCustomMarshalerMD(). -enum EnumCustomMarshalerMethods -{ - CustomMarshalerMethods_MarshalNativeToManaged = 0, - CustomMarshalerMethods_MarshalManagedToNative, - CustomMarshalerMethods_CleanUpNativeData, - CustomMarshalerMethods_CleanUpManagedData, - CustomMarshalerMethods_GetNativeDataSize, - CustomMarshalerMethods_GetInstance, - CustomMarshalerMethods_LastMember -}; - - -class CustomMarshalerInfo +class CustomMarshalerInfo final { public: // Constructor and destructor. @@ -43,82 +29,35 @@ class CustomMarshalerInfo void* operator new(size_t size, LoaderHeap* pHeap); void operator delete(void* pMem); - // Helpers used to invoke the different methods in the ICustomMarshaler interface. - OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); - void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); - void InvokeCleanUpNativeMeth(void* pNative); - void InvokeCleanUpManagedMeth(OBJECTREF MngObj); - // Accessors. - int GetNativeSize() - { - LIMITED_METHOD_CONTRACT; - return m_NativeSize; - } - - int GetManagedSize() - { - WRAPPER_NO_CONTRACT; - return m_hndManagedType.GetSize(); - } - - TypeHandle GetManagedType() - { - LIMITED_METHOD_CONTRACT; - return m_hndManagedType; - } - - BOOL IsDataByValue() - { - LIMITED_METHOD_CONTRACT; - return m_bDataIsByValue; - } - OBJECTREF GetCustomMarshaler() { LIMITED_METHOD_CONTRACT; return m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); } - TypeHandle GetCustomMarshalerType() - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - } - CONTRACTL_END; - return m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler)->GetTypeHandle(); - } - - // Helper function to retrieve a custom marshaler method desc. - static MethodDesc* GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype); - - // Link used to contain this CM info in a linked list. - SLink m_Link; +#ifdef FEATURE_COMINTEROP + static CustomMarshalerInfo* CreateIEnumeratorMarshalerInfo(LoaderHeap* pHeap, LoaderAllocator* pLoaderAllocator); +#endif // FEATURE_COMINTEROP private: - int m_NativeSize; - TypeHandle m_hndManagedType; LoaderAllocator* m_pLoaderAllocator; LOADERHANDLE m_hndCustomMarshaler; - MethodDesc* m_pMarshalNativeToManagedMD; - MethodDesc* m_pMarshalManagedToNativeMD; - MethodDesc* m_pCleanUpNativeDataMD; - MethodDesc* m_pCleanUpManagedDataMD; - BOOL m_bDataIsByValue; -}; - -typedef SList CMINFOLIST; + CustomMarshalerInfo(LoaderAllocator* pLoaderAllocator, LOADERHANDLE hndCustomMarshaler) + : m_pLoaderAllocator(pLoaderAllocator) + , m_hndCustomMarshaler(hndCustomMarshaler) + { + LIMITED_METHOD_CONTRACT; + } +}; class Assembly; -class EECMHelperHashtableKey +class EECMInfoHashtableKey { public: - EECMHelperHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation, Assembly* invokingAssembly) + EECMInfoHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation, Assembly* invokingAssembly) : m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) , m_strMarshalerTypeName(strMarshalerTypeName) , m_cCookieStrBytes(cCookieStrBytes) @@ -169,152 +108,16 @@ class EECMHelperHashtableKey }; -class EECMHelperHashtableHelper +class EECMInfoHashtableHelper { public: - static EEHashEntry_t* AllocateEntry(EECMHelperHashtableKey* pKey, BOOL bDeepCopy, AllocationHeap Heap); + static EEHashEntry_t* AllocateEntry(EECMInfoHashtableKey* pKey, BOOL bDeepCopy, AllocationHeap Heap); static void DeleteEntry(EEHashEntry_t* pEntry, AllocationHeap Heap); - static BOOL CompareKeys(EEHashEntry_t* pEntry, EECMHelperHashtableKey* pKey); - static DWORD Hash(EECMHelperHashtableKey* pKey); -}; - - -typedef EEHashTable EECMHelperHashTable; - - -class CustomMarshalerHelper -{ -public: - // Helpers used to invoke the different methods in the ICustomMarshaler interface. - OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); - void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); - void InvokeCleanUpNativeMeth(void* pNative); - void InvokeCleanUpManagedMeth(OBJECTREF MngObj); - - // Accessors. - int GetNativeSize() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->GetNativeSize(); - } - - int GetManagedSize() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->GetManagedSize(); - } - - TypeHandle GetManagedType() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->GetManagedType(); - } - - BOOL IsDataByValue() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->IsDataByValue(); - } - - // Helper function to retrieve the custom marshaler object. - virtual CustomMarshalerInfo* GetCustomMarshalerInfo() = 0; - -protected: - ~CustomMarshalerHelper( void ) - { - LIMITED_METHOD_CONTRACT; - } + static BOOL CompareKeys(EEHashEntry_t* pEntry, EECMInfoHashtableKey* pKey); + static DWORD Hash(EECMInfoHashtableKey* pKey); }; -class NonSharedCustomMarshalerHelper : public CustomMarshalerHelper -{ -public: - // Constructor. - NonSharedCustomMarshalerHelper(CustomMarshalerInfo* pCMInfo) : m_pCMInfo(pCMInfo) - { - WRAPPER_NO_CONTRACT; - } - - // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void *operator new(size_t size, LoaderHeap *pHeap); - void operator delete(void* pMem); - -protected: - // Helper function to retrieve the custom marshaler object. - virtual CustomMarshalerInfo* GetCustomMarshalerInfo() - { - LIMITED_METHOD_CONTRACT; - return m_pCMInfo; - } - -private: - CustomMarshalerInfo* m_pCMInfo; -}; - - -class SharedCustomMarshalerHelper : public CustomMarshalerHelper -{ -public: - // Constructor. - SharedCustomMarshalerHelper(Assembly* pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); - - // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void* operator new(size_t size, LoaderHeap* pHeap); - void operator delete(void* pMem); - - // Accessors. - inline Assembly* GetAssembly() - { - LIMITED_METHOD_CONTRACT; - return m_pAssembly; - } - - inline TypeHandle GetManagedType() - { - LIMITED_METHOD_CONTRACT; - return m_hndManagedType; - } - - inline DWORD GetMarshalerTypeNameByteCount() - { - LIMITED_METHOD_CONTRACT; - return m_cMarshalerTypeNameBytes; - } - - inline LPCSTR GetMarshalerTypeName() - { - LIMITED_METHOD_CONTRACT; - return m_strMarshalerTypeName; - } - - inline LPCSTR GetCookieString() - { - LIMITED_METHOD_CONTRACT; - return m_strCookie; - } - - inline ULONG GetCookieStringByteCount() - { - LIMITED_METHOD_CONTRACT; - return m_cCookieStrBytes; - } - -protected: - // Helper function to retrieve the custom marshaler object. - virtual CustomMarshalerInfo* GetCustomMarshalerInfo(); - -private: - Assembly* m_pAssembly; - TypeHandle m_hndManagedType; - DWORD m_cMarshalerTypeNameBytes; - LPCUTF8 m_strMarshalerTypeName; - DWORD m_cCookieStrBytes; - LPCUTF8 m_strCookie; -}; - -extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject); +typedef EEHashTable EECMInfoHashTable; #endif // _CUSTOMMARSHALERINFO_H_ diff --git a/src/coreclr/vm/dispparammarshaler.cpp b/src/coreclr/vm/dispparammarshaler.cpp index ee05c624a1cc18..5ec105ce4de85b 100644 --- a/src/coreclr/vm/dispparammarshaler.cpp +++ b/src/coreclr/vm/dispparammarshaler.cpp @@ -96,14 +96,7 @@ void DispParamOleColorMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECT OLE_COLOR OleColor = bByref ? *V_UI4REF(pSrcVar) : V_UI4(pSrcVar); // Convert the OLECOLOR to a System.Drawing.Color. - SYSTEMCOLOR MngColor; - ConvertOleColorToSystemColor(OleColor, &MngColor); - - // Box the System.Drawing.Color value class and give back the boxed object. - TypeHandle hndColorType = - AppDomain::GetCurrentDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); - - *pDestObj = hndColorType.GetMethodTable()->Box(&MngColor); + ConvertOleColorToSystemColor(OleColor, pDestObj); } void DispParamOleColorMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIANT *pDestVar) @@ -556,7 +549,18 @@ void DispParamCustomMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECTRE IUnknown *pUnk = bByref ? *V_UNKNOWNREF(pSrcVar) : V_UNKNOWN(pSrcVar); // Marshal the contents of the VARIANT using the custom marshaler. - *pDestObj = m_pCMHelper->InvokeMarshalNativeToManagedMeth(pUnk); + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_MANAGED); + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pDestObj), + PtrToArgSlot(&pUnk) + }; + + marshalNativeToManaged.Call(Args); + GCPROTECT_END (); } void DispParamCustomMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIANT *pDestVar) @@ -577,7 +581,21 @@ void DispParamCustomMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIAN SafeVariantClear(pDestVar); // Invoke the MarshalManagedToNative method. - pUnk = (IUnknown*)m_pCMHelper->InvokeMarshalManagedToNativeMeth(*pSrcObj); + IUnknown* pUnkRaw = nullptr; + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite marshalManagedToNative(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_NATIVE); + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pSrcObj), + PtrToArgSlot(&pUnkRaw) + }; + + marshalManagedToNative.Call(Args); + GCPROTECT_END(); + pUnk = pUnkRaw; + if (!pUnk) { // Put a null IDispatch pointer in the VARIANT. @@ -631,7 +649,18 @@ void DispParamCustomMarshaler::MarshalManagedToNativeRef(OBJECTREF *pSrcObj, VAR SafeVariantClear(&vtmp); // Convert the object using the custom marshaler. - V_UNKNOWN(&vtmp) = (IUnknown*)m_pCMHelper->InvokeMarshalManagedToNativeMeth(*pSrcObj); + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite marshalManagedToNative(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_NATIVE); + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pSrcObj), + PtrToArgSlot(V_UNKNOWN(&vtmp)) + }; + + marshalManagedToNative.Call(Args); + GCPROTECT_END(); V_VT(&vtmp) = m_vt; // Call VariantChangeType if required. @@ -661,5 +690,19 @@ void DispParamCustomMarshaler::CleanUpManaged(OBJECTREF *pObj) MODE_COOPERATIVE; } CONTRACTL_END; - m_pCMHelper->InvokeCleanUpManagedMeth(*pObj); + + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite clearManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CLEAR_MANAGED); + + void* dummyNative = nullptr; + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pObj), + PtrToArgSlot(&dummyNative) + }; + + clearManaged.Call(Args); + GCPROTECT_END (); } diff --git a/src/coreclr/vm/dispparammarshaler.h b/src/coreclr/vm/dispparammarshaler.h index 5bf22445dbedc9..51d4a359da420e 100644 --- a/src/coreclr/vm/dispparammarshaler.h +++ b/src/coreclr/vm/dispparammarshaler.h @@ -196,8 +196,8 @@ class DispParamDelegateMarshaler : public DispParamMarshaler class DispParamCustomMarshaler : public DispParamMarshaler { public: - DispParamCustomMarshaler(CustomMarshalerHelper *pCMHelper, VARTYPE vt) : - m_pCMHelper(pCMHelper), + DispParamCustomMarshaler(CustomMarshalerInfo *pCMHelper, VARTYPE vt) : + m_pCMInfo(pCMHelper), m_vt(vt) { WRAPPER_NO_CONTRACT; @@ -215,8 +215,8 @@ class DispParamCustomMarshaler : public DispParamMarshaler virtual void CleanUpManaged(OBJECTREF *pObj); private: - CustomMarshalerHelper* m_pCMHelper; - VARTYPE m_vt; + CustomMarshalerInfo* m_pCMInfo; + VARTYPE m_vt; }; #endif // _DISPPARAMMARSHALER_H diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index d528fa10e16425..aa9b3d6531553a 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -1477,25 +1477,19 @@ LocalDesc ILOleColorMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); - TypeHandle hndColorType = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); - // // value class // - return LocalDesc(hndColorType); // System.Drawing.Color + return LocalDesc(m_pargs->color.m_pColorType); } void ILOleColorMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; - LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); - MethodDesc* pConvertMD = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); - EmitLoadManagedValue(pslILEmit); - // int System.Drawing.ColorTranslator.ToOle(System.Drawing.Color c) - pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); + pslILEmit->EmitBOX(pslILEmit->GetToken(m_pargs->color.m_pColorType)); + pslILEmit->EmitCALL(METHOD__COLORMARSHALER__CONVERT_TO_NATIVE, 1, 1); EmitStoreNativeValue(pslILEmit); } @@ -1503,12 +1497,9 @@ void ILOleColorMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit { STANDARD_VM_CONTRACT; - LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); - MethodDesc* pConvertMD = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); - EmitLoadNativeValue(pslILEmit); - // System.Drawing.Color System.Drawing.ColorTranslator.FromOle(int oleColor) - pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); + pslILEmit->EmitCALL(METHOD__COLORMARSHALER__CONVERT_TO_MANAGED, 1, 1); + pslILEmit->EmitUNBOX_ANY(pslILEmit->GetToken(m_pargs->color.m_pColorType)); EmitStoreManagedValue(pslILEmit); } @@ -4935,7 +4926,7 @@ void ILReferenceCustomMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); // - // call CreateCustomMarshalerHelper + // call CreateCustomMarshaler // pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(m_pargs->rcm.m_pMD)); @@ -4946,10 +4937,7 @@ 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); // Create the CustomMarshalerHelper - - // Get the managed ICustomMarshaler object from the helper - pslILEmit->EmitCALL(METHOD__MNGD_REF_CUSTOM_MARSHALER__GET_MARSHALER, 1, 1); + pslILEmit->EmitCALL(METHOD__STUBHELPERS__CREATE_CUSTOM_MARSHALER, 3, 1); // Create the ICustomMarshaler pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum); // Store the ICustomMarshaler as our marshaler state } diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index ca84692561b038..7f5dad6bb2276d 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -2533,7 +2533,7 @@ class ILOleColorMarshaler : public ILMarshaler enum { c_fInOnly = TRUE, - c_nativeSize = sizeof(OLE_COLOR), + c_nativeSize = sizeof(uint32_t), }; protected: diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 957d13fe5024be..15f9e5b1ececb2 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -2188,8 +2188,8 @@ void GetComSourceInterfacesForClass(MethodTable *pMT, CQuickArray } //-------------------------------------------------------------------------------- -// This method converts an OLE_COLOR to a System.Color. -void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysColor) +// This method converts an OLE_COLOR to a boxed Color object. +void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, OBJECTREF *pDestSysColor) { CONTRACTL { @@ -2199,21 +2199,14 @@ void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysCo } CONTRACTL_END; - // Retrieve the method desc to use for the current AD. - MethodDesc *pOleColorToSystemColorMD = - GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); - - MethodDescCallSite oleColorToSystemColor(pOleColorToSystemColorMD); - - _ASSERTE(pOleColorToSystemColorMD->HasRetBuffArg()); + MethodDescCallSite oleColorToSystemColor(METHOD__COLORMARSHALER__CONVERT_TO_MANAGED); ARG_SLOT Args[] = { - PtrToArgSlot(pDestSysColor), - PtrToArgSlot(SrcOleColor) + PtrToArgSlot(&SrcOleColor) }; - oleColorToSystemColor.Call(Args); + *pDestSysColor = oleColorToSystemColor.Call_RetOBJECTREF(Args); } //-------------------------------------------------------------------------------- @@ -2228,14 +2221,24 @@ OLE_COLOR ConvertSystemColorToOleColor(OBJECTREF *pSrcObj) } CONTRACTL_END; - // Retrieve the method desc to use for the current AD. - MethodDesc *pSystemColorToOleColorMD = - GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); - MethodDescCallSite systemColorToOleColor(pSystemColorToOleColorMD); + OLE_COLOR result; + OBJECTREF sysColor = NULL; + + GCPROTECT_BEGIN(sysColor); - // Set up the args and call the method. - SYSTEMCOLOR *pSrcSysColor = (SYSTEMCOLOR *)(*pSrcObj)->UnBox(); - return systemColorToOleColor.CallWithValueTypes_RetOleColor((const ARG_SLOT *)&pSrcSysColor); + sysColor = *pSrcObj; + + MethodDescCallSite sysColorToOleColor(METHOD__COLORMARSHALER__CONVERT_TO_NATIVE); + + ARG_SLOT Args[] = + { + ObjToArgSlot(sysColor) + }; + + result = (OLE_COLOR)sysColorToOleColor.Call_RetI4(Args); + + GCPROTECT_END(); + return result; } //-------------------------------------------------------------------------------- diff --git a/src/coreclr/vm/interoputil.h b/src/coreclr/vm/interoputil.h index b3666f385a55b2..37322a4649ac8b 100644 --- a/src/coreclr/vm/interoputil.h +++ b/src/coreclr/vm/interoputil.h @@ -33,21 +33,6 @@ enum DefaultInterfaceType DefaultInterfaceType_BaseComClass = 4 }; -// System.Drawing.Color struct definition. - -struct SYSTEMCOLOR -{ -#ifdef HOST_64BIT - STRINGREF name; - INT64 value; -#else - INT64 value; - STRINGREF name; -#endif - short knownColor; - short state; -}; - struct ComMethodTable; struct IUnkEntry; interface IStream; @@ -274,9 +259,8 @@ MethodTable *GetDefaultInterfaceMTForClass(MethodTable *pMT, BOOL *pbDispatch); void GetComSourceInterfacesForClass(MethodTable *pClassMT, CQuickArray &rItfList); //-------------------------------------------------------------------------------- -// These methods convert an OLE_COLOR to a System.Color and vice versa. -void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysColor); -OLE_COLOR ConvertSystemColorToOleColor(SYSTEMCOLOR *pSrcSysColor); +// These methods convert an OLE_COLOR to a boxed Color object and vice versa. +void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, OBJECTREF *pDestSysColor); OLE_COLOR ConvertSystemColorToOleColor(OBJECTREF *pSrcObj); //-------------------------------------------------------------------------------- @@ -386,9 +370,6 @@ VOID EnsureComStarted(BOOL fCoInitCurrentThread = TRUE); IUnknown* MarshalObjectToInterface(OBJECTREF* ppObject, MethodTable* pItfMT, MethodTable* pClassMT, DWORD dwFlags); void UnmarshalObjectFromInterface(OBJECTREF *ppObjectDest, IUnknown **ppUnkSrc, MethodTable *pItfMT, MethodTable *pClassMT, DWORD dwFlags); - -#define DEFINE_ASM_QUAL_TYPE_NAME(varname, typename, asmname) static const char varname##[] = { typename##", "##asmname## }; - #else // FEATURE_COMINTEROP inline HRESULT EnsureComStartedNoThrow() { diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index eaa50c2f8421c0..7f1feca8f4ef18 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -198,6 +198,7 @@ DEFINE_METASIG_T(SM(Obj_RefGuid_RefIntPtr_RetInt, j r(g(GUID)) r(I), i)) DEFINE_METASIG_T(SM(Exception_Obj_RefIntPtr_RetVoidPtr, C(EXCEPTION) j r(I), P(v))) #endif // FEATURE_OBJCMARSHAL DEFINE_METASIG(SM(Int_RetVoid, i, v)) +DEFINE_METASIG(SM(Int_RetObj, i, j)) DEFINE_METASIG(SM(Int_Int_RetVoid, i i, v)) DEFINE_METASIG(SM(Str_RetIntPtr, s, I)) DEFINE_METASIG(SM(Str_RetBool, s, F)) @@ -205,7 +206,7 @@ DEFINE_METASIG(SM(IntPtr_IntPtr_RetVoid, I I, v)) 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_Int_IntPtr_RetObj, I i I, j)) 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_T(SM(Obj_Array_RetVoid, j C(ARRAY), v)) @@ -250,7 +251,6 @@ 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(RefDbl_Dbl_RetDbl, r(d) d, d)) DEFINE_METASIG(SM(RefDbl_Dbl_Dbl_RetDbl, r(d) d d, d)) @@ -447,12 +447,10 @@ DEFINE_METASIG_T(IM(Obj_EventArgs_RetVoid, j C(EVENT_ARGS), v)) DEFINE_METASIG_T(IM(Exception_RetVoid, C(EXCEPTION), v)) -DEFINE_METASIG(IM(IntPtr_RetObj, I, j)) DEFINE_METASIG(IM(IntPtr_RetVoid, I, v)) DEFINE_METASIG_T(IM(RefGuid_RetIntPtr, r(g(GUID)), I)) DEFINE_METASIG(IM(Obj_RetInt, j, i)) -DEFINE_METASIG(IM(Obj_RetIntPtr, j, I)) DEFINE_METASIG(IM(Obj_RetVoid, j, v)) DEFINE_METASIG(IM(Obj_RetObj, j, j)) DEFINE_METASIG(IM(Obj_IntPtr_RetVoid, j I, v)) diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 40ccb2eeaff134..6785ad0999a4fd 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -25,51 +25,56 @@ #include "dispparammarshaler.h" #endif // FEATURE_COMINTEROP -#ifdef FEATURE_COMINTEROP - DEFINE_ASM_QUAL_TYPE_NAME(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, g_EnumeratorToEnumClassName, g_CorelibAsmName); - - static const int ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN = ARRAY_SIZE(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME); - static const char ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE[] = {""}; - static const int ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN = ARRAY_SIZE(ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE); - - DEFINE_ASM_QUAL_TYPE_NAME(COLOR_TRANSLATOR_ASM_QUAL_TYPE_NAME, g_ColorTranslatorClassName, g_DrawingAsmName); - DEFINE_ASM_QUAL_TYPE_NAME(COLOR_ASM_QUAL_TYPE_NAME, g_ColorClassName, g_DrawingAsmName); - - #define OLECOLOR_TO_SYSTEMCOLOR_METH_NAME "FromOle" - #define SYSTEMCOLOR_TO_OLECOLOR_METH_NAME "ToOle" -#endif // FEATURE_COMINTEROP - - - #define INITIAL_NUM_STRUCT_ILSTUB_HASHTABLE_BUCKETS 32 #define INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS 32 #define INITIAL_NUM_CMINFO_HASHTABLE_BUCKETS 32 #define DEBUG_CONTEXT_STR_LEN 2000 -//========================================================================== -// Set's up the custom marshaler information. -//========================================================================== -CustomMarshalerHelper *SetupCustomMarshalerHelper(LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes, Assembly *pAssembly, TypeHandle hndManagedType) +namespace { - CONTRACT (CustomMarshalerHelper*) + //========================================================================== + // Sets up the custom marshaler information. + //========================================================================== + CustomMarshalerInfo *SetupCustomMarshalerInfo(LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes, Assembly *pAssembly, TypeHandle hndManagedType) { - STANDARD_VM_CHECK; - PRECONDITION(CheckPointer(pAssembly)); - POSTCONDITION(CheckPointer(RETVAL)); + CONTRACT (CustomMarshalerInfo*) + { + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pAssembly)); + POSTCONDITION(CheckPointer(RETVAL)); + } + CONTRACT_END; + + EEMarshalingData *pMarshalingData = NULL; + + // The assembly is not shared so we use the current app domain's marshaling data. + pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); + + // Retrieve the custom marshaler helper from the EE marshaling data. + RETURN pMarshalingData->GetCustomMarshalerInfo(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); } - CONTRACT_END; - EEMarshalingData *pMarshalingData = NULL; +#ifdef FEATURE_COMINTEROP + CustomMarshalerInfo *GetIEnumeratorCustomMarshalerInfo(Assembly *pAssembly) + { + CONTRACT (CustomMarshalerInfo*) + { + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pAssembly)); + POSTCONDITION(CheckPointer(RETVAL)); + } + CONTRACT_END; - // The assembly is not shared so we use the current app domain's marshaling data. - pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); + EEMarshalingData *pMarshalingData = NULL; - // Retrieve the custom marshaler helper from the EE marshaling data. - RETURN pMarshalingData->GetCustomMarshalerHelper(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); -} + // The assembly is not shared so we use the current app domain's marshaling data. + pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); + + // Retrieve the custom marshaler helper from the EE marshaling data. + RETURN pMarshalingData->GetIEnumeratorMarshalerInfo(); + } +#endif // FEATURE_COMINTEROP -namespace -{ //========================================================================== // Return: S_OK if there is valid data to compress // S_FALSE if at end of data block @@ -405,69 +410,6 @@ VOID CollateParamTokens(IMDInternalImport *pInternalImport, mdMethodDef md, ULON } } - -#ifdef FEATURE_COMINTEROP -OleColorMarshalingInfo::OleColorMarshalingInfo() : - m_OleColorToSystemColorMD(NULL), - m_SystemColorToOleColorMD(NULL) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - SString qualifiedColorTranslatorTypeName(SString::Utf8, COLOR_TRANSLATOR_ASM_QUAL_TYPE_NAME); - - // Load the color translator class. - TypeHandle hndColorTranslatorType = TypeName::GetTypeFromAsmQualifiedName(qualifiedColorTranslatorTypeName.GetUnicode(), TRUE /* bThrowIfNotFound */); - - SString qualifiedColorTypeName(SString::Utf8, COLOR_ASM_QUAL_TYPE_NAME); - // Load the color class. - m_hndColorType = TypeName::GetTypeFromAsmQualifiedName(qualifiedColorTypeName.GetUnicode(), TRUE /* bThrowIfNotFound */); - - // Retrieve the method to convert an OLE_COLOR to a System.Drawing.Color. - m_OleColorToSystemColorMD = MemberLoader::FindMethodByName(hndColorTranslatorType.GetMethodTable(), OLECOLOR_TO_SYSTEMCOLOR_METH_NAME); - _ASSERTE(m_OleColorToSystemColorMD && "Unable to find the translator method to convert an OLE_COLOR to a System.Drawing.Color!"); - _ASSERTE(m_OleColorToSystemColorMD->IsStatic() && "The translator method to convert an OLE_COLOR to a System.Drawing.Color must be static!"); - - // Retrieve the method to convert a System.Drawing.Color to an OLE_COLOR. - m_SystemColorToOleColorMD = MemberLoader::FindMethodByName(hndColorTranslatorType.GetMethodTable(), SYSTEMCOLOR_TO_OLECOLOR_METH_NAME); - _ASSERTE(m_SystemColorToOleColorMD && "Unable to find the translator method to convert a System.Drawing.Color to an OLE_COLOR!"); - _ASSERTE(m_SystemColorToOleColorMD->IsStatic() && "The translator method to convert a System.Drawing.Color to an OLE_COLOR must be static!"); -} - - -void *OleColorMarshalingInfo::operator new(size_t size, LoaderHeap *pHeap) -{ - CONTRACT (void*) - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pHeap)); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END; - - void* mem = pHeap->AllocMem(S_SIZE_T(size)); - - RETURN mem; -} - - -void OleColorMarshalingInfo::operator delete(void *pMem) -{ - LIMITED_METHOD_CONTRACT; - // Instances of this class are always allocated on the loader heap so - // the delete operator has nothing to do. -} - -#endif // FEATURE_COMINTEROP - EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst) : m_pAllocator(pAllocator), m_pHeap(pAllocator->GetLowFrequencyHeap()), @@ -483,8 +425,7 @@ EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst) LockOwner lock = {pCrst, IsOwnerOfCrst}; m_structILStubCache.Init(INITIAL_NUM_STRUCT_ILSTUB_HASHTABLE_BUCKETS, &lock); - m_CMHelperHashtable.Init(INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS, &lock); - m_SharedCMHelperToCMInfoMap.Init(INITIAL_NUM_CMINFO_HASHTABLE_BUCKETS, &lock); + m_CMInfoHashTable.Init(INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS, &lock); } @@ -492,22 +433,11 @@ EEMarshalingData::~EEMarshalingData() { WRAPPER_NO_CONTRACT; - CustomMarshalerInfo *pCMInfo; - - // @TODO(DM): Remove the linked list of CMInfo's and instead hang the OBJECTHANDLE - // contained inside the CMInfo off the AppDomain directly. The AppDomain can have - // a list of tasks to do when it gets teared down and we could leverage that - // to release the object handles. - - // Walk through the linked list and delete all the custom marshaler info's. - while ((pCMInfo = m_pCMInfoList.RemoveHead()) != NULL) - delete pCMInfo; - #ifdef FEATURE_COMINTEROP - if (m_pOleColorInfo) + if (m_pIEnumeratorMarshalerInfo) { - delete m_pOleColorInfo; - m_pOleColorInfo = NULL; + delete m_pIEnumeratorMarshalerInfo; + m_pIEnumeratorMarshalerInfo = NULL; } #endif } @@ -557,31 +487,28 @@ void EEMarshalingData::CacheStructILStub(MethodTable* pMT, MethodDesc* pStubMD) } -CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) +CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) { - CONTRACT (CustomMarshalerHelper*) + CONTRACT (CustomMarshalerInfo*) { - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; INJECT_FAULT(COMPlusThrowOM()); PRECONDITION(CheckPointer(pAssembly)); POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - CustomMarshalerHelper *pCMHelper = NULL; - CustomMarshalerHelper* pNewCMHelper = NULL; + CustomMarshalerInfo *pCMInfo = NULL; NewHolder pNewCMInfo(NULL); TypeHandle hndCustomMarshalerType; // Create the key that will be used to lookup in the hashtable. - EECMHelperHashtableKey Key(cMarshalerTypeNameBytes, strMarshalerTypeName, cCookieStrBytes, strCookie, hndManagedType.GetInstantiation(), pAssembly); + EECMInfoHashtableKey Key(cMarshalerTypeNameBytes, strMarshalerTypeName, cCookieStrBytes, strCookie, hndManagedType.GetInstantiation(), pAssembly); // Lookup the custom marshaler helper in the hashtable. - if (m_CMHelperHashtable.GetValue(&Key, (HashDatum*)&pCMHelper)) - RETURN pCMHelper; + if (m_CMInfoHashTable.GetValue(&Key, (HashDatum*)&pCMInfo)) + RETURN pCMInfo; { GCX_COOP(); @@ -603,127 +530,54 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss // Create the custom marshaler info in the specified heap. pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, hndCustomMarshalerType, hndManagedType, strCookie, cCookieStrBytes); - - // Create the custom marshaler helper in the specified heap. - pNewCMHelper = new (m_pHeap) NonSharedCustomMarshalerHelper(pNewCMInfo); } { CrstHolder lock(m_lock); // Verify that the custom marshaler helper has not already been added by another thread. - if (m_CMHelperHashtable.GetValue(&Key, (HashDatum*)&pCMHelper)) - { - RETURN pCMHelper; - } - - // Add the custom marshaler helper to the hash table. - m_CMHelperHashtable.InsertValue(&Key, pNewCMHelper, FALSE); - - // If we create the CM info, then add it to the linked list. - if (pNewCMInfo) - { - m_pCMInfoList.InsertHead(pNewCMInfo); - pNewCMInfo.SuppressRelease(); - } - - // Release the lock and return the custom marshaler info. - } - - RETURN pNewCMHelper; -} - -CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(SharedCustomMarshalerHelper *pSharedCMHelper) -{ - CONTRACT (CustomMarshalerInfo*) - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END; - - CustomMarshalerInfo *pCMInfo = NULL; - NewHolder pNewCMInfo(NULL); - TypeHandle hndCustomMarshalerType; - - // Lookup the custom marshaler helper in the hashtable. - if (m_SharedCMHelperToCMInfoMap.GetValue(pSharedCMHelper, (HashDatum*)&pCMInfo)) - RETURN pCMInfo; - - // Append a NULL terminator to the marshaler type name. - CQuickArray strCMMarshalerTypeName; - DWORD strLen = pSharedCMHelper->GetMarshalerTypeNameByteCount(); - strCMMarshalerTypeName.ReSizeThrows(pSharedCMHelper->GetMarshalerTypeNameByteCount() + 1); - memcpy(strCMMarshalerTypeName.Ptr(), pSharedCMHelper->GetMarshalerTypeName(), strLen); - strCMMarshalerTypeName[strLen] = 0; - - // Load the custom marshaler class. - hndCustomMarshalerType = TypeName::GetTypeReferencedByCustomAttribute(strCMMarshalerTypeName.Ptr(), pSharedCMHelper->GetAssembly()); - if (hndCustomMarshalerType.IsGenericTypeDefinition()) - { - // Instantiate generic custom marshalers using the instantiation of the type being marshaled. - hndCustomMarshalerType = hndCustomMarshalerType.Instantiate(pSharedCMHelper->GetManagedType().GetInstantiation()); - } - - // Create the custom marshaler info in the specified heap. - pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, - hndCustomMarshalerType, - pSharedCMHelper->GetManagedType(), - pSharedCMHelper->GetCookieString(), - pSharedCMHelper->GetCookieStringByteCount()); - - { - CrstHolder lock(m_lock); - - // Verify that the custom marshaler info has not already been added by another thread. - if (m_SharedCMHelperToCMInfoMap.GetValue(pSharedCMHelper, (HashDatum*)&pCMInfo)) + if (m_CMInfoHashTable.GetValue(&Key, (HashDatum*)&pCMInfo)) { RETURN pCMInfo; } // Add the custom marshaler helper to the hash table. - m_SharedCMHelperToCMInfoMap.InsertValue(pSharedCMHelper, pNewCMInfo, FALSE); + m_CMInfoHashTable.InsertValue(&Key, pNewCMInfo); - // Add the custom marshaler into the linked list. - m_pCMInfoList.InsertHead(pNewCMInfo); + // If we create the CM info, then add it to the linked list. + pNewCMInfo.SuppressRelease(); // Release the lock and return the custom marshaler info. } - pNewCMInfo.SuppressRelease(); RETURN pNewCMInfo; } #ifdef FEATURE_COMINTEROP -OleColorMarshalingInfo *EEMarshalingData::GetOleColorMarshalingInfo() +CustomMarshalerInfo *EEMarshalingData::GetIEnumeratorMarshalerInfo() { - CONTRACT (OleColorMarshalingInfo*) + CONTRACT (CustomMarshalerInfo*) { - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; INJECT_FAULT(COMPlusThrowOM()); POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - if (m_pOleColorInfo == NULL) + if (m_pIEnumeratorMarshalerInfo == NULL) { - OleColorMarshalingInfo *pOleColorInfo = new (m_pHeap) OleColorMarshalingInfo(); + CustomMarshalerInfo *pMarshalerInfo = CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(m_pHeap, m_pAllocator); - if (InterlockedCompareExchangeT(&m_pOleColorInfo, pOleColorInfo, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_pIEnumeratorMarshalerInfo, pMarshalerInfo, NULL) != NULL) { - // Another thread beat us to it. Delete on OleColorMarshalingInfo is an empty operation + // Another thread beat us to it. Delete on CustomMarshalerInfo is an empty operation // which is OK, since the possible leak is rare, small, and constant. This is the same // pattern as in code:GetCustomMarshalerInfo. - delete pOleColorInfo; + delete pMarshalerInfo; } } - RETURN m_pOleColorInfo; + RETURN m_pIEnumeratorMarshalerInfo; } #endif // FEATURE_COMINTEROP @@ -921,7 +775,7 @@ MarshalInfo::MarshalInfo(Module* pModule, m_ms = ms; m_fAnsi = (ms == MARSHAL_SCENARIO_NDIRECT || ms == MARSHAL_SCENARIO_FIELD) && (nlType == nltAnsi); m_nativeArgSize = 0; - m_pCMHelper = NULL; + m_pCMInfo = NULL; m_CMVt = VT_EMPTY; m_args.m_pMarshalInfo = this; m_args.m_pMT = NULL; @@ -1116,7 +970,7 @@ MarshalInfo::MarshalInfo(Module* pModule, IfFailGoto(E_FAIL, lFail); } - // Set m_type to MARSHAL_TYPE_UNKNOWN in case SetupCustomMarshalerHelper throws. + // Set m_type to MARSHAL_TYPE_UNKNOWN in case SetupCustomMarshalerInfo throws. m_type = MARSHAL_TYPE_UNKNOWN; if (fLoadCustomMarshal) @@ -1126,7 +980,7 @@ MarshalInfo::MarshalInfo(Module* pModule, if (!fEmitsIL) { - m_pCMHelper = SetupCustomMarshalerHelper(ParamInfo.m_strCMMarshalerTypeName, + m_pCMInfo = SetupCustomMarshalerInfo(ParamInfo.m_strCMMarshalerTypeName, ParamInfo.m_cCMMarshalerTypeNameBytes, ParamInfo.m_strCMCookie, ParamInfo.m_cCMCookieStrBytes, @@ -1135,7 +989,7 @@ MarshalInfo::MarshalInfo(Module* pModule, } else { - m_pCMHelper = NULL; + m_pCMInfo = NULL; MethodDesc* pMDforModule = pMD; if (pMD->IsILStub()) { @@ -1614,15 +1468,11 @@ MarshalInfo::MarshalInfo(Module* pModule, { if (!fEmitsIL) { - m_pCMHelper = SetupCustomMarshalerHelper(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, - ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN, - pAssembly, sigTH); + m_pCMInfo = GetIEnumeratorCustomMarshalerInfo(pAssembly); } else { - m_pCMHelper = NULL; + m_pCMInfo = NULL; MethodDesc* pMDforModule = pMD; if (pMD->IsILStub()) { @@ -1957,6 +1807,14 @@ MarshalInfo::MarshalInfo(Module* pModule, IfFailGoto(E_FAIL, lFail); } + GCX_COOP(); + + FieldDesc* pColorTypeField = CoreLibBinder::GetField(FIELD__COLORMARSHALER__COLOR_TYPE); + pColorTypeField->CheckRunClassInitThrowing(); + void* colorTypeHandle = pColorTypeField->GetStaticValuePtr(); + + m_args.color.m_pColorType = TypeHandle::FromPtr(colorTypeHandle).GetMethodTable(); + m_type = MARSHAL_TYPE_OLECOLOR; } #endif // FEATURE_COMINTEROP @@ -3281,7 +3139,7 @@ DispParamMarshaler *MarshalInfo::GenerateDispParamMarshaler() break; case MARSHAL_TYPE_REFERENCECUSTOMMARSHALER: - pDispParamMarshaler = new DispParamCustomMarshaler(m_pCMHelper, m_CMVt); + pDispParamMarshaler = new DispParamCustomMarshaler(m_pCMInfo, m_CMVt); break; } @@ -3733,14 +3591,14 @@ bool IsUnsupportedTypedrefReturn(MetaSig& msig) #include "stubhelpers.h" -extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType) +extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType, QCall::ObjectHandleOnStack retObject) { QCALL_CONTRACT; - CustomMarshalerHelper* pCMHelper = NULL; - BEGIN_QCALL; + CustomMarshalerInfo* pCMInfo = NULL; + Module* pModule = pMD->GetModule(); Assembly* pAssembly = pModule->GetAssembly(); @@ -3748,40 +3606,37 @@ extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* p if (!hndManagedType.IsTypeDesc() && IsTypeRefOrDef(g_CollectionsEnumeratorClassName, hndManagedType.GetModule(), hndManagedType.GetCl())) { - pCMHelper = SetupCustomMarshalerHelper(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, - ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN, - pAssembly, hndManagedType); + _ASSERTE(!"Setting the custom marshaler for IEnumerator should be done on the managed side."); } - else #endif // FEATURE_COMINTEROP - { - // - // Retrieve the native type for the current parameter. - // - BOOL result; - NativeTypeParamInfo ParamInfo; - result = ParseNativeTypeInfo(paramToken, pModule->GetMDImport(), &ParamInfo); + // + // Retrieve the native type for the current parameter. + // - // - // this should all have been done at stub creation time - // - CONSISTENCY_CHECK(result != 0); - CONSISTENCY_CHECK(ParamInfo.m_NativeType == NATIVE_TYPE_CUSTOMMARSHALER); + BOOL result; + NativeTypeParamInfo ParamInfo; + result = ParseNativeTypeInfo(paramToken, pModule->GetMDImport(), &ParamInfo); + + // + // this should all have been done at stub creation time + // + CONSISTENCY_CHECK(result != 0); + CONSISTENCY_CHECK(ParamInfo.m_NativeType == NATIVE_TYPE_CUSTOMMARSHALER); - // Set up the custom marshaler info. - pCMHelper = SetupCustomMarshalerHelper(ParamInfo.m_strCMMarshalerTypeName, - ParamInfo.m_cCMMarshalerTypeNameBytes, - ParamInfo.m_strCMCookie, - ParamInfo.m_cCMCookieStrBytes, - pAssembly, - hndManagedType); + // Set up the custom marshaler info. + pCMInfo = SetupCustomMarshalerInfo(ParamInfo.m_strCMMarshalerTypeName, + ParamInfo.m_cCMMarshalerTypeNameBytes, + ParamInfo.m_strCMCookie, + ParamInfo.m_cCMCookieStrBytes, + pAssembly, + hndManagedType); + + { + GCX_COOP(); + retObject.Set(pCMInfo->GetCustomMarshaler()); } END_QCALL; - - return (void*)pCMHelper; } diff --git a/src/coreclr/vm/mlinfo.h b/src/coreclr/vm/mlinfo.h index 795427ef4b9a45..3d2c5186556191 100644 --- a/src/coreclr/vm/mlinfo.h +++ b/src/coreclr/vm/mlinfo.h @@ -102,6 +102,13 @@ struct OverrideProcArgs { UINT32 fixedStringLength; } fs; + +#ifdef FEATURE_COMINTEROP + struct + { + MethodTable* m_pColorType; + } color; +#endif }; }; @@ -188,45 +195,6 @@ BOOL ParseNativeTypeInfo(mdToken token, BOOL IsFixedBuffer(mdFieldDef field, IMDInternalImport* pInternalImport); #endif -#ifdef FEATURE_COMINTEROP -class OleColorMarshalingInfo -{ -public: - // Constructor. - OleColorMarshalingInfo(); - - // OleColorMarshalingInfo's are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void *operator new(size_t size, LoaderHeap *pHeap); - void operator delete(void *pMem); - - // Accessors. - TypeHandle GetColorType() - { - LIMITED_METHOD_CONTRACT; - return m_hndColorType; - } - MethodDesc *GetOleColorToSystemColorMD() - { - LIMITED_METHOD_CONTRACT; - return m_OleColorToSystemColorMD; - } - MethodDesc *GetSystemColorToOleColorMD() - { - LIMITED_METHOD_CONTRACT; - return m_SystemColorToOleColorMD; - } - - -private: - TypeHandle m_hndColorType; - MethodDesc* m_OleColorToSystemColorMD; - MethodDesc* m_SystemColorToOleColorMD; -}; - -#endif // FEATURE_COMINTEROP - - class EEMarshalingData { public: @@ -258,27 +226,21 @@ class EEMarshalingData void CacheStructILStub(MethodTable* pMT, MethodDesc* pStubMD); #endif - // This method returns the custom marshaling helper associated with the name cookie pair. If the + // This method returns the custom marshaling info associated with the name cookie pair. If the // CM info has not been created yet for this pair then it will be created and returned. - CustomMarshalerHelper *GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); - - // This method returns the custom marshaling info associated with shared CM helper. - CustomMarshalerInfo *GetCustomMarshalerInfo(SharedCustomMarshalerHelper *pSharedCMHelper); + CustomMarshalerInfo *GetCustomMarshalerInfo(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); #ifdef FEATURE_COMINTEROP - // This method retrieves OLE_COLOR marshaling info. - OleColorMarshalingInfo *GetOleColorMarshalingInfo(); + CustomMarshalerInfo *GetIEnumeratorMarshalerInfo(); #endif // FEATURE_COMINTEROP private: EEPtrHashTable m_structILStubCache; - EECMHelperHashTable m_CMHelperHashtable; - EEPtrHashTable m_SharedCMHelperToCMInfoMap; + EECMInfoHashTable m_CMInfoHashTable; LoaderAllocator* m_pAllocator; LoaderHeap* m_pHeap; - CMINFOLIST m_pCMInfoList; #ifdef FEATURE_COMINTEROP - OleColorMarshalingInfo* m_pOleColorInfo; + CustomMarshalerInfo* m_pIEnumeratorMarshalerInfo; #endif // FEATURE_COMINTEROP CrstBase* m_lock; }; @@ -543,7 +505,7 @@ class MarshalInfo #endif // FEATURE_COMINTEROP // Information used by NT_CUSTOMMARSHALER. - CustomMarshalerHelper* m_pCMHelper; + CustomMarshalerInfo* m_pCMInfo; VARTYPE m_CMVt; OverrideProcArgs m_args; diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 215e2d34ef69a9..01d3e69f01ace5 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -225,7 +225,6 @@ static const Entry s_QCall[] = DllImportEntry(MultiCoreJIT_InternalStartProfile) #endif DllImportEntry(LoaderAllocator_Destroy) - DllImportEntry(CustomMarshaler_GetMarshalerObject) DllImportEntry(String_Intern) DllImportEntry(String_IsInterned) DllImportEntry(AppDomain_CreateDynamicAssembly) @@ -325,8 +324,6 @@ static const Entry s_QCall[] = DllImportEntry(MngdSafeArrayMarshaler_ConvertSpaceToManaged) DllImportEntry(MngdSafeArrayMarshaler_ConvertContentsToManaged) DllImportEntry(MngdSafeArrayMarshaler_ClearNative) - DllImportEntry(Variant_ConvertSystemColorToOleColor) - DllImportEntry(Variant_ConvertOleColorToSystemColor) DllImportEntry(Variant_ConvertValueTypeToRecord) #endif // FEATURE_COMINTEROP DllImportEntry(NativeLibrary_LoadFromPath) @@ -423,7 +420,7 @@ static const Entry s_QCall[] = #if defined(TARGET_X86) || defined(TARGET_AMD64) DllImportEntry(X86BaseCpuId) #endif - DllImportEntry(StubHelpers_CreateCustomMarshalerHelper) + DllImportEntry(StubHelpers_CreateCustomMarshaler) DllImportEntry(StubHelpers_SetStringTrailByte) DllImportEntry(StubHelpers_ThrowInteropParamException) DllImportEntry(StubHelpers_MarshalToManagedVaList) diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp index 17602750ab2edc..4692bfb3a4cf57 100644 --- a/src/coreclr/vm/stubgen.cpp +++ b/src/coreclr/vm/stubgen.cpp @@ -1177,6 +1177,11 @@ void ILCodeStream::EmitBNE_UN(ILCodeLabel* pCodeLabel) WRAPPER_NO_CONTRACT; Emit(CEE_BNE_UN, -2, (UINT_PTR)pCodeLabel); } +void ILCodeStream::EmitBOX(int token) +{ + WRAPPER_NO_CONTRACT; + Emit(CEE_BOX, 0, token); +} void ILCodeStream::EmitBR(ILCodeLabel* pCodeLabel) { WRAPPER_NO_CONTRACT; @@ -1812,6 +1817,11 @@ void ILCodeStream::EmitUNALIGNED(BYTE alignment) Emit(CEE_UNALIGNED, 0, alignment); } +void ILCodeStream::EmitUNBOX_ANY(int token) +{ + WRAPPER_NO_CONTRACT; + Emit(CEE_UNBOX_ANY, 0, token); +} void ILCodeStream::EmitNEWOBJ(BinderMethodID id, int numInArgs) { diff --git a/src/coreclr/vm/stubgen.h b/src/coreclr/vm/stubgen.h index 3e5427fece5753..ba42eae5be65a4 100644 --- a/src/coreclr/vm/stubgen.h +++ b/src/coreclr/vm/stubgen.h @@ -852,6 +852,7 @@ class ILCodeStream void EmitBLE_UN (ILCodeLabel* pCodeLabel); void EmitBLT (ILCodeLabel* pCodeLabel); void EmitBNE_UN (ILCodeLabel* pCodeLabel); + void EmitBOX (int token); void EmitBR (ILCodeLabel* pCodeLabel); void EmitBREAK (); void EmitBRFALSE (ILCodeLabel* pCodeLabel); @@ -943,6 +944,7 @@ class ILCodeStream void EmitSUB (); void EmitTHROW (); void EmitUNALIGNED (BYTE alignment); + void EmitUNBOX_ANY (int token); // Overloads to simplify common usage patterns void EmitNEWOBJ (BinderMethodID id, int numInArgs); diff --git a/src/coreclr/vm/stubhelpers.h b/src/coreclr/vm/stubhelpers.h index 5b0bb00d684ba7..72f5102aa9c823 100644 --- a/src/coreclr/vm/stubhelpers.h +++ b/src/coreclr/vm/stubhelpers.h @@ -44,7 +44,7 @@ class StubHelpers static FCDECL0(void*, NextCallReturnAddress); }; -extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType); +extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType, QCall::ObjectHandleOnStack retObject); #ifdef PROFILING_SUPPORTED extern "C" void* QCALLTYPE StubHelpers_ProfilerBeginTransitionCallback(MethodDesc* pTargetMD);