summaryrefslogtreecommitdiff
path: root/src/vm/mlinfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/mlinfo.h')
-rw-r--r--src/vm/mlinfo.h998
1 files changed, 998 insertions, 0 deletions
diff --git a/src/vm/mlinfo.h b/src/vm/mlinfo.h
new file mode 100644
index 0000000000..f66c9c6bd8
--- /dev/null
+++ b/src/vm/mlinfo.h
@@ -0,0 +1,998 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// File: mlinfo.h
+//
+
+//
+
+
+#include "stubgen.h"
+#include "custommarshalerinfo.h"
+
+#ifdef FEATURE_COMINTEROP
+#include <windows.ui.xaml.h>
+#endif
+
+#ifndef _MLINFO_H_
+#define _MLINFO_H_
+
+#define NATIVE_TYPE_DEFAULT NATIVE_TYPE_MAX
+#define VARIABLESIZE ((BYTE)(-1))
+
+
+#ifdef FEATURE_COMINTEROP
+class DispParamMarshaler;
+#endif // FEATURE_COMINTEROP
+
+#ifdef FEATURE_COMINTEROP
+enum DispatchWrapperType
+{
+ DispatchWrapperType_Unknown = 0x00000001,
+ DispatchWrapperType_Dispatch = 0x00000002,
+ DispatchWrapperType_Error = 0x00000008,
+ DispatchWrapperType_Currency = 0x00000010,
+ DispatchWrapperType_BStr = 0x00000020,
+ DispatchWrapperType_SafeArray = 0x00010000
+};
+#endif // FEATURE_COMINTEROP
+
+typedef enum
+{
+ HANDLEASNORMAL = 0,
+ OVERRIDDEN = 1,
+ DISALLOWED = 2,
+} MarshalerOverrideStatus;
+
+
+enum MarshalFlags
+{
+ MARSHAL_FLAG_CLR_TO_NATIVE = 0x01,
+ MARSHAL_FLAG_IN = 0x02,
+ MARSHAL_FLAG_OUT = 0x04,
+ MARSHAL_FLAG_BYREF = 0x08,
+ MARSHAL_FLAG_HRESULT_SWAP = 0x10,
+ MARSHAL_FLAG_RETVAL = 0x20,
+ MARSHAL_FLAG_HIDDENLENPARAM = 0x40,
+};
+
+#include <pshpack1.h>
+// Captures arguments for C array marshaling.
+struct CREATE_MARSHALER_CARRAY_OPERANDS
+{
+ MethodTable* methodTable;
+ UINT32 multiplier;
+ UINT32 additive;
+ VARTYPE elementType;
+ UINT16 countParamIdx;
+ BYTE bestfitmapping;
+ BYTE throwonunmappablechar;
+};
+#include <poppack.h>
+
+struct OverrideProcArgs
+{
+ class MarshalInfo* m_pMarshalInfo;
+
+ union
+ {
+ MethodTable* m_pMT;
+
+ struct
+ {
+ VARTYPE m_vt;
+ UINT16 m_optionalbaseoffset; //for fast marshaling, offset of dataptr if known and less than 64k (0 otherwise)
+ MethodTable* m_pMT;
+#ifdef FEATURE_COMINTEROP
+ SIZE_T m_cbElementSize;
+ WinMDAdapter::RedirectedTypeIndex m_redirectedTypeIndex;
+#endif // FEATURE_COMINTEROP
+ } na;
+
+ struct
+ {
+ MethodTable* m_pMT;
+ MethodDesc* m_pCopyCtor;
+ MethodDesc* m_pDtor;
+ } mm;
+
+ struct
+ {
+ MethodDesc* m_pMD;
+ mdToken m_paramToken;
+ void* m_hndManagedType; // TypeHandle cannot be a union member
+ } rcm; // MARSHAL_TYPE_REFERENCECUSTOMMARSHALER
+
+ };
+};
+
+typedef MarshalerOverrideStatus (*OVERRIDEPROC)(NDirectStubLinker* psl,
+ BOOL byref,
+ BOOL fin,
+ BOOL fout,
+ BOOL fManagedToNative,
+ OverrideProcArgs* pargs,
+ UINT* pResID,
+ UINT argidx,
+ UINT nativeStackOffset);
+
+typedef MarshalerOverrideStatus (*RETURNOVERRIDEPROC)(NDirectStubLinker* psl,
+ BOOL fManagedToNative,
+ BOOL fHresultSwap,
+ OverrideProcArgs* pargs,
+ UINT* pResID);
+
+//==========================================================================
+// This structure contains the native type information for a given
+// parameter.
+//==========================================================================
+struct NativeTypeParamInfo
+{
+ NativeTypeParamInfo()
+ : m_NativeType(NATIVE_TYPE_DEFAULT)
+ , m_ArrayElementType(NATIVE_TYPE_DEFAULT)
+ , m_SizeIsSpecified(FALSE)
+ , m_CountParamIdx(0)
+ , m_Multiplier(0)
+ , m_Additive(1)
+ , m_strCMMarshalerTypeName(NULL)
+ , m_cCMMarshalerTypeNameBytes(0)
+ , m_strCMCookie(NULL)
+ , m_cCMCookieStrBytes(0)
+#ifdef FEATURE_COMINTEROP
+ , m_SafeArrayElementVT(VT_EMPTY)
+ , m_strSafeArrayUserDefTypeName(NULL)
+ , m_cSafeArrayUserDefTypeNameBytes(0)
+ , m_IidParamIndex(-1)
+ , m_strInterfaceTypeName(NULL)
+ , m_cInterfaceTypeNameBytes(0)
+#endif // FEATURE_COMINTEROP
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ // The native type of the parameter.
+ CorNativeType m_NativeType;
+
+ // for NT_ARRAY only
+ CorNativeType m_ArrayElementType; // The array element type.
+
+ BOOL m_SizeIsSpecified; // used to do some validation
+ UINT16 m_CountParamIdx; // index of "sizeis" parameter
+ UINT32 m_Multiplier; // multipler for "sizeis"
+ UINT32 m_Additive; // additive for 'sizeis"
+
+ // For NT_CUSTOMMARSHALER only.
+ LPUTF8 m_strCMMarshalerTypeName;
+ DWORD m_cCMMarshalerTypeNameBytes;
+ LPUTF8 m_strCMCookie;
+ DWORD m_cCMCookieStrBytes;
+
+#ifdef FEATURE_COMINTEROP
+ // For NT_SAFEARRAY only.
+ VARTYPE m_SafeArrayElementVT;
+ LPUTF8 m_strSafeArrayUserDefTypeName;
+ DWORD m_cSafeArrayUserDefTypeNameBytes;
+
+ DWORD m_IidParamIndex; // Capture iid_is syntax from IDL.
+
+ // for NATIVE_TYPE_SPECIFIED_INTERFACE
+ LPUTF8 m_strInterfaceTypeName;
+ DWORD m_cInterfaceTypeNameBytes;
+#endif // FEATURE_COMINTEROP
+};
+
+HRESULT CheckForCompressedData(PCCOR_SIGNATURE pvNativeTypeStart, PCCOR_SIGNATURE pvNativeType, ULONG cbNativeType);
+
+BOOL ParseNativeTypeInfo(mdToken token,
+ IMDInternalImport* pScope,
+ NativeTypeParamInfo* pParamInfo);
+
+void VerifyAndAdjustNormalizedType(
+ Module * pModule,
+ SigPointer sigPtr,
+ const SigTypeContext * pTypeContext,
+ CorElementType * pManagedElemType,
+ CorNativeType * pNativeType);
+
+#ifdef FEATURE_COMINTEROP
+
+class EventArgsMarshalingInfo
+{
+public:
+ // Constructor.
+ EventArgsMarshalingInfo();
+
+ // Destructor.
+ ~EventArgsMarshalingInfo();
+
+ // EventArgsMarshalingInfo'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 GetSystemNCCEventArgsType()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_hndSystemNCCEventArgsType;
+ }
+
+ TypeHandle GetSystemPCEventArgsType()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_hndSystemPCEventArgsType;
+ }
+
+ ABI::Windows::UI::Xaml::Interop::INotifyCollectionChangedEventArgsFactory *GetNCCEventArgsFactory()
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS; // For potential COOP->PREEMP->COOP switch
+ MODE_ANY;
+ PRECONDITION(!GetAppDomain()->IsCompilationDomain());
+ }
+ CONTRACTL_END;
+
+ if (m_pNCCEventArgsFactory.Load() == NULL)
+ {
+ GCX_PREEMP();
+ SafeComHolderPreemp<ABI::Windows::UI::Xaml::Interop::INotifyCollectionChangedEventArgsFactory> pNCCEventArgsFactory;
+
+ IfFailThrow(clr::winrt::GetActivationFactory(g_WinRTNotifyCollectionChangedEventArgsNameW, (ABI::Windows::UI::Xaml::Interop::INotifyCollectionChangedEventArgsFactory **)&pNCCEventArgsFactory));
+ _ASSERTE_MSG(pNCCEventArgsFactory, "Got NULL NCCEventArgs factory!");
+
+ if (InterlockedCompareExchangeT(&m_pNCCEventArgsFactory, (ABI::Windows::UI::Xaml::Interop::INotifyCollectionChangedEventArgsFactory *)pNCCEventArgsFactory, NULL) == NULL)
+ pNCCEventArgsFactory.SuppressRelease();
+ }
+
+ return m_pNCCEventArgsFactory;
+ }
+
+ ABI::Windows::UI::Xaml::Data::IPropertyChangedEventArgsFactory *GetPCEventArgsFactory()
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS; // For potential COOP->PREEMP->COOP switch
+ MODE_ANY;
+ PRECONDITION(!GetAppDomain()->IsCompilationDomain());
+ }
+ CONTRACTL_END;
+
+ if (m_pPCEventArgsFactory.Load() == NULL)
+ {
+ GCX_PREEMP();
+ SafeComHolderPreemp<ABI::Windows::UI::Xaml::Data::IPropertyChangedEventArgsFactory> pPCEventArgsFactory;
+
+ IfFailThrow(clr::winrt::GetActivationFactory(g_WinRTPropertyChangedEventArgsNameW, (ABI::Windows::UI::Xaml::Data::IPropertyChangedEventArgsFactory **)&pPCEventArgsFactory));
+ _ASSERTE_MSG(pPCEventArgsFactory, "Got NULL PCEventArgs factory!");
+
+ if (InterlockedCompareExchangeT(&m_pPCEventArgsFactory, (ABI::Windows::UI::Xaml::Data::IPropertyChangedEventArgsFactory *)pPCEventArgsFactory, NULL) == NULL)
+ pPCEventArgsFactory.SuppressRelease();
+ }
+
+ return m_pPCEventArgsFactory;
+ }
+
+ MethodDesc *GetSystemNCCEventArgsToWinRTNCCEventArgsMD()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pSystemNCCEventArgsToWinRTNCCEventArgsMD;
+ }
+
+ MethodDesc *GetWinRTNCCEventArgsToSystemNCCEventArgsMD()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pWinRTNCCEventArgsToSystemNCCEventArgsMD;
+ }
+
+ MethodDesc *GetSystemPCEventArgsToWinRTPCEventArgsMD()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pSystemPCEventArgsToWinRTPCEventArgsMD;
+ }
+
+ MethodDesc *GetWinRTPCEventArgsToSystemPCEventArgsMD()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pWinRTPCEventArgsToSystemPCEventArgsMD;
+ }
+
+#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+ BOOL IsEventArgsHelperMethod(MethodDesc *pMD)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (pMD == m_pSystemNCCEventArgsToWinRTNCCEventArgsMD || pMD == m_pWinRTNCCEventArgsToSystemNCCEventArgsMD ||
+ pMD == m_pSystemPCEventArgsToWinRTPCEventArgsMD || pMD == m_pWinRTPCEventArgsToSystemPCEventArgsMD);
+ }
+#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+
+private:
+ TypeHandle m_hndSystemNCCEventArgsType;
+ TypeHandle m_hndSystemPCEventArgsType;
+
+ MethodDesc *m_pSystemNCCEventArgsToWinRTNCCEventArgsMD;
+ MethodDesc *m_pWinRTNCCEventArgsToSystemNCCEventArgsMD;
+ MethodDesc *m_pSystemPCEventArgsToWinRTPCEventArgsMD;
+ MethodDesc *m_pWinRTPCEventArgsToSystemPCEventArgsMD;
+
+ VolatilePtr<ABI::Windows::UI::Xaml::Interop::INotifyCollectionChangedEventArgsFactory> m_pNCCEventArgsFactory;
+ VolatilePtr<ABI::Windows::UI::Xaml::Data::IPropertyChangedEventArgsFactory> m_pPCEventArgsFactory;
+};
+
+class UriMarshalingInfo
+{
+public:
+ // Constructor.
+ UriMarshalingInfo();
+
+ // Destructor
+ ~UriMarshalingInfo();
+
+ // UriMarshalingInfo'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 GetSystemUriType()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_hndSystemUriType;
+ }
+
+ ABI::Windows::Foundation::IUriRuntimeClassFactory* GetUriFactory()
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS; // For potential COOP->PREEMP->COOP switch
+ MODE_ANY;
+ PRECONDITION(!GetAppDomain()->IsCompilationDomain());
+ }
+ CONTRACTL_END;
+
+ if (m_pUriFactory.Load() == NULL)
+ {
+ GCX_PREEMP();
+
+ SafeComHolderPreemp<ABI::Windows::Foundation::IUriRuntimeClassFactory> pUriFactory;
+
+ // IUriRuntimeClassFactory: 44A9796F-723E-4FDF-A218-033E75B0C084
+ IfFailThrow(clr::winrt::GetActivationFactory(g_WinRTUriClassNameW, (ABI::Windows::Foundation::IUriRuntimeClassFactory **)&pUriFactory));
+ _ASSERTE_MSG(pUriFactory, "Got Null Uri factory!");
+
+ if (InterlockedCompareExchangeT(&m_pUriFactory, (ABI::Windows::Foundation::IUriRuntimeClassFactory *) pUriFactory, NULL) == NULL)
+ pUriFactory.SuppressRelease();
+ }
+
+ return m_pUriFactory;
+ }
+
+ MethodDesc *GetSystemUriCtorMD()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_SystemUriCtorMD;
+ }
+
+ MethodDesc *GetSystemUriOriginalStringMD()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_SystemUriOriginalStringGetterMD;
+ }
+
+#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+ BOOL IsUriHelperMethod(MethodDesc *pMD)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return pMD == m_SystemUriCtorMD || pMD == m_SystemUriOriginalStringGetterMD;
+ }
+#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+
+private:
+ TypeHandle m_hndSystemUriType;
+
+ MethodDesc* m_SystemUriCtorMD;
+ MethodDesc* m_SystemUriOriginalStringGetterMD;
+
+ VolatilePtr<ABI::Windows::Foundation::IUriRuntimeClassFactory> m_pUriFactory;
+};
+
+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;
+ }
+
+#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+ BOOL IsOleColorHelperMethod(MethodDesc *pMD)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return pMD == m_OleColorToSystemColorMD || pMD == m_SystemColorToOleColorMD;
+ }
+#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+
+private:
+ TypeHandle m_hndColorType;
+ MethodDesc* m_OleColorToSystemColorMD;
+ MethodDesc* m_SystemColorToOleColorMD;
+};
+
+#endif // FEATURE_COMINTEROP
+
+
+class EEMarshalingData
+{
+public:
+ EEMarshalingData(BaseDomain *pDomain, LoaderHeap *pHeap, CrstBase *pCrst);
+ ~EEMarshalingData();
+
+ // EEMarshalingData'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);
+
+ // This method returns the custom marshaling helper 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);
+
+#ifdef FEATURE_COMINTEROP
+ // This method retrieves OLE_COLOR marshaling info.
+ OleColorMarshalingInfo *GetOleColorMarshalingInfo();
+ UriMarshalingInfo *GetUriMarshalingInfo();
+ EventArgsMarshalingInfo *GetEventArgsMarshalingInfo();
+
+#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+ BOOL IsOleColorHelperMethod(MethodDesc *pMD)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pOleColorInfo != NULL && m_pOleColorInfo->IsOleColorHelperMethod(pMD);
+ }
+
+ BOOL IsUriHelperMethod(MethodDesc *pMD)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pUriInfo != NULL && m_pUriInfo->IsUriHelperMethod(pMD);
+ }
+
+ BOOL IsEventArgsHelperMethod(MethodDesc *pMD)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pEventArgsInfo != NULL && m_pEventArgsInfo->IsEventArgsHelperMethod(pMD);
+ }
+#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
+
+#endif // FEATURE_COMINTEROP
+
+private:
+#ifndef CROSSGEN_COMPILE
+ EECMHelperHashTable m_CMHelperHashtable;
+ EEPtrHashTable m_SharedCMHelperToCMInfoMap;
+#endif // CROSSGEN_COMPILE
+ LoaderHeap* m_pHeap;
+ BaseDomain* m_pDomain;
+ CMINFOLIST m_pCMInfoList;
+#ifdef FEATURE_COMINTEROP
+ OleColorMarshalingInfo* m_pOleColorInfo;
+ UriMarshalingInfo* m_pUriInfo;
+ EventArgsMarshalingInfo* m_pEventArgsInfo;
+#endif // FEATURE_COMINTEROP
+};
+
+struct ItfMarshalInfo;
+
+class MarshalInfo
+{
+public:
+ enum MarshalType
+ {
+#define DEFINE_MARSHALER_TYPE(mtype, mclass, fWinRTSupported) mtype,
+#include "mtypes.h"
+ MARSHAL_TYPE_UNKNOWN
+ };
+
+ enum MarshalScenario
+ {
+ MARSHAL_SCENARIO_NDIRECT,
+#ifdef FEATURE_COMINTEROP
+ MARSHAL_SCENARIO_COMINTEROP,
+ MARSHAL_SCENARIO_WINRT,
+#endif // FEATURE_COMINTEROP
+ MARSHAL_SCENARIO_FIELD
+ };
+
+private:
+
+public:
+ void *operator new(size_t size, void *pInPlace)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return pInPlace;
+ }
+
+ MarshalInfo(Module* pModule,
+ SigPointer sig,
+ const SigTypeContext *pTypeContext,
+ mdToken token,
+ MarshalScenario ms,
+ CorNativeLinkType nlType,
+ CorNativeLinkFlags nlFlags,
+ BOOL isParam,
+ UINT paramidx, // parameter # for use in error messages (ignored if not parameter)
+ UINT numArgs, // number of arguments. used to check SizeParamIndex is within valid range
+ BOOL BestFit,
+ BOOL ThrowOnUnmappableChar,
+ BOOL fEmitsIL,
+ MethodDesc* pMD = NULL,
+ BOOL fUseCustomMarshal = TRUE
+#ifdef _DEBUG
+ ,
+ LPCUTF8 pDebugName = NULL,
+ LPCUTF8 pDebugClassName = NULL,
+ UINT argidx = 0 // 0 for return value, -1 for field
+#endif
+
+ );
+
+ VOID EmitOrThrowInteropParamException(NDirectStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx);
+
+ // These methods retrieve the information for different element types.
+ HRESULT HandleArrayElemType(NativeTypeParamInfo *pParamInfo,
+ UINT16 optbaseoffset,
+ TypeHandle elemTypeHnd,
+ int iRank,
+ BOOL fNoLowerBounds,
+ BOOL isParam,
+ Assembly *pAssembly);
+
+ void GenerateArgumentIL(NDirectStubLinker* psl,
+ int argOffset, // the argument's index is m_paramidx + argOffset
+ UINT nativeStackOffset, // offset of the argument on the native stack
+ BOOL fMngToNative);
+
+ void GenerateReturnIL(NDirectStubLinker* psl,
+ int argOffset, // the argument's index is m_paramidx + argOffset
+ BOOL fMngToNative,
+ BOOL fieldGetter,
+ BOOL retval);
+
+ void SetupArgumentSizes();
+
+ UINT16 GetNativeArgSize()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_nativeArgSize;
+ }
+
+ MarshalType GetMarshalType()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_type;
+ }
+
+ BYTE GetBestFitMapping()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return ((m_BestFit == 0) ? 0 : 1);
+ }
+
+ BYTE GetThrowOnUnmappableChar()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return ((m_ThrowOnUnmappableChar == 0) ? 0 : 1);
+ }
+
+ BOOL IsFpuReturn()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_type == MARSHAL_TYPE_FLOAT || m_type == MARSHAL_TYPE_DOUBLE;
+ }
+
+ BOOL IsIn()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_in;
+ }
+
+ BOOL IsOut()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_out;
+ }
+
+ BOOL IsByRef()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_byref;
+ }
+
+ Module* GetModule()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pModule;
+ }
+
+ int GetArrayRank()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_iArrayRank;
+ }
+
+ BOOL GetNoLowerBounds()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_nolowerbounds;
+ }
+
+#ifdef FEATURE_COMINTEROP
+ void SetHiddenLengthParamIndex(UINT16 index)
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(m_hiddenLengthParamIndex == (UINT16)-1);
+ m_hiddenLengthParamIndex = index;
+ }
+
+ UINT16 HiddenLengthParamIndex()
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(m_hiddenLengthParamIndex != (UINT16)-1);
+ return m_hiddenLengthParamIndex;
+ }
+
+ DWORD GetHiddenLengthManagedHome()
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(m_dwHiddenLengthManagedHomeLocal != 0xFFFFFFFF);
+ return m_dwHiddenLengthManagedHomeLocal;
+ }
+
+ DWORD GetHiddenLengthNativeHome()
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(m_dwHiddenLengthNativeHomeLocal != 0xFFFFFFFF);
+ return m_dwHiddenLengthNativeHomeLocal;
+ }
+
+ MarshalType GetHiddenLengthParamMarshalType();
+ CorElementType GetHiddenLengthParamElementType();
+ UINT16 GetHiddenLengthParamStackSize();
+
+ void MarshalHiddenLengthArgument(NDirectStubLinker *psl, BOOL managedToNative, BOOL isForReturnArray);
+#endif // FEATURE_COMINTEROP
+
+ // used the same logic of tlbexp to check whether the argument of the method is a VarArg
+ BOOL IsOleVarArgCandidate()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_fOleVarArgCandidate; // m_fOleVarArgCandidate is set in the constructor method
+ }
+
+ void GetMops(CREATE_MARSHALER_CARRAY_OPERANDS* pMopsOut)
+ {
+ WRAPPER_NO_CONTRACT;
+ pMopsOut->methodTable = m_hndArrayElemType.AsMethodTable();
+ pMopsOut->elementType = m_arrayElementType;
+ pMopsOut->countParamIdx = m_countParamIdx;
+ pMopsOut->multiplier = m_multiplier;
+ pMopsOut->additive = m_additive;
+ pMopsOut->bestfitmapping = GetBestFitMapping();
+ pMopsOut->throwonunmappablechar = GetThrowOnUnmappableChar();
+ }
+
+ TypeHandle GetArrayElementTypeHandle()
+ {
+ return m_hndArrayElemType;
+ }
+
+#ifdef FEATURE_COMINTEROP
+ DispParamMarshaler *GenerateDispParamMarshaler();
+ DispatchWrapperType GetDispWrapperType();
+#endif // FEATURE_COMINTEROP
+
+ void GetItfMarshalInfo(ItfMarshalInfo* pInfo);
+
+ // Helper functions used to map the specified type to its interface marshalling info.
+ static void GetItfMarshalInfo(TypeHandle th, TypeHandle thItf, BOOL fDispItf, BOOL fInspItf, MarshalScenario ms, ItfMarshalInfo *pInfo);
+ static HRESULT TryGetItfMarshalInfo(TypeHandle th, BOOL fDispItf, BOOL fInspItf, ItfMarshalInfo *pInfo);
+
+ VOID MarshalTypeToString(SString& strMarshalType, BOOL fSizeIsSpecified);
+ static VOID VarTypeToString(VARTYPE vt, SString& strVarType);
+
+ // Returns true if the specified marshaler requires COM to have been started.
+ bool MarshalerRequiresCOM();
+
+ MethodDesc *GetMethodDesc()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pMD;
+ }
+
+ UINT GetParamIndex()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_paramidx;
+ }
+
+#ifdef FEATURE_COMINTEROP
+ BOOL IsWinRTScenario()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return m_ms == MarshalInfo::MARSHAL_SCENARIO_WINRT;
+ }
+#endif // FEATURE_COMINTEROP
+
+private:
+
+ UINT16 GetManagedSize(MarshalType mtype, MarshalScenario ms);
+ UINT16 GetNativeSize(MarshalType mtype, MarshalScenario ms);
+ static bool IsInOnly(MarshalType mtype);
+ static bool IsSupportedForWinRT(MarshalType mtype);
+
+ static OVERRIDEPROC GetArgumentOverrideProc(MarshalType mtype);
+ static RETURNOVERRIDEPROC GetReturnOverrideProc(MarshalType mtype);
+
+#ifdef _DEBUG
+ VOID DumpMarshalInfo(Module* pModule, SigPointer sig, const SigTypeContext *pTypeContext, mdToken token,
+ MarshalScenario ms, CorNativeLinkType nlType, CorNativeLinkFlags nlFlags);
+#endif
+
+private:
+ MarshalType m_type;
+ BOOL m_byref;
+ BOOL m_in;
+ BOOL m_out;
+ MethodTable* m_pMT; // Used if this is a true value type
+ MethodDesc* m_pMD; // Save MethodDesc for later inspection so that we can pass SizeParamIndex by ref
+ TypeHandle m_hndArrayElemType;
+ VARTYPE m_arrayElementType;
+ int m_iArrayRank;
+ BOOL m_nolowerbounds; // if managed type is SZARRAY, don't allow lower bounds
+
+ // for NT_ARRAY only
+ UINT32 m_multiplier; // multipler for "sizeis"
+ UINT32 m_additive; // additive for 'sizeis"
+ UINT16 m_countParamIdx; // index of "sizeis" parameter
+
+#ifdef FEATURE_COMINTEROP
+ // For NATIVE_TYPE_HIDDENLENGTHARRAY
+ UINT16 m_hiddenLengthParamIndex; // index of the injected hidden length parameter
+ DWORD m_dwHiddenLengthManagedHomeLocal; // home local for the managed hidden length parameter
+ DWORD m_dwHiddenLengthNativeHomeLocal; // home local for the native hidden length parameter
+
+ MethodTable* m_pDefaultItfMT; // WinRT default interface (if m_pMT is a class)
+#endif // FEATURE_COMINTEROP
+
+ UINT16 m_nativeArgSize;
+ UINT16 m_managedArgSize;
+
+ MarshalScenario m_ms;
+ BOOL m_fAnsi;
+ BOOL m_fDispItf;
+ BOOL m_fInspItf;
+#ifdef FEATURE_COMINTEROP
+ BOOL m_fErrorNativeType;
+#endif // FEATURE_COMINTEROP
+
+ // Information used by NT_CUSTOMMARSHALER.
+ CustomMarshalerHelper* m_pCMHelper;
+ VARTYPE m_CMVt;
+
+ OverrideProcArgs m_args;
+
+ UINT m_paramidx;
+ UINT m_resID; // resource ID for error message (if any)
+ BOOL m_BestFit;
+ BOOL m_ThrowOnUnmappableChar;
+
+ BOOL m_fOleVarArgCandidate; // indicate whether the arg is a candidate for vararg or not
+
+#if defined(_DEBUG)
+ LPCUTF8 m_strDebugMethName;
+ LPCUTF8 m_strDebugClassName;
+ UINT m_iArg; // 0 for return value, -1 for field
+#endif
+
+ Module* m_pModule;
+};
+
+
+
+//
+// Flags used to control the behavior of the ArrayMarshalInfo class.
+//
+
+enum ArrayMarshalInfoFlags
+{
+ amiRuntime = 0x0001,
+ amiExport32Bit = 0x0002,
+ amiExport64Bit = 0x0004,
+ amiIsPtr = 0x0008,
+ amiSafeArraySubTypeExplicitlySpecified = 0x0010
+};
+
+#define IsAMIRuntime(flags) (flags & amiRuntime)
+#define IsAMIExport(flags) (flags & (amiExport32Bit | amiExport64Bit))
+#define IsAMIExport32Bit(flags) (flags & amiExport32Bit)
+#define IsAMIExport64Bit(flags) (flags & amiExport64Bit)
+#define IsAMIPtr(flags) (flags & amiIsPtr)
+#define IsAMISafeArraySubTypeExplicitlySpecified(flags) (flags & amiSafeArraySubTypeExplicitlySpecified)
+//
+// Helper classes to determine the marshalling information for arrays.
+//
+
+class ArrayMarshalInfo
+{
+public:
+ ArrayMarshalInfo(ArrayMarshalInfoFlags flags)
+ : m_vtElement(VT_EMPTY)
+ , m_errorResourceId(0)
+ , m_flags(flags)
+#ifdef FEATURE_COMINTEROP
+ , m_redirectedTypeIndex((WinMDAdapter::RedirectedTypeIndex)0)
+ , m_cbElementSize(0)
+#endif // FEATURE_COMINTEROP
+ {
+ WRAPPER_NO_CONTRACT;
+ }
+
+ void InitForNativeArray(MarshalInfo::MarshalScenario ms, TypeHandle elemTypeHnd, CorNativeType elementNativeType, BOOL isAnsi);
+ void InitForFixedArray(TypeHandle elemTypeHnd, CorNativeType elementNativeType, BOOL isAnsi);
+
+#ifdef FEATURE_COMINTEROP
+ void InitForSafeArray(MarshalInfo::MarshalScenario ms, TypeHandle elemTypeHnd, VARTYPE elementVT, BOOL isAnsi);
+ void InitForHiddenLengthArray(TypeHandle elemTypeHnd);
+#endif // FEATURE_COMINTEROP
+
+ TypeHandle GetElementTypeHandle()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_thElement;
+ }
+
+ BOOL IsPtr()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return IsAMIPtr(m_flags);
+ }
+
+ VARTYPE GetElementVT()
+ {
+ LIMITED_METHOD_CONTRACT;
+ if ((IsAMIRuntime(m_flags) && IsAMIPtr(m_flags)) != 0)
+ {
+ // for the purpose of marshaling, we don't care about the inner
+ // type - we just marshal pointer-sized values
+ return (sizeof(LPVOID) == 4 ? VT_I4 : VT_I8);
+ }
+ else
+ {
+ return m_vtElement;
+ }
+ }
+
+ BOOL IsValid()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ return m_vtElement != VT_EMPTY;
+ }
+
+ BOOL IsSafeArraySubTypeExplicitlySpecified()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return IsAMISafeArraySubTypeExplicitlySpecified(m_flags);
+ }
+
+ DWORD GetErrorResourceId()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(!IsValid());
+ }
+ CONTRACTL_END;
+
+ return m_errorResourceId;
+ }
+
+#ifdef FEATURE_COMINTEROP
+ WinMDAdapter::RedirectedTypeIndex GetRedirectedTypeIndex()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_redirectedTypeIndex;
+ }
+
+ SIZE_T GetElementSize()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_cbElementSize;
+ }
+#endif // FEATURE_COMINTEROP
+
+protected:
+ // Helper function that does the actual work to figure out the element type handle and var type.
+ void InitElementInfo(CorNativeType arrayNativeType, MarshalInfo::MarshalScenario ms, TypeHandle elemTypeHnd, CorNativeType elementNativeType, BOOL isAnsi);
+
+ VARTYPE GetPointerSize()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ // If we are exporting, use the pointer size specified via the flags, otherwise use
+ // the current size of a pointer.
+ if (IsAMIExport32Bit(m_flags))
+ return 4;
+ else if (IsAMIExport64Bit(m_flags))
+ return 8;
+ else
+ return sizeof(LPVOID);
+ }
+
+protected:
+ TypeHandle m_thElement;
+ TypeHandle m_thInterfaceArrayElementClass;
+ VARTYPE m_vtElement;
+ DWORD m_errorResourceId;
+ ArrayMarshalInfoFlags m_flags;
+
+#ifdef FEATURE_COMINTEROP
+ WinMDAdapter::RedirectedTypeIndex m_redirectedTypeIndex;
+ SIZE_T m_cbElementSize;
+#endif // FEATURE_COMINTEROP
+};
+
+
+//===================================================================================
+// Throws an exception indicating a param has invalid element type / native type
+// information.
+//===================================================================================
+VOID ThrowInteropParamException(UINT resID, UINT paramIdx);
+
+VOID CollateParamTokens(IMDInternalImport *pInternalImport, mdMethodDef md, ULONG numargs, mdParamDef *aParams);
+bool IsUnsupportedValueTypeReturn(MetaSig& msig);
+
+void FindCopyCtor(Module *pModule, MethodTable *pMT, MethodDesc **pMDOut);
+void FindDtor(Module *pModule, MethodTable *pMT, MethodDesc **pMDOut);
+
+// We'll cap the total native size at a (somewhat) arbitrary limit to ensure
+// that we don't expose some overflow bug later on.
+#define MAX_SIZE_FOR_INTEROP 0x7ffffff0
+
+#endif // _MLINFO_H_