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 | 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 | |
111 | typedef 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 | |
121 | typedef 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 | //========================================================================== |
131 | struct 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 | |
187 | HRESULT CheckForCompressedData(PCCOR_SIGNATURE pvNativeTypeStart, PCCOR_SIGNATURE pvNativeType, ULONG cbNativeType); |
188 | |
189 | BOOL ParseNativeTypeInfo(mdToken token, |
190 | IMDInternalImport* pScope, |
191 | NativeTypeParamInfo* pParamInfo); |
192 | |
193 | void VerifyAndAdjustNormalizedType( |
194 | Module * pModule, |
195 | SigPointer sigPtr, |
196 | const SigTypeContext * pTypeContext, |
197 | CorElementType * pManagedElemType, |
198 | CorNativeType * pNativeType); |
199 | |
200 | #ifdef FEATURE_COMINTEROP |
201 | |
202 | class EventArgsMarshalingInfo |
203 | { |
204 | public: |
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 | |
254 | private: |
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 | |
264 | class UriMarshalingInfo |
265 | { |
266 | public: |
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 | |
326 | private: |
327 | TypeHandle m_hndSystemUriType; |
328 | |
329 | MethodDesc* m_SystemUriCtorMD; |
330 | MethodDesc* m_SystemUriOriginalStringGetterMD; |
331 | |
332 | VolatilePtr<ABI::Windows::Foundation::IUriRuntimeClassFactory> m_pUriFactory; |
333 | }; |
334 | |
335 | class OleColorMarshalingInfo |
336 | { |
337 | public: |
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 | |
364 | private: |
365 | TypeHandle m_hndColorType; |
366 | MethodDesc* m_OleColorToSystemColorMD; |
367 | MethodDesc* m_SystemColorToOleColorMD; |
368 | }; |
369 | |
370 | #endif // FEATURE_COMINTEROP |
371 | |
372 | |
373 | class EEMarshalingData |
374 | { |
375 | public: |
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 | |
400 | private: |
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 | |
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 | 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 | |
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 IsUnsupportedValueTypeReturn(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_ |
904 | |