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
26class DispParamMarshaler;
27#endif // FEATURE_COMINTEROP
28
29#ifdef FEATURE_COMINTEROP
30enum 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
42typedef enum
43{
44 HANDLEASNORMAL = 0,
45 OVERRIDDEN = 1,
46 DISALLOWED = 2,
47} MarshalerOverrideStatus;
48
49
50enum 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.
63struct 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
75struct OverrideProcArgs
76{
77 class MarshalInfo* m_pMarshalInfo;
78
79 union
80 {
81 MethodTable* m_pMT;
82
83 struct
84 {
85 VARTYPE m_vt;
86 UINT16 m_optionalbaseoffset; //for fast marshaling, offset of dataptr if known and less than 64k (0 otherwise)
87 MethodTable* m_pMT;
88#ifdef FEATURE_COMINTEROP
89 SIZE_T m_cbElementSize;
90 WinMDAdapter::RedirectedTypeIndex m_redirectedTypeIndex;
91#endif // FEATURE_COMINTEROP
92 } na;
93
94 struct
95 {
96 MethodTable* m_pMT;
97 MethodDesc* m_pCopyCtor;
98 MethodDesc* m_pDtor;
99 } mm;
100
101 struct
102 {
103 MethodDesc* m_pMD;
104 mdToken m_paramToken;
105 void* m_hndManagedType; // TypeHandle cannot be a union member
106 } rcm; // MARSHAL_TYPE_REFERENCECUSTOMMARSHALER
107
108 };
109};
110
111typedef MarshalerOverrideStatus (*OVERRIDEPROC)(NDirectStubLinker* psl,
112 BOOL byref,
113 BOOL fin,
114 BOOL fout,
115 BOOL fManagedToNative,
116 OverrideProcArgs* pargs,
117 UINT* pResID,
118 UINT argidx,
119 UINT nativeStackOffset);
120
121typedef MarshalerOverrideStatus (*RETURNOVERRIDEPROC)(NDirectStubLinker* psl,
122 BOOL fManagedToNative,
123 BOOL fHresultSwap,
124 OverrideProcArgs* pargs,
125 UINT* pResID);
126
127//==========================================================================
128// This structure contains the native type information for a given
129// parameter.
130//==========================================================================
131struct NativeTypeParamInfo
132{
133 NativeTypeParamInfo()
134 : m_NativeType(NATIVE_TYPE_DEFAULT)
135 , m_ArrayElementType(NATIVE_TYPE_DEFAULT)
136 , m_SizeIsSpecified(FALSE)
137 , m_CountParamIdx(0)
138 , m_Multiplier(0)
139 , m_Additive(1)
140 , m_strCMMarshalerTypeName(NULL)
141 , m_cCMMarshalerTypeNameBytes(0)
142 , m_strCMCookie(NULL)
143 , m_cCMCookieStrBytes(0)
144#ifdef FEATURE_COMINTEROP
145 , m_SafeArrayElementVT(VT_EMPTY)
146 , m_strSafeArrayUserDefTypeName(NULL)
147 , m_cSafeArrayUserDefTypeNameBytes(0)
148 , m_IidParamIndex(-1)
149 , m_strInterfaceTypeName(NULL)
150 , m_cInterfaceTypeNameBytes(0)
151#endif // FEATURE_COMINTEROP
152 {
153 LIMITED_METHOD_CONTRACT;
154 }
155
156 // The native type of the parameter.
157 CorNativeType m_NativeType;
158
159 // for NT_ARRAY only
160 CorNativeType m_ArrayElementType; // The array element type.
161
162 BOOL m_SizeIsSpecified; // used to do some validation
163 UINT16 m_CountParamIdx; // index of "sizeis" parameter
164 UINT32 m_Multiplier; // multipler for "sizeis"
165 UINT32 m_Additive; // additive for 'sizeis"
166
167 // For NT_CUSTOMMARSHALER only.
168 LPUTF8 m_strCMMarshalerTypeName;
169 DWORD m_cCMMarshalerTypeNameBytes;
170 LPUTF8 m_strCMCookie;
171 DWORD m_cCMCookieStrBytes;
172
173#ifdef FEATURE_COMINTEROP
174 // For NT_SAFEARRAY only.
175 VARTYPE m_SafeArrayElementVT;
176 LPUTF8 m_strSafeArrayUserDefTypeName;
177 DWORD m_cSafeArrayUserDefTypeNameBytes;
178
179 DWORD m_IidParamIndex; // Capture iid_is syntax from IDL.
180
181 // for NATIVE_TYPE_SPECIFIED_INTERFACE
182 LPUTF8 m_strInterfaceTypeName;
183 DWORD m_cInterfaceTypeNameBytes;
184#endif // FEATURE_COMINTEROP
185};
186
187HRESULT CheckForCompressedData(PCCOR_SIGNATURE pvNativeTypeStart, PCCOR_SIGNATURE pvNativeType, ULONG cbNativeType);
188
189BOOL ParseNativeTypeInfo(mdToken token,
190 IMDInternalImport* pScope,
191 NativeTypeParamInfo* pParamInfo);
192
193void VerifyAndAdjustNormalizedType(
194 Module * pModule,
195 SigPointer sigPtr,
196 const SigTypeContext * pTypeContext,
197 CorElementType * pManagedElemType,
198 CorNativeType * pNativeType);
199
200#ifdef FEATURE_COMINTEROP
201
202class EventArgsMarshalingInfo
203{
204public:
205 // Constructor.
206 EventArgsMarshalingInfo();
207
208 // Destructor.
209 ~EventArgsMarshalingInfo();
210
211 // EventArgsMarshalingInfo's are always allocated on the loader heap so we need to redefine
212 // the new and delete operators to ensure this.
213 void *operator new(size_t size, LoaderHeap *pHeap);
214 void operator delete(void *pMem);
215
216 // Accessors.
217 TypeHandle GetSystemNCCEventArgsType()
218 {
219 LIMITED_METHOD_CONTRACT;
220 return m_hndSystemNCCEventArgsType;
221 }
222
223 TypeHandle GetSystemPCEventArgsType()
224 {
225 LIMITED_METHOD_CONTRACT;
226 return m_hndSystemPCEventArgsType;
227 }
228
229 MethodDesc *GetSystemNCCEventArgsToWinRTNCCEventArgsMD()
230 {
231 LIMITED_METHOD_CONTRACT;
232 return m_pSystemNCCEventArgsToWinRTNCCEventArgsMD;
233 }
234
235 MethodDesc *GetWinRTNCCEventArgsToSystemNCCEventArgsMD()
236 {
237 LIMITED_METHOD_CONTRACT;
238 return m_pWinRTNCCEventArgsToSystemNCCEventArgsMD;
239 }
240
241 MethodDesc *GetSystemPCEventArgsToWinRTPCEventArgsMD()
242 {
243 LIMITED_METHOD_CONTRACT;
244 return m_pSystemPCEventArgsToWinRTPCEventArgsMD;
245 }
246
247 MethodDesc *GetWinRTPCEventArgsToSystemPCEventArgsMD()
248 {
249 LIMITED_METHOD_CONTRACT;
250 return m_pWinRTPCEventArgsToSystemPCEventArgsMD;
251 }
252
253
254private:
255 TypeHandle m_hndSystemNCCEventArgsType;
256 TypeHandle m_hndSystemPCEventArgsType;
257
258 MethodDesc *m_pSystemNCCEventArgsToWinRTNCCEventArgsMD;
259 MethodDesc *m_pWinRTNCCEventArgsToSystemNCCEventArgsMD;
260 MethodDesc *m_pSystemPCEventArgsToWinRTPCEventArgsMD;
261 MethodDesc *m_pWinRTPCEventArgsToSystemPCEventArgsMD;
262};
263
264class UriMarshalingInfo
265{
266public:
267 // Constructor.
268 UriMarshalingInfo();
269
270 // Destructor
271 ~UriMarshalingInfo();
272
273 // UriMarshalingInfo's are always allocated on the loader heap so we need to redefine
274 // the new and delete operators to ensure this.
275 void *operator new(size_t size, LoaderHeap *pHeap);
276 void operator delete(void *pMem);
277
278 // Accessors.
279 TypeHandle GetSystemUriType()
280 {
281 LIMITED_METHOD_CONTRACT;
282 return m_hndSystemUriType;
283 }
284
285 ABI::Windows::Foundation::IUriRuntimeClassFactory* GetUriFactory()
286 {
287 CONTRACTL
288 {
289 THROWS;
290 GC_TRIGGERS; // For potential COOP->PREEMP->COOP switch
291 MODE_ANY;
292 PRECONDITION(!GetAppDomain()->IsCompilationDomain());
293 }
294 CONTRACTL_END;
295
296 if (m_pUriFactory.Load() == NULL)
297 {
298 GCX_PREEMP();
299
300 SafeComHolderPreemp<ABI::Windows::Foundation::IUriRuntimeClassFactory> pUriFactory;
301
302 // IUriRuntimeClassFactory: 44A9796F-723E-4FDF-A218-033E75B0C084
303 IfFailThrow(clr::winrt::GetActivationFactory(g_WinRTUriClassNameW, (ABI::Windows::Foundation::IUriRuntimeClassFactory **)&pUriFactory));
304 _ASSERTE_MSG(pUriFactory, "Got Null Uri factory!");
305
306 if (InterlockedCompareExchangeT(&m_pUriFactory, (ABI::Windows::Foundation::IUriRuntimeClassFactory *) pUriFactory, NULL) == NULL)
307 pUriFactory.SuppressRelease();
308 }
309
310 return m_pUriFactory;
311 }
312
313 MethodDesc *GetSystemUriCtorMD()
314 {
315 LIMITED_METHOD_CONTRACT;
316 return m_SystemUriCtorMD;
317 }
318
319 MethodDesc *GetSystemUriOriginalStringMD()
320 {
321 LIMITED_METHOD_CONTRACT;
322 return m_SystemUriOriginalStringGetterMD;
323 }
324
325
326private:
327 TypeHandle m_hndSystemUriType;
328
329 MethodDesc* m_SystemUriCtorMD;
330 MethodDesc* m_SystemUriOriginalStringGetterMD;
331
332 VolatilePtr<ABI::Windows::Foundation::IUriRuntimeClassFactory> m_pUriFactory;
333};
334
335class OleColorMarshalingInfo
336{
337public:
338 // Constructor.
339 OleColorMarshalingInfo();
340
341 // OleColorMarshalingInfo's are always allocated on the loader heap so we need to redefine
342 // the new and delete operators to ensure this.
343 void *operator new(size_t size, LoaderHeap *pHeap);
344 void operator delete(void *pMem);
345
346 // Accessors.
347 TypeHandle GetColorType()
348 {
349 LIMITED_METHOD_CONTRACT;
350 return m_hndColorType;
351 }
352 MethodDesc *GetOleColorToSystemColorMD()
353 {
354 LIMITED_METHOD_CONTRACT;
355 return m_OleColorToSystemColorMD;
356 }
357 MethodDesc *GetSystemColorToOleColorMD()
358 {
359 LIMITED_METHOD_CONTRACT;
360 return m_SystemColorToOleColorMD;
361 }
362
363
364private:
365 TypeHandle m_hndColorType;
366 MethodDesc* m_OleColorToSystemColorMD;
367 MethodDesc* m_SystemColorToOleColorMD;
368};
369
370#endif // FEATURE_COMINTEROP
371
372
373class EEMarshalingData
374{
375public:
376 EEMarshalingData(BaseDomain *pDomain, LoaderHeap *pHeap, CrstBase *pCrst);
377 ~EEMarshalingData();
378
379 // EEMarshalingData's are always allocated on the loader heap so we need to redefine
380 // the new and delete operators to ensure this.
381 void *operator new(size_t size, LoaderHeap *pHeap);
382 void operator delete(void *pMem);
383
384 // This method returns the custom marshaling helper associated with the name cookie pair. If the
385 // CM info has not been created yet for this pair then it will be created and returned.
386 CustomMarshalerHelper *GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes);
387
388 // This method returns the custom marshaling info associated with shared CM helper.
389 CustomMarshalerInfo *GetCustomMarshalerInfo(SharedCustomMarshalerHelper *pSharedCMHelper);
390
391#ifdef FEATURE_COMINTEROP
392 // This method retrieves OLE_COLOR marshaling info.
393 OleColorMarshalingInfo *GetOleColorMarshalingInfo();
394 UriMarshalingInfo *GetUriMarshalingInfo();
395 EventArgsMarshalingInfo *GetEventArgsMarshalingInfo();
396
397
398#endif // FEATURE_COMINTEROP
399
400private:
401#ifndef CROSSGEN_COMPILE
402 EECMHelperHashTable m_CMHelperHashtable;
403 EEPtrHashTable m_SharedCMHelperToCMInfoMap;
404#endif // CROSSGEN_COMPILE
405 LoaderHeap* m_pHeap;
406 BaseDomain* m_pDomain;
407 CMINFOLIST m_pCMInfoList;
408#ifdef FEATURE_COMINTEROP
409 OleColorMarshalingInfo* m_pOleColorInfo;
410 UriMarshalingInfo* m_pUriInfo;
411 EventArgsMarshalingInfo* m_pEventArgsInfo;
412#endif // FEATURE_COMINTEROP
413};
414
415struct ItfMarshalInfo;
416
417class MarshalInfo
418{
419public:
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
437private:
438
439public:
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 MethodDesc* pMD = NULL,
460 BOOL fUseCustomMarshal = TRUE
461#ifdef _DEBUG
462 ,
463 LPCUTF8 pDebugName = NULL,
464 LPCUTF8 pDebugClassName = NULL,
465 UINT argidx = 0 // 0 for return value, -1 for field
466#endif
467
468 );
469
470 VOID EmitOrThrowInteropParamException(NDirectStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx);
471
472 // These methods retrieve the information for different element types.
473 HRESULT HandleArrayElemType(NativeTypeParamInfo *pParamInfo,
474 UINT16 optbaseoffset,
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
658private:
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
673private:
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
738enum 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
757class ArrayMarshalInfo
758{
759public:
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
855protected:
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
873protected:
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//===================================================================================
891VOID ThrowInteropParamException(UINT resID, UINT paramIdx);
892
893VOID CollateParamTokens(IMDInternalImport *pInternalImport, mdMethodDef md, ULONG numargs, mdParamDef *aParams);
894bool IsUnsupportedValueTypeReturn(MetaSig& msig);
895
896void FindCopyCtor(Module *pModule, MethodTable *pMT, MethodDesc **pMDOut);
897void 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_
904