[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / mlinfo.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 //
5 // File: mlinfo.h
6 // 
7
8 // 
9
10
11 #include "stubgen.h"
12 #include "custommarshalerinfo.h"
13
14 #ifdef FEATURE_COMINTEROP
15 #include <windows.ui.xaml.h>
16 #endif
17
18 #ifndef _MLINFO_H_
19 #define _MLINFO_H_
20
21 #define NATIVE_TYPE_DEFAULT NATIVE_TYPE_MAX
22 #define VARIABLESIZE ((BYTE)(-1))
23
24
25 #ifdef FEATURE_COMINTEROP
26 class DispParamMarshaler;
27 #endif // FEATURE_COMINTEROP
28
29 #ifdef FEATURE_COMINTEROP
30 enum DispatchWrapperType
31 {
32     DispatchWrapperType_Unknown         = 0x00000001,
33     DispatchWrapperType_Dispatch        = 0x00000002,
34     //DispatchWrapperType_Record          = 0x00000004,
35     DispatchWrapperType_Error           = 0x00000008,
36     DispatchWrapperType_Currency        = 0x00000010,
37     DispatchWrapperType_BStr            = 0x00000020,
38     DispatchWrapperType_SafeArray       = 0x00010000
39 };
40 #endif // FEATURE_COMINTEROP
41
42 typedef enum
43 {
44     HANDLEASNORMAL  = 0,
45     OVERRIDDEN      = 1,
46     DISALLOWED      = 2,
47 } MarshalerOverrideStatus;
48
49
50 enum MarshalFlags
51 {
52     MARSHAL_FLAG_CLR_TO_NATIVE  = 0x01,
53     MARSHAL_FLAG_IN             = 0x02,
54     MARSHAL_FLAG_OUT            = 0x04,
55     MARSHAL_FLAG_BYREF          = 0x08,
56     MARSHAL_FLAG_HRESULT_SWAP   = 0x10,
57     MARSHAL_FLAG_RETVAL         = 0x20,
58     MARSHAL_FLAG_HIDDENLENPARAM = 0x40,
59 };
60
61 #include <pshpack1.h>
62 // Captures arguments for C array marshaling.
63 struct CREATE_MARSHALER_CARRAY_OPERANDS
64 {
65     MethodTable*    methodTable;
66     UINT32          multiplier;
67     UINT32          additive;
68     VARTYPE         elementType;
69     UINT16          countParamIdx;
70     BYTE            bestfitmapping;
71     BYTE            throwonunmappablechar;
72 };
73 #include <poppack.h>
74
75 struct OverrideProcArgs
76 {
77     class MarshalInfo*  m_pMarshalInfo;
78     
79     union 
80     {
81         MethodTable*        m_pMT;
82
83         struct
84         {
85             MethodTable*    m_pArrayMT;
86             VARTYPE         m_vt;
87 #ifdef FEATURE_COMINTEROP
88             SIZE_T          m_cbElementSize;
89             WinMDAdapter::RedirectedTypeIndex m_redirectedTypeIndex;
90 #endif // FEATURE_COMINTEROP
91         } na;
92
93         struct
94         {
95             MethodTable* m_pMT;
96             MethodDesc*  m_pCopyCtor;
97             MethodDesc*  m_pDtor;
98         } mm;
99
100         struct
101         {
102             MethodDesc* m_pMD;
103             mdToken     m_paramToken;
104             void*       m_hndManagedType; // TypeHandle cannot be a union member
105         } rcm;  // MARSHAL_TYPE_REFERENCECUSTOMMARSHALER
106
107     };
108 };
109
110 typedef MarshalerOverrideStatus (*OVERRIDEPROC)(NDirectStubLinker*    psl,
111                                                 BOOL                  byref,
112                                                 BOOL                  fin,
113                                                 BOOL                  fout,
114                                                 BOOL                  fManagedToNative,
115                                                 OverrideProcArgs*     pargs,
116                                                 UINT*                 pResID,
117                                                 UINT                  argidx,
118                                                 UINT                  nativeStackOffset);
119
120 typedef MarshalerOverrideStatus (*RETURNOVERRIDEPROC)(NDirectStubLinker*  psl,
121                                                       BOOL                fManagedToNative,
122                                                       BOOL                fHresultSwap,
123                                                       OverrideProcArgs*   pargs,
124                                                       UINT*               pResID);
125
126 //==========================================================================
127 // This structure contains the native type information for a given 
128 // parameter.
129 //==========================================================================
130 struct NativeTypeParamInfo
131 {
132     NativeTypeParamInfo()
133     : m_NativeType(NATIVE_TYPE_DEFAULT)
134     , m_ArrayElementType(NATIVE_TYPE_DEFAULT)
135     , m_SizeIsSpecified(FALSE)
136     , m_CountParamIdx(0)
137     , m_Multiplier(0)
138     , m_Additive(1)
139     , m_strCMMarshalerTypeName(NULL) 
140     , m_cCMMarshalerTypeNameBytes(0)
141     , m_strCMCookie(NULL)
142     , m_cCMCookieStrBytes(0)
143 #ifdef FEATURE_COMINTEROP
144     , m_SafeArrayElementVT(VT_EMPTY)
145     , m_strSafeArrayUserDefTypeName(NULL)
146     , m_cSafeArrayUserDefTypeNameBytes(0)
147     , m_IidParamIndex(-1)
148     , m_strInterfaceTypeName(NULL)
149     , m_cInterfaceTypeNameBytes(0)
150 #endif // FEATURE_COMINTEROP
151     {
152         LIMITED_METHOD_CONTRACT;
153     }   
154
155     // The native type of the parameter.
156     CorNativeType           m_NativeType;
157
158     // for NT_ARRAY only
159     CorNativeType           m_ArrayElementType; // The array element type.
160
161     BOOL                    m_SizeIsSpecified;  // used to do some validation
162     UINT16                  m_CountParamIdx;    // index of "sizeis" parameter
163     UINT32                  m_Multiplier;       // multipler for "sizeis"
164     UINT32                  m_Additive;         // additive for 'sizeis"
165
166     // For NT_CUSTOMMARSHALER only.
167     LPUTF8                  m_strCMMarshalerTypeName;
168     DWORD                   m_cCMMarshalerTypeNameBytes;
169     LPUTF8                  m_strCMCookie;
170     DWORD                   m_cCMCookieStrBytes;
171
172 #ifdef FEATURE_COMINTEROP
173     // For NT_SAFEARRAY only.
174     VARTYPE                 m_SafeArrayElementVT;
175     LPUTF8                  m_strSafeArrayUserDefTypeName;
176     DWORD                   m_cSafeArrayUserDefTypeNameBytes;
177
178     DWORD                   m_IidParamIndex;    // Capture iid_is syntax from IDL.
179
180     // for NATIVE_TYPE_SPECIFIED_INTERFACE
181     LPUTF8                  m_strInterfaceTypeName;
182     DWORD                   m_cInterfaceTypeNameBytes;
183 #endif // FEATURE_COMINTEROP
184 };
185
186 HRESULT CheckForCompressedData(PCCOR_SIGNATURE pvNativeTypeStart, PCCOR_SIGNATURE pvNativeType, ULONG cbNativeType);
187
188 BOOL ParseNativeTypeInfo(mdToken                    token,
189                          IMDInternalImport*         pScope,
190                          NativeTypeParamInfo*       pParamInfo);
191
192 void VerifyAndAdjustNormalizedType(
193                          Module *                   pModule,
194                          SigPointer                 sigPtr,
195                          const SigTypeContext *     pTypeContext,
196                          CorElementType *           pManagedElemType,
197                          CorNativeType *            pNativeType);
198
199 #ifdef FEATURE_COMINTEROP
200
201 class EventArgsMarshalingInfo
202 {
203 public:
204     // Constructor.
205     EventArgsMarshalingInfo();
206
207     // Destructor.
208     ~EventArgsMarshalingInfo();
209     
210     // EventArgsMarshalingInfo's are always allocated on the loader heap so we need to redefine
211     // the new and delete operators to ensure this.
212     void *operator new(size_t size, LoaderHeap *pHeap);
213     void operator delete(void *pMem);
214
215     // Accessors.
216     TypeHandle GetSystemNCCEventArgsType()
217     {
218         LIMITED_METHOD_CONTRACT;
219         return m_hndSystemNCCEventArgsType;
220     }
221
222     TypeHandle GetSystemPCEventArgsType()
223     {
224         LIMITED_METHOD_CONTRACT;
225         return m_hndSystemPCEventArgsType;
226     }
227
228     MethodDesc *GetSystemNCCEventArgsToWinRTNCCEventArgsMD()
229     {
230         LIMITED_METHOD_CONTRACT;
231         return m_pSystemNCCEventArgsToWinRTNCCEventArgsMD;
232     }
233
234     MethodDesc *GetWinRTNCCEventArgsToSystemNCCEventArgsMD()
235     {
236         LIMITED_METHOD_CONTRACT;
237         return m_pWinRTNCCEventArgsToSystemNCCEventArgsMD;
238     }
239
240     MethodDesc *GetSystemPCEventArgsToWinRTPCEventArgsMD()
241     {
242         LIMITED_METHOD_CONTRACT;
243         return m_pSystemPCEventArgsToWinRTPCEventArgsMD;
244     }
245
246     MethodDesc *GetWinRTPCEventArgsToSystemPCEventArgsMD()
247     {
248         LIMITED_METHOD_CONTRACT;
249         return m_pWinRTPCEventArgsToSystemPCEventArgsMD;
250     }
251
252
253 private:
254     TypeHandle m_hndSystemNCCEventArgsType;
255     TypeHandle m_hndSystemPCEventArgsType;
256
257     MethodDesc *m_pSystemNCCEventArgsToWinRTNCCEventArgsMD;
258     MethodDesc *m_pWinRTNCCEventArgsToSystemNCCEventArgsMD;
259     MethodDesc *m_pSystemPCEventArgsToWinRTPCEventArgsMD;
260     MethodDesc *m_pWinRTPCEventArgsToSystemPCEventArgsMD;
261 };
262
263 class UriMarshalingInfo
264 {
265 public:
266     // Constructor.
267     UriMarshalingInfo();
268     
269     // Destructor
270     ~UriMarshalingInfo();
271     
272     // UriMarshalingInfo's are always allocated on the loader heap so we need to redefine
273     // the new and delete operators to ensure this.
274     void *operator new(size_t size, LoaderHeap *pHeap);
275     void operator delete(void *pMem);
276
277     // Accessors.
278     TypeHandle GetSystemUriType()
279     {
280         LIMITED_METHOD_CONTRACT;
281         return m_hndSystemUriType;
282     }
283
284     ABI::Windows::Foundation::IUriRuntimeClassFactory* GetUriFactory()
285     {
286         CONTRACTL
287         {
288             THROWS;
289             GC_TRIGGERS;    // For potential COOP->PREEMP->COOP switch
290             MODE_ANY;
291             PRECONDITION(!GetAppDomain()->IsCompilationDomain()); 
292         }
293         CONTRACTL_END;   
294
295         if (m_pUriFactory.Load() == NULL)
296         {
297             GCX_PREEMP();
298
299             SafeComHolderPreemp<ABI::Windows::Foundation::IUriRuntimeClassFactory> pUriFactory;
300
301             // IUriRuntimeClassFactory: 44A9796F-723E-4FDF-A218-033E75B0C084
302             IfFailThrow(clr::winrt::GetActivationFactory(g_WinRTUriClassNameW, (ABI::Windows::Foundation::IUriRuntimeClassFactory **)&pUriFactory));
303             _ASSERTE_MSG(pUriFactory, "Got Null Uri factory!");
304
305             if (InterlockedCompareExchangeT(&m_pUriFactory, (ABI::Windows::Foundation::IUriRuntimeClassFactory *) pUriFactory, NULL) == NULL)
306                 pUriFactory.SuppressRelease();            
307         }
308         
309         return m_pUriFactory;
310     }
311
312     MethodDesc *GetSystemUriCtorMD()
313     {
314         LIMITED_METHOD_CONTRACT;
315         return m_SystemUriCtorMD;
316     }
317
318     MethodDesc *GetSystemUriOriginalStringMD()
319     {
320         LIMITED_METHOD_CONTRACT;
321         return m_SystemUriOriginalStringGetterMD;
322     }
323
324
325 private:
326     TypeHandle m_hndSystemUriType;
327
328     MethodDesc* m_SystemUriCtorMD;
329     MethodDesc* m_SystemUriOriginalStringGetterMD;
330
331     VolatilePtr<ABI::Windows::Foundation::IUriRuntimeClassFactory> m_pUriFactory;
332 };
333
334 class OleColorMarshalingInfo
335 {
336 public:
337     // Constructor.
338     OleColorMarshalingInfo();
339
340     // OleColorMarshalingInfo's are always allocated on the loader heap so we need to redefine
341     // the new and delete operators to ensure this.
342     void *operator new(size_t size, LoaderHeap *pHeap);
343     void operator delete(void *pMem);
344
345     // Accessors.
346     TypeHandle GetColorType()
347     {
348         LIMITED_METHOD_CONTRACT;
349         return m_hndColorType;
350     }
351     MethodDesc *GetOleColorToSystemColorMD()
352     {
353         LIMITED_METHOD_CONTRACT;
354         return m_OleColorToSystemColorMD;
355     }
356     MethodDesc *GetSystemColorToOleColorMD()
357     {
358         LIMITED_METHOD_CONTRACT;
359         return m_SystemColorToOleColorMD;
360     }
361
362
363 private:
364     TypeHandle  m_hndColorType;
365     MethodDesc* m_OleColorToSystemColorMD;
366     MethodDesc* m_SystemColorToOleColorMD;
367 };
368
369 #endif // FEATURE_COMINTEROP
370
371
372 class EEMarshalingData
373 {
374 public:
375     EEMarshalingData(LoaderAllocator *pAllocator, CrstBase *pCrst);
376     ~EEMarshalingData();
377
378     // EEMarshalingData's are always allocated on the loader heap so we need to redefine
379     // the new and delete operators to ensure this.
380     void *operator new(size_t size, LoaderHeap *pHeap);
381     void operator delete(void *pMem);
382
383     // This method returns the custom marshaling helper associated with the name cookie pair. If the 
384     // CM info has not been created yet for this pair then it will be created and returned.
385     CustomMarshalerHelper *GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes);
386
387     // This method returns the custom marshaling info associated with shared CM helper.
388     CustomMarshalerInfo *GetCustomMarshalerInfo(SharedCustomMarshalerHelper *pSharedCMHelper);
389
390 #ifdef FEATURE_COMINTEROP
391     // This method retrieves OLE_COLOR marshaling info.
392     OleColorMarshalingInfo *GetOleColorMarshalingInfo();
393     UriMarshalingInfo *GetUriMarshalingInfo();
394     EventArgsMarshalingInfo *GetEventArgsMarshalingInfo();
395
396
397 #endif // FEATURE_COMINTEROP
398
399 private:
400 #ifndef CROSSGEN_COMPILE
401     EECMHelperHashTable                 m_CMHelperHashtable;
402     EEPtrHashTable                      m_SharedCMHelperToCMInfoMap;
403 #endif // CROSSGEN_COMPILE
404     LoaderAllocator*                    m_pAllocator;
405     LoaderHeap*                         m_pHeap;
406     CMINFOLIST                          m_pCMInfoList;
407 #ifdef FEATURE_COMINTEROP
408     OleColorMarshalingInfo*             m_pOleColorInfo;
409     UriMarshalingInfo*                  m_pUriInfo;
410     EventArgsMarshalingInfo*            m_pEventArgsInfo;
411 #endif // FEATURE_COMINTEROP
412     CrstBase*                           m_lock;
413 };
414
415 struct ItfMarshalInfo;
416
417 class MarshalInfo
418 {
419 public:
420     enum MarshalType
421     {
422 #define DEFINE_MARSHALER_TYPE(mtype, mclass, fWinRTSupported) mtype,
423 #include "mtypes.h"
424         MARSHAL_TYPE_UNKNOWN
425     };
426
427     enum MarshalScenario
428     {
429         MARSHAL_SCENARIO_NDIRECT,
430 #ifdef FEATURE_COMINTEROP
431         MARSHAL_SCENARIO_COMINTEROP,
432         MARSHAL_SCENARIO_WINRT,
433 #endif // FEATURE_COMINTEROP
434         MARSHAL_SCENARIO_FIELD
435     };
436
437 private:
438
439 public:
440     void *operator new(size_t size, void *pInPlace)
441     {
442         LIMITED_METHOD_CONTRACT;
443         return pInPlace;
444     }
445
446     MarshalInfo(Module* pModule,
447                 SigPointer sig,
448                 const SigTypeContext *pTypeContext,
449                 mdToken token,
450                 MarshalScenario ms,
451                 CorNativeLinkType nlType,
452                 CorNativeLinkFlags nlFlags,
453                 BOOL isParam,
454                 UINT paramidx,          // parameter # for use in error messages (ignored if not parameter)
455                 UINT numArgs,           // number of arguments. used to check SizeParamIndex is within valid range
456                 BOOL BestFit,
457                 BOOL ThrowOnUnmappableChar,
458                 BOOL fEmitsIL,
459                 BOOL onInstanceMethod,
460                 MethodDesc* pMD = NULL,
461                 BOOL fUseCustomMarshal = TRUE
462 #ifdef _DEBUG
463                 ,
464                 LPCUTF8 pDebugName = NULL,
465                 LPCUTF8 pDebugClassName = NULL,
466                 UINT    argidx = 0  // 0 for return value, -1 for field
467 #endif
468
469                 );
470
471     VOID EmitOrThrowInteropParamException(NDirectStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx);
472
473     // These methods retrieve the information for different element types.
474     HRESULT HandleArrayElemType(NativeTypeParamInfo *pParamInfo,
475                                 TypeHandle elemTypeHnd, 
476                                 int iRank, 
477                                 BOOL fNoLowerBounds, 
478                                 BOOL isParam, 
479                                 Assembly *pAssembly);
480
481     void GenerateArgumentIL(NDirectStubLinker* psl,
482                             int argOffset, // the argument's index is m_paramidx + argOffset
483                             UINT nativeStackOffset, // offset of the argument on the native stack
484                             BOOL fMngToNative);
485     
486     void GenerateReturnIL(NDirectStubLinker* psl,
487                           int argOffset, // the argument's index is m_paramidx + argOffset
488                           BOOL fMngToNative,
489                           BOOL fieldGetter,
490                           BOOL retval);
491     
492     void SetupArgumentSizes();
493
494     UINT16 GetNativeArgSize()
495     {
496         LIMITED_METHOD_CONTRACT;
497         return m_nativeArgSize;
498     }
499
500     MarshalType GetMarshalType()
501     {
502         LIMITED_METHOD_CONTRACT;
503         return m_type;
504     }
505
506     BYTE    GetBestFitMapping()
507     {
508         LIMITED_METHOD_CONTRACT;
509         return ((m_BestFit == 0) ? 0 : 1);
510     }
511     
512     BYTE    GetThrowOnUnmappableChar()
513     {
514         LIMITED_METHOD_CONTRACT;
515         return ((m_ThrowOnUnmappableChar == 0) ? 0 : 1);
516     }
517
518     BOOL   IsFpuReturn()
519     {
520         LIMITED_METHOD_CONTRACT;
521         return m_type == MARSHAL_TYPE_FLOAT || m_type == MARSHAL_TYPE_DOUBLE;
522     }
523
524     BOOL   IsIn()
525     {
526         LIMITED_METHOD_CONTRACT;
527         return m_in;
528     }
529
530     BOOL   IsOut()
531     {
532         LIMITED_METHOD_CONTRACT;
533         return m_out;
534     }
535
536     BOOL   IsByRef()
537     {
538         LIMITED_METHOD_CONTRACT;
539         return m_byref;
540     }
541
542     Module* GetModule()
543     {
544         LIMITED_METHOD_CONTRACT;
545         return m_pModule;
546     }
547
548     int GetArrayRank()
549     {
550         LIMITED_METHOD_CONTRACT;
551         return m_iArrayRank;
552     }
553
554     BOOL GetNoLowerBounds()
555     {
556         LIMITED_METHOD_CONTRACT;
557         return m_nolowerbounds;
558     }
559
560 #ifdef FEATURE_COMINTEROP
561     void SetHiddenLengthParamIndex(UINT16 index)
562     {
563         LIMITED_METHOD_CONTRACT;
564         _ASSERTE(m_hiddenLengthParamIndex == (UINT16)-1);
565         m_hiddenLengthParamIndex = index;
566     }
567
568     UINT16 HiddenLengthParamIndex()
569     {
570         LIMITED_METHOD_CONTRACT;
571         _ASSERTE(m_hiddenLengthParamIndex != (UINT16)-1);
572         return m_hiddenLengthParamIndex;
573     }
574
575     DWORD GetHiddenLengthManagedHome()
576     {
577         LIMITED_METHOD_CONTRACT;
578         _ASSERTE(m_dwHiddenLengthManagedHomeLocal != 0xFFFFFFFF);
579         return m_dwHiddenLengthManagedHomeLocal;
580     }
581
582     DWORD GetHiddenLengthNativeHome()
583     {
584         LIMITED_METHOD_CONTRACT;
585         _ASSERTE(m_dwHiddenLengthNativeHomeLocal != 0xFFFFFFFF);
586         return m_dwHiddenLengthNativeHomeLocal;
587     }
588
589     MarshalType GetHiddenLengthParamMarshalType();
590     CorElementType GetHiddenLengthParamElementType();
591     UINT16      GetHiddenLengthParamStackSize();
592
593     void MarshalHiddenLengthArgument(NDirectStubLinker *psl, BOOL managedToNative, BOOL isForReturnArray);
594 #endif // FEATURE_COMINTEROP
595
596     // used the same logic of tlbexp to check whether the argument of the method is a VarArg
597     BOOL IsOleVarArgCandidate()
598     {
599         LIMITED_METHOD_CONTRACT;
600         return m_fOleVarArgCandidate; // m_fOleVarArgCandidate is set in the constructor method
601     }
602
603     void GetMops(CREATE_MARSHALER_CARRAY_OPERANDS* pMopsOut)
604     {
605         WRAPPER_NO_CONTRACT;
606         pMopsOut->methodTable = m_hndArrayElemType.AsMethodTable();
607         pMopsOut->elementType = m_arrayElementType;
608         pMopsOut->countParamIdx = m_countParamIdx;
609         pMopsOut->multiplier  = m_multiplier;
610         pMopsOut->additive    = m_additive;
611         pMopsOut->bestfitmapping = GetBestFitMapping();
612         pMopsOut->throwonunmappablechar = GetThrowOnUnmappableChar();
613     }
614
615     TypeHandle GetArrayElementTypeHandle()
616     {
617         return m_hndArrayElemType;
618     }
619
620 #ifdef FEATURE_COMINTEROP
621     DispParamMarshaler *GenerateDispParamMarshaler();
622     DispatchWrapperType GetDispWrapperType();
623 #endif // FEATURE_COMINTEROP
624
625     void GetItfMarshalInfo(ItfMarshalInfo* pInfo);
626
627     // Helper functions used to map the specified type to its interface marshalling info.
628     static void GetItfMarshalInfo(TypeHandle th, TypeHandle thItf, BOOL fDispItf, BOOL fInspItf, MarshalScenario ms, ItfMarshalInfo *pInfo);
629     static HRESULT TryGetItfMarshalInfo(TypeHandle th, BOOL fDispItf, BOOL fInspItf, ItfMarshalInfo *pInfo);
630
631     VOID MarshalTypeToString(SString& strMarshalType, BOOL fSizeIsSpecified);
632     static VOID VarTypeToString(VARTYPE vt, SString& strVarType);
633
634     // Returns true if the specified marshaler requires COM to have been started.
635     bool MarshalerRequiresCOM();
636
637     MethodDesc *GetMethodDesc()
638     {
639         LIMITED_METHOD_CONTRACT;
640         return m_pMD;    
641     }
642
643     UINT GetParamIndex()
644     {
645         LIMITED_METHOD_CONTRACT;
646         return m_paramidx;
647     }
648
649 #ifdef FEATURE_COMINTEROP    
650     BOOL IsWinRTScenario()
651     {
652         LIMITED_METHOD_CONTRACT;
653
654         return m_ms == MarshalInfo::MARSHAL_SCENARIO_WINRT;
655     }
656 #endif // FEATURE_COMINTEROP
657
658 private:
659
660     UINT16                      GetManagedSize(MarshalType mtype, MarshalScenario ms);
661     UINT16                      GetNativeSize(MarshalType mtype, MarshalScenario ms);
662     static bool                 IsInOnly(MarshalType mtype);
663     static bool                 IsSupportedForWinRT(MarshalType mtype);
664
665     static OVERRIDEPROC         GetArgumentOverrideProc(MarshalType mtype);
666     static RETURNOVERRIDEPROC   GetReturnOverrideProc(MarshalType mtype);
667     
668 #ifdef _DEBUG
669     VOID DumpMarshalInfo(Module* pModule, SigPointer sig, const SigTypeContext *pTypeContext, mdToken token,
670                          MarshalScenario ms, CorNativeLinkType nlType, CorNativeLinkFlags nlFlags);
671 #endif
672
673 private:
674     MarshalType     m_type;
675     BOOL            m_byref;
676     BOOL            m_in;
677     BOOL            m_out;
678     MethodTable*    m_pMT;  // Used if this is a true value type
679     MethodDesc*     m_pMD;  // Save MethodDesc for later inspection so that we can pass SizeParamIndex by ref    
680     TypeHandle      m_hndArrayElemType;
681     VARTYPE         m_arrayElementType;
682     int             m_iArrayRank;
683     BOOL            m_nolowerbounds;  // if managed type is SZARRAY, don't allow lower bounds
684
685     // for NT_ARRAY only
686     UINT32          m_multiplier;     // multipler for "sizeis"
687     UINT32          m_additive;       // additive for 'sizeis"
688     UINT16          m_countParamIdx;  // index of "sizeis" parameter
689
690 #ifdef FEATURE_COMINTEROP
691     // For NATIVE_TYPE_HIDDENLENGTHARRAY
692     UINT16          m_hiddenLengthParamIndex;           // index of the injected hidden length parameter
693     DWORD           m_dwHiddenLengthManagedHomeLocal;   // home local for the managed hidden length parameter
694     DWORD           m_dwHiddenLengthNativeHomeLocal;    // home local for the native hidden length parameter
695
696     MethodTable*    m_pDefaultItfMT;                    // WinRT default interface (if m_pMT is a class)
697 #endif // FEATURE_COMINTEROP
698
699     UINT16          m_nativeArgSize;
700     UINT16          m_managedArgSize;
701
702     MarshalScenario m_ms;
703     BOOL            m_fAnsi;
704     BOOL            m_fDispItf;
705     BOOL            m_fInspItf;
706 #ifdef FEATURE_COMINTEROP
707     BOOL            m_fErrorNativeType;
708 #endif // FEATURE_COMINTEROP
709
710     // Information used by NT_CUSTOMMARSHALER.
711     CustomMarshalerHelper* m_pCMHelper;
712     VARTYPE         m_CMVt;
713
714     OverrideProcArgs  m_args;
715
716     UINT            m_paramidx;
717     UINT            m_resID;     // resource ID for error message (if any)
718     BOOL            m_BestFit;
719     BOOL            m_ThrowOnUnmappableChar;
720
721     BOOL            m_fOleVarArgCandidate; // indicate whether the arg is a candidate for vararg or not
722
723 #if defined(_DEBUG)
724     LPCUTF8         m_strDebugMethName;
725     LPCUTF8         m_strDebugClassName;
726     UINT            m_iArg;  // 0 for return value, -1 for field
727 #endif
728
729     Module*         m_pModule;
730 };
731
732
733
734 //
735 // Flags used to control the behavior of the ArrayMarshalInfo class.
736 //
737
738 enum ArrayMarshalInfoFlags
739 {
740     amiRuntime                                  = 0x0001,
741     amiExport32Bit                              = 0x0002,
742     amiExport64Bit                              = 0x0004,
743     amiIsPtr                                    = 0x0008,
744     amiSafeArraySubTypeExplicitlySpecified      = 0x0010
745 };
746
747 #define IsAMIRuntime(flags) (flags & amiRuntime)
748 #define IsAMIExport(flags) (flags & (amiExport32Bit | amiExport64Bit))
749 #define IsAMIExport32Bit(flags) (flags & amiExport32Bit)
750 #define IsAMIExport64Bit(flags) (flags & amiExport64Bit)
751 #define IsAMIPtr(flags) (flags & amiIsPtr)
752 #define IsAMISafeArraySubTypeExplicitlySpecified(flags) (flags & amiSafeArraySubTypeExplicitlySpecified)
753 //
754 // Helper classes to determine the marshalling information for arrays.
755 //
756
757 class ArrayMarshalInfo
758 {
759 public:
760     ArrayMarshalInfo(ArrayMarshalInfoFlags flags)
761     : m_vtElement(VT_EMPTY) 
762     , m_errorResourceId(0) 
763     , m_flags(flags)
764 #ifdef FEATURE_COMINTEROP
765     , m_redirectedTypeIndex((WinMDAdapter::RedirectedTypeIndex)0)
766     , m_cbElementSize(0)
767 #endif // FEATURE_COMINTEROP
768     {   
769         WRAPPER_NO_CONTRACT;
770     }
771
772     void InitForNativeArray(MarshalInfo::MarshalScenario ms, TypeHandle elemTypeHnd, CorNativeType elementNativeType, BOOL isAnsi);
773     void InitForFixedArray(TypeHandle elemTypeHnd, CorNativeType elementNativeType, BOOL isAnsi);
774
775 #ifdef FEATURE_COMINTEROP    
776     void InitForSafeArray(MarshalInfo::MarshalScenario ms, TypeHandle elemTypeHnd, VARTYPE elementVT, BOOL isAnsi);
777     void InitForHiddenLengthArray(TypeHandle elemTypeHnd);
778 #endif // FEATURE_COMINTEROP
779     
780     TypeHandle GetElementTypeHandle()
781     {
782         LIMITED_METHOD_CONTRACT;
783         return m_thElement;    
784     }
785
786     BOOL IsPtr()
787     {
788         LIMITED_METHOD_CONTRACT;
789         return IsAMIPtr(m_flags);
790     }
791
792     VARTYPE GetElementVT()
793     {
794         LIMITED_METHOD_CONTRACT;
795         if ((IsAMIRuntime(m_flags) && IsAMIPtr(m_flags)) != 0)
796         {
797             // for the purpose of marshaling, we don't care about the inner
798             // type - we just marshal pointer-sized values
799             return (sizeof(LPVOID) == 4 ? VT_I4 : VT_I8);
800         }
801         else
802         {
803             return m_vtElement;
804         }
805     }
806
807     BOOL IsValid()
808     {
809         CONTRACTL
810         {
811             NOTHROW;
812             GC_NOTRIGGER;
813             MODE_ANY;
814         }
815         CONTRACTL_END;        
816         
817         return m_vtElement != VT_EMPTY;
818     }
819
820     BOOL IsSafeArraySubTypeExplicitlySpecified()
821     {
822         LIMITED_METHOD_CONTRACT;
823         
824         return IsAMISafeArraySubTypeExplicitlySpecified(m_flags);
825     }
826     
827     DWORD GetErrorResourceId()
828     {
829         CONTRACTL
830         {
831             NOTHROW;
832             GC_NOTRIGGER;
833             MODE_ANY;
834             PRECONDITION(!IsValid());
835         }
836         CONTRACTL_END;        
837     
838         return m_errorResourceId;
839     }
840
841 #ifdef FEATURE_COMINTEROP
842     WinMDAdapter::RedirectedTypeIndex GetRedirectedTypeIndex()
843     {
844         LIMITED_METHOD_CONTRACT;
845         return m_redirectedTypeIndex;
846     }
847
848     SIZE_T GetElementSize()
849     {
850         LIMITED_METHOD_CONTRACT;
851         return m_cbElementSize;
852     }
853 #endif // FEATURE_COMINTEROP
854
855 protected:    
856     // Helper function that does the actual work to figure out the element type handle and var type.    
857     void InitElementInfo(CorNativeType arrayNativeType, MarshalInfo::MarshalScenario ms, TypeHandle elemTypeHnd, CorNativeType elementNativeType, BOOL isAnsi);
858
859     VARTYPE GetPointerSize()
860     {
861         LIMITED_METHOD_CONTRACT;
862
863         // If we are exporting, use the pointer size specified via the flags, otherwise use
864         // the current size of a pointer.
865         if (IsAMIExport32Bit(m_flags))
866             return 4;
867         else if (IsAMIExport64Bit(m_flags))
868             return 8;
869         else 
870             return sizeof(LPVOID);
871     }
872
873 protected:
874     TypeHandle m_thElement;
875     TypeHandle m_thInterfaceArrayElementClass;
876     VARTYPE m_vtElement;
877     DWORD m_errorResourceId;
878     ArrayMarshalInfoFlags m_flags;
879
880 #ifdef FEATURE_COMINTEROP    
881     WinMDAdapter::RedirectedTypeIndex m_redirectedTypeIndex;
882     SIZE_T m_cbElementSize;
883 #endif // FEATURE_COMINTEROP
884 };
885
886
887 //===================================================================================
888 // Throws an exception indicating a param has invalid element type / native type
889 // information.
890 //===================================================================================
891 VOID ThrowInteropParamException(UINT resID, UINT paramIdx);
892
893 VOID CollateParamTokens(IMDInternalImport *pInternalImport, mdMethodDef md, ULONG numargs, mdParamDef *aParams);
894 bool IsUnsupportedTypedrefReturn(MetaSig& msig);
895
896 void FindCopyCtor(Module *pModule, MethodTable *pMT, MethodDesc **pMDOut);
897 void FindDtor(Module *pModule, MethodTable *pMT, MethodDesc **pMDOut);
898
899 // We'll cap the total native size at a (somewhat) arbitrary limit to ensure
900 // that we don't expose some overflow bug later on.
901 #define MAX_SIZE_FOR_INTEROP    0x7ffffff0
902
903 #endif // _MLINFO_H_