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.
5 // File: FieldMarshaler.h
9 // FieldMarshalers are used to allow CLR programs to allocate and access
10 // native structures for interop purposes. FieldMarshalers are actually normal GC
11 // objects with a class, but instead of keeping fields in the GC object,
12 // it keeps a hidden pointer to a fixed memory block (which may have been
13 // allocated by a third party.) Field accesses to FieldMarshalers are redirected
14 // to this fixed block.
18 #ifndef __FieldMarshaler_h__
19 #define __FieldMarshaler_h__
24 #include "olevariant.h"
26 #ifdef FEATURE_COMINTEROP
27 #endif // FEATURE_COMINTEROP
31 #endif // FEATURE_PREJIT
34 class EEClassLayoutInfo;
38 class FieldMarshaler_NestedLayoutClass;
39 class FieldMarshaler_NestedValueClass;
40 class FieldMarshaler_StringUni;
41 class FieldMarshaler_StringAnsi;
42 class FieldMarshaler_FixedStringUni;
43 class FieldMarshaler_FixedStringAnsi;
44 class FieldMarshaler_FixedArray;
45 class FieldMarshaler_FixedCharArrayAnsi;
46 class FieldMarshaler_Delegate;
47 class FieldMarshaler_Illegal;
48 class FieldMarshaler_Copy1;
49 class FieldMarshaler_Copy2;
50 class FieldMarshaler_Copy4;
51 class FieldMarshaler_Copy8;
52 class FieldMarshaler_Ansi;
53 class FieldMarshaler_WinBool;
54 class FieldMarshaler_CBool;
55 class FieldMarshaler_Decimal;
56 class FieldMarshaler_Date;
57 class FieldMarshaler_BSTR;
58 #ifdef FEATURE_COMINTEROP
59 class FieldMarshaler_SafeArray;
60 class FieldMarshaler_HSTRING;
61 class FieldMarshaler_Interface;
62 class FieldMarshaler_Variant;
63 class FieldMarshaler_VariantBool;
64 class FieldMarshaler_DateTimeOffset;
65 class FieldMarshaler_SystemType;
66 class FieldMarshaler_Exception;
67 class FieldMarshaler_Nullable;
68 #endif // FEATURE_COMINTEROP
70 //=======================================================================
71 // Each possible COM+/Native pairing of data type has a
72 // NLF_* id. This is used to select the marshaling code.
73 //=======================================================================
75 #define DEFINE_NFT(name, nativesize, fWinRTSupported) name,
83 //=======================================================================
84 // Magic number for default struct packing size.
86 // Currently we set this to the packing size of the largest supported
87 // fundamental type and let the field marshaller downsize where needed.
88 //=======================================================================
89 #define DEFAULT_PACKING_SIZE 32
92 //=======================================================================
93 // This is invoked from the class loader while building the data structures for a type.
94 // This function checks if explicit layout metadata exists.
97 // TRUE - yes, there's layout metadata
98 // FALSE - no, there's no layout.
99 // fail - throws a typeload exception
102 // *pNLType gets set to nltAnsi or nltUnicode
103 // *pPackingSize declared packing size
104 // *pfExplicitoffsets offsets explicit in metadata or computed?
105 //=======================================================================
106 BOOL HasLayoutMetadata(Assembly* pAssembly, IMDInternalImport *pInternalImport, mdTypeDef cl,
107 MethodTable *pParentMT, BYTE *pPackingSize, BYTE *pNLTType,
108 BOOL *pfExplicitOffsets);
111 //=======================================================================
112 // This function returns TRUE if the type passed in is either a value class or a class and if it has layout information
113 // and is marshalable. In all other cases it will return FALSE.
114 //=======================================================================
115 BOOL IsStructMarshalable(TypeHandle th);
117 //=======================================================================
118 // The classloader stores an intermediate representation of the layout
119 // metadata in an array of these structures. The dual-pass nature
120 // is a bit extra overhead but building this structure requiring loading
121 // other classes (for nested structures) and I'd rather keep this
122 // next to the other places where we load other classes (e.g. the superclass
123 // and implemented interfaces.)
125 // Each redirected field gets one entry in LayoutRawFieldInfo.
126 // The array is terminated by one dummy record whose m_MD == mdMemberDefNil.
127 // WARNING!! Before you change this struct see the comment above the m_FieldMarshaler field
128 //=======================================================================
129 struct LayoutRawFieldInfo
131 mdFieldDef m_MD; // mdMemberDefNil for end of array
132 UINT8 m_nft; // NFT_* value
133 UINT32 m_offset; // native offset of field
134 UINT32 m_cbNativeSize; // native size of field in bytes
135 ULONG m_sequence; // sequence # from metadata
136 BOOL m_fIsOverlapped;
139 //----- Post v1.0 addition: The LayoutKind.Sequential attribute now affects managed layout as well.
140 //----- So we need to keep a parallel set of layout data for the managed side. The Size and AlignmentReq
141 //----- is redundant since we can figure it out from the sig but since we're already accessing the sig
142 //----- in ParseNativeType, we might as well capture it at that time.
143 UINT32 m_managedSize; // managed size of field
144 UINT32 m_managedAlignmentReq; // natural alignment of field
145 UINT32 m_managedOffset; // managed offset of field
146 UINT32 m_pad; // needed to keep m_FieldMarshaler 8-byte aligned
149 // We in-place create a field marshaler in the following
150 // memory, so keep it 8-byte aligned or
151 // the vtable pointer initialization will cause a
152 // misaligned memory write on IA64.
153 // The entire struct's size must also be multiple of 8 bytes
157 char m_space[MAXFIELDMARSHALERSIZE];
162 //=======================================================================
164 //=======================================================================
166 VOID LayoutUpdateNative(LPVOID *ppProtectedManagedData, SIZE_T offsetbias, MethodTable *pMT, BYTE* pNativeData, OBJECTREF *ppCleanupWorkListOnStack);
167 VOID LayoutUpdateCLR(LPVOID *ppProtectedManagedData, SIZE_T offsetbias, MethodTable *pMT, BYTE *pNativeData);
168 VOID LayoutDestroyNative(LPVOID pNative, MethodTable *pMT);
170 VOID FmtClassUpdateNative(OBJECTREF *ppProtectedManagedData, BYTE *pNativeData, OBJECTREF *ppCleanupWorkListOnStack);
171 VOID FmtClassUpdateCLR(OBJECTREF *ppProtectedManagedData, BYTE *pNativeData);
172 VOID FmtClassDestroyNative(LPVOID pNative, MethodTable *pMT);
174 VOID FmtValueTypeUpdateNative(LPVOID pProtectedManagedData, MethodTable *pMT, BYTE *pNativeData, OBJECTREF *ppCleanupWorkListOnStack);
175 VOID FmtValueTypeUpdateCLR(LPVOID pProtectedManagedData, MethodTable *pMT, BYTE *pNativeData);
178 //=======================================================================
179 // Abstract base class. Each type of NStruct reference field extends
180 // this class and implements the necessary methods.
183 // - this method receives a COM+ field value and a pointer to
184 // native field inside the fixed portion. it should marshal
185 // the COM+ value to a new native instance and store it
186 // inside *pNativeValue. Do not destroy the value you overwrite
189 // may throw COM+ exceptions
192 // - this method receives a read-only pointer to the native field inside
193 // the fixed portion. it should marshal the native value to
194 // a new CLR instance and store it in *ppCLRValue.
195 // (the caller keeps *ppCLRValue gc-protected.)
197 // may throw CLR exceptions
200 // - should do the type-specific deallocation of a native instance.
201 // if the type has a "NULL" value, this method should
202 // overwrite the field with this "NULL" value (whether or not
203 // it does, however, it's considered a bug to depend on the
204 // value left over after a DestroyNativeImpl.)
206 // must NOT throw a CLR exception
209 // - returns the size, in bytes, of the native version of the field.
211 // AlignmentRequirementImpl
212 // - returns one of 1,2,4 or 8; indicating the "natural" alignment
213 // of the native field. In general,
215 // for scalars, the AR is equal to the size
216 // for arrays, the AR is that of a single element
217 // for structs, the AR is that of the member with the largest AR
220 //=======================================================================
223 #ifndef DACCESS_COMPILE
225 #define UNUSED_METHOD_IMPL(PROTOTYPE) \
228 LIMITED_METHOD_CONTRACT; \
229 _ASSERTE(!"Not supposed to get here."); \
232 #define ELEMENT_SIZE_IMPL(NativeSize, AlignmentReq) \
233 UINT32 NativeSizeImpl() const \
235 LIMITED_METHOD_CONTRACT; \
238 UINT32 AlignmentRequirementImpl() const \
240 LIMITED_METHOD_CONTRACT; \
241 return AlignmentReq; \
244 #define SCALAR_MARSHALER_IMPL(NativeSize, AlignmentReq) \
245 BOOL IsScalarMarshalerImpl() const \
247 LIMITED_METHOD_CONTRACT; \
250 ELEMENT_SIZE_IMPL(NativeSize, AlignmentReq)
252 #define COPY_TO_IMPL_BASE_STRUCT_ONLY() \
253 VOID CopyToImpl(VOID *pDest, SIZE_T destSize) \
255 static_assert(sizeof(*this) == sizeof(FieldMarshaler), \
256 "Please, implement CopyToImpl for correct copy of field values"); \
258 FieldMarshaler::CopyToImpl(pDest, destSize); \
261 #define START_COPY_TO_IMPL(CLASS_NAME) \
262 VOID CopyToImpl(VOID *pDest, SIZE_T destSize) const \
264 FieldMarshaler::CopyToImpl(pDest, destSize); \
266 CLASS_NAME *pDestFieldMarshaller = (std::remove_const<std::remove_pointer<decltype(this)>::type>::type *) pDest; \
267 _ASSERTE(sizeof(*pDestFieldMarshaller) <= destSize); \
269 #define END_COPY_TO_IMPL(CLASS_NAME) \
270 static_assert(std::is_same<CLASS_NAME *, decltype(pDestFieldMarshaller)>::value, \
271 "Structure's name is required"); \
275 //=======================================================================
277 // FieldMarshaler's are constructed in place and replicated via bit-wise
278 // copy, so you can't have a destructor. Make sure you don't define a
279 // destructor in derived classes!!
280 // We used to enforce this by defining a private destructor, by the C++
281 // compiler doesn't allow that anymore.
283 //=======================================================================
288 VOID UpdateNative(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
289 VOID UpdateCLR(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
290 VOID DestroyNative(LPVOID pNativeValue) const;
291 UINT32 NativeSize() const;
292 UINT32 AlignmentRequirement() const;
293 BOOL IsScalarMarshaler() const;
294 BOOL IsNestedValueClassMarshaler() const;
295 VOID ScalarUpdateNative(LPVOID pCLR, LPVOID pNative) const;
296 VOID ScalarUpdateCLR(const VOID *pNative, LPVOID pCLR) const;
297 VOID NestedValueClassUpdateNative(const VOID **ppProtectedCLR, SIZE_T startoffset, LPVOID pNative, OBJECTREF *ppCleanupWorkListOnStack) const;
298 VOID NestedValueClassUpdateCLR(const VOID *pNative, LPVOID *ppProtectedCLR, SIZE_T startoffset) const;
299 VOID CopyTo(VOID *pDest, SIZE_T destSize) const;
300 #ifdef FEATURE_PREJIT
301 void Save(DataImage *image);
302 void Fixup(DataImage *image);
303 #endif // FEATURE_PREJIT
306 VOID DestroyNativeImpl(LPVOID pNativeValue) const
308 LIMITED_METHOD_CONTRACT;
311 BOOL IsScalarMarshalerImpl() const
313 LIMITED_METHOD_CONTRACT;
317 BOOL IsNestedValueClassMarshalerImpl() const
319 LIMITED_METHOD_CONTRACT;
323 UNUSED_METHOD_IMPL(VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const)
324 UNUSED_METHOD_IMPL(VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const)
325 UNUSED_METHOD_IMPL(VOID NestedValueClassUpdateNativeImpl(const VOID **ppProtectedCLR, SIZE_T startoffset, LPVOID pNative, OBJECTREF *ppCleanupWorkListOnStack) const)
326 UNUSED_METHOD_IMPL(VOID NestedValueClassUpdateCLRImpl(const VOID *pNative, LPVOID *ppProtectedCLR, SIZE_T startoffset) const)
329 // Methods for saving & restoring in prejitted images:
332 NStructFieldType GetNStructFieldType() const
334 LIMITED_METHOD_CONTRACT;
338 void SetNStructFieldType(NStructFieldType nft)
340 LIMITED_METHOD_CONTRACT;
344 #ifdef FEATURE_PREJIT
345 void SaveImpl(DataImage *image)
347 STANDARD_VM_CONTRACT;
350 void FixupImpl(DataImage *image)
352 STANDARD_VM_CONTRACT;
354 image->FixupFieldDescPointer(this, &m_pFD);
356 #endif // FEATURE_PREJIT
368 #ifdef FEATURE_PREJIT
369 Module::RestoreFieldDescPointer(&m_pFD);
370 #endif // FEATURE_PREJIT
373 void CopyToImpl(VOID *pDest, SIZE_T destSize) const
375 FieldMarshaler *pDestFieldMarshaller = (FieldMarshaler *) pDest;
377 _ASSERTE(sizeof(*pDestFieldMarshaller) <= destSize);
379 pDestFieldMarshaller->SetFieldDesc(GetFieldDesc());
380 pDestFieldMarshaller->SetExternalOffset(GetExternalOffset());
381 pDestFieldMarshaller->SetNStructFieldType(GetNStructFieldType());
384 void SetFieldDesc(FieldDesc* pFD)
386 LIMITED_METHOD_CONTRACT;
387 m_pFD.SetValueMaybeNull(pFD);
390 FieldDesc* GetFieldDesc() const
392 CONTRACT (FieldDesc*)
397 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
401 RETURN m_pFD.GetValueMaybeNull();
404 void SetExternalOffset(UINT32 dwExternalOffset)
406 LIMITED_METHOD_CONTRACT;
407 m_dwExternalOffset = dwExternalOffset;
410 UINT32 GetExternalOffset() const
412 LIMITED_METHOD_CONTRACT;
413 return m_dwExternalOffset;
419 LIMITED_METHOD_CONTRACT;
422 m_dwExternalOffset = 0xcccccccc;
426 static inline void RestoreHelper(RelativeFixupPointer<PTR_MethodTable> *ppMT)
433 PRECONDITION(CheckPointer(ppMT));
437 #ifdef FEATURE_PREJIT
438 Module::RestoreMethodTablePointer(ppMT);
439 #else // FEATURE_PREJIT
440 // without NGEN we only have to make sure that the type is fully loaded
441 ClassLoader::EnsureLoaded(ppMT->GetValue());
442 #endif // FEATURE_PREJIT
446 static inline BOOL IsRestoredHelper(const RelativeFixupPointer<PTR_MethodTable> &pMT)
450 #ifdef FEATURE_PREJIT
451 return pMT.IsNull() || (!pMT.IsTagged() && pMT.GetValue()->IsRestored());
452 #else // FEATURE_PREJIT
453 // putting the IsFullyLoaded check here is tempting but incorrect
455 #endif // FEATURE_PREJIT
460 RelativeFixupPointer<PTR_FieldDesc> m_pFD; // FieldDesc
461 UINT32 m_dwExternalOffset; // offset of field in the fixed portion
462 NStructFieldType m_nft;
466 //=======================================================================
467 // BSTR <--> System.String
468 //=======================================================================
469 class FieldMarshaler_BSTR : public FieldMarshaler
473 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
474 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
475 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
477 ELEMENT_SIZE_IMPL(sizeof(BSTR), sizeof(BSTR))
478 COPY_TO_IMPL_BASE_STRUCT_ONLY()
481 #ifdef FEATURE_COMINTEROP
482 //=======================================================================
483 // HSTRING <--> System.String
484 //=======================================================================
485 class FieldMarshaler_HSTRING : public FieldMarshaler
488 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
489 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
490 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
492 ELEMENT_SIZE_IMPL(sizeof(HSTRING), sizeof(HSTRING))
493 COPY_TO_IMPL_BASE_STRUCT_ONLY()
496 //=======================================================================
497 // Windows.Foundation.IReference`1 <--> System.Nullable`1
498 //=======================================================================
499 class FieldMarshaler_Nullable : public FieldMarshaler
503 FieldMarshaler_Nullable(MethodTable* pMT)
505 m_pNullableTypeMT.SetValueMaybeNull(pMT);
508 BOOL IsNullableMarshalerImpl() const
510 LIMITED_METHOD_CONTRACT;
514 //UnImplementedMethods.
515 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
516 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
518 ELEMENT_SIZE_IMPL(sizeof(IUnknown*), sizeof(IUnknown*))
521 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
522 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
523 VOID DestroyNativeImpl(const VOID* pNativeValue) const;
524 MethodDesc* GetMethodDescForGenericInstantiation(MethodDesc* pMD) const;
526 BOOL IsScalarMarshalerImpl() const
528 LIMITED_METHOD_CONTRACT;
532 #ifdef FEATURE_PREJIT
533 void FixupImpl(DataImage *image)
535 STANDARD_VM_CONTRACT;
537 image->FixupMethodTablePointer(this, &m_pNullableTypeMT);
539 FieldMarshaler::FixupImpl(image);
541 #endif // FEATURE_PREJIT
553 RestoreHelper(&m_pNullableTypeMT);
555 FieldMarshaler::RestoreImpl();
558 START_COPY_TO_IMPL(FieldMarshaler_Nullable)
560 pDestFieldMarshaller->m_pNullableTypeMT.SetValueMaybeNull(GetMethodTable());
562 END_COPY_TO_IMPL(FieldMarshaler_Nullable)
565 BOOL IsRestored() const
569 return IsRestoredHelper(m_pNullableTypeMT);
573 MethodTable *GetMethodTable() const
580 PRECONDITION(IsRestored());
584 return m_pNullableTypeMT.GetValue();
588 RelativeFixupPointer<PTR_MethodTable> m_pNullableTypeMT;
592 //=======================================================================
593 // Windows.UI.Xaml.Interop.TypeName <--> System.Type
594 //=======================================================================
595 class FieldMarshaler_SystemType : public FieldMarshaler
598 VOID UpdateNativeImpl(OBJECTREF * pCLRValue, LPVOID pNativeValue, OBJECTREF * ppCleanupWorkListOnStack) const;
599 VOID UpdateCLRImpl(const VOID * pNativeValue, OBJECTREF * ppProtectedCLRValue, OBJECTREF * ppProtectedOldCLRValue) const;
600 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
602 ELEMENT_SIZE_IMPL(sizeof(HSTRING), sizeof(HSTRING))
603 COPY_TO_IMPL_BASE_STRUCT_ONLY()
606 //=======================================================================
607 // Windows.Foundation.HResult <--> System.Exception
608 // Note: The WinRT struct has exactly 1 field, Value (an HRESULT)
609 //=======================================================================
610 class FieldMarshaler_Exception : public FieldMarshaler
613 VOID UpdateNativeImpl(OBJECTREF * pCLRValue, LPVOID pNativeValue, OBJECTREF * ppCleanupWorkListOnStack) const;
614 VOID UpdateCLRImpl(const VOID * pNativeValue, OBJECTREF * ppProtectedCLRValue, OBJECTREF * ppProtectedOldCLRValue) const;
616 ELEMENT_SIZE_IMPL(sizeof(HRESULT), sizeof(HRESULT))
617 COPY_TO_IMPL_BASE_STRUCT_ONLY()
620 #endif // FEATURE_COMINTEROP
624 //=======================================================================
625 // Embedded struct <--> LayoutClass
626 //=======================================================================
627 class FieldMarshaler_NestedLayoutClass : public FieldMarshaler
630 FieldMarshaler_NestedLayoutClass(MethodTable *pMT)
633 m_pNestedMethodTable.SetValueMaybeNull(pMT);
636 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
637 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
638 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
640 UINT32 NativeSizeImpl() const;
641 UINT32 AlignmentRequirementImpl() const;
643 #ifdef FEATURE_PREJIT
644 void FixupImpl(DataImage *image)
646 STANDARD_VM_CONTRACT;
648 image->FixupMethodTablePointer(this, &m_pNestedMethodTable);
650 FieldMarshaler::FixupImpl(image);
652 #endif // FEATURE_PREJIT
664 RestoreHelper(&m_pNestedMethodTable);
666 FieldMarshaler::RestoreImpl();
669 START_COPY_TO_IMPL(FieldMarshaler_NestedLayoutClass)
671 pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(GetMethodTable());
673 END_COPY_TO_IMPL(FieldMarshaler_NestedLayoutClass)
676 BOOL IsRestored() const
680 return IsRestoredHelper(m_pNestedMethodTable);
684 MethodTable *GetMethodTable() const
691 PRECONDITION(IsRestored());
695 return m_pNestedMethodTable.GetValueMaybeNull();
699 // MethodTable of nested FieldMarshaler.
700 RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
704 //=======================================================================
705 // Embedded struct <--> ValueClass
706 //=======================================================================
707 class FieldMarshaler_NestedValueClass : public FieldMarshaler
711 FieldMarshaler_NestedValueClass(MethodTable *pMT)
713 FieldMarshaler_NestedValueClass(MethodTable *pMT, BOOL isFixedBuffer)
717 m_pNestedMethodTable.SetValueMaybeNull(pMT);
719 m_isFixedBuffer = isFixedBuffer;
723 BOOL IsNestedValueClassMarshalerImpl() const
725 LIMITED_METHOD_CONTRACT;
729 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
730 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
732 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
734 UINT32 NativeSizeImpl() const;
735 UINT32 AlignmentRequirementImpl() const;
736 VOID NestedValueClassUpdateNativeImpl(const VOID **ppProtectedCLR, SIZE_T startoffset, LPVOID pNative, OBJECTREF *ppCleanupWorkListOnStack) const;
737 VOID NestedValueClassUpdateCLRImpl(const VOID *pNative, LPVOID *ppProtectedCLR, SIZE_T startoffset) const;
739 #ifdef FEATURE_PREJIT
740 void FixupImpl(DataImage *image)
742 STANDARD_VM_CONTRACT;
744 image->FixupMethodTablePointer(this, &m_pNestedMethodTable);
746 FieldMarshaler::FixupImpl(image);
748 #endif // FEATURE_PREJIT
760 RestoreHelper(&m_pNestedMethodTable);
762 FieldMarshaler::RestoreImpl();
765 START_COPY_TO_IMPL(FieldMarshaler_NestedValueClass)
767 pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(GetMethodTable());
769 pDestFieldMarshaller->m_isFixedBuffer = m_isFixedBuffer;
772 END_COPY_TO_IMPL(FieldMarshaler_NestedValueClass)
775 BOOL IsRestored() const
779 return IsRestoredHelper(m_pNestedMethodTable);
786 return GetMethodTable()->IsBlittable();
789 MethodTable *GetMethodTable() const
796 PRECONDITION(IsRestored());
800 return m_pNestedMethodTable.GetValueMaybeNull();
804 BOOL IsFixedBuffer() const
806 return m_isFixedBuffer;
812 // MethodTable of nested NStruct.
813 RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
815 BOOL m_isFixedBuffer;
820 //=======================================================================
821 // LPWSTR <--> System.String
822 //=======================================================================
823 class FieldMarshaler_StringUni : public FieldMarshaler
827 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
828 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
829 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
831 ELEMENT_SIZE_IMPL(sizeof(LPWSTR), sizeof(LPWSTR))
832 COPY_TO_IMPL_BASE_STRUCT_ONLY()
835 //=======================================================================
836 // LPUTF8STR <--> System.String
837 //=======================================================================
838 class FieldMarshaler_StringUtf8 : public FieldMarshaler
842 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
843 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
844 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
846 ELEMENT_SIZE_IMPL(sizeof(LPSTR), sizeof(LPSTR))
847 COPY_TO_IMPL_BASE_STRUCT_ONLY()
850 //=======================================================================
851 // LPSTR <--> System.String
852 //=======================================================================
853 class FieldMarshaler_StringAnsi : public FieldMarshaler
856 FieldMarshaler_StringAnsi(BOOL BestFit, BOOL ThrowOnUnmappableChar) :
857 m_BestFitMap(!!BestFit), m_ThrowOnUnmappableChar(!!ThrowOnUnmappableChar)
862 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
863 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
864 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
866 ELEMENT_SIZE_IMPL(sizeof(LPSTR), sizeof(LPSTR))
870 LIMITED_METHOD_CONTRACT;
874 BOOL GetThrowOnUnmappableChar()
876 LIMITED_METHOD_CONTRACT;
877 return m_ThrowOnUnmappableChar;
880 START_COPY_TO_IMPL(FieldMarshaler_StringAnsi)
882 pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
883 pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
885 END_COPY_TO_IMPL(FieldMarshaler_StringAnsi)
889 bool m_ThrowOnUnmappableChar:1;
893 //=======================================================================
894 // Embedded LPWSTR <--> System.String
895 //=======================================================================
896 class FieldMarshaler_FixedStringUni : public FieldMarshaler
899 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
900 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
902 ELEMENT_SIZE_IMPL(m_numchar * sizeof(WCHAR), sizeof(WCHAR))
904 FieldMarshaler_FixedStringUni(UINT32 numChar)
910 START_COPY_TO_IMPL(FieldMarshaler_FixedStringUni)
912 pDestFieldMarshaller->m_numchar = m_numchar;
914 END_COPY_TO_IMPL(FieldMarshaler_FixedStringUni)
917 // # of characters for fixed strings
922 //=======================================================================
923 // Embedded LPSTR <--> System.String
924 //=======================================================================
925 class FieldMarshaler_FixedStringAnsi : public FieldMarshaler
928 FieldMarshaler_FixedStringAnsi(UINT32 numChar, BOOL BestFitMap, BOOL ThrowOnUnmappableChar) :
929 m_numchar(numChar), m_BestFitMap(!!BestFitMap), m_ThrowOnUnmappableChar(!!ThrowOnUnmappableChar)
934 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
935 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
937 ELEMENT_SIZE_IMPL(m_numchar * sizeof(CHAR), sizeof(CHAR))
941 LIMITED_METHOD_CONTRACT;
945 BOOL GetThrowOnUnmappableChar()
947 LIMITED_METHOD_CONTRACT;
948 return m_ThrowOnUnmappableChar;
951 START_COPY_TO_IMPL(FieldMarshaler_FixedStringAnsi)
953 pDestFieldMarshaller->m_numchar = m_numchar;
954 pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
955 pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
957 END_COPY_TO_IMPL(FieldMarshaler_FixedStringAnsi)
960 // # of characters for fixed strings
963 bool m_ThrowOnUnmappableChar:1;
967 //=======================================================================
968 // Embedded AnsiChar array <--> char[]
969 //=======================================================================
970 class FieldMarshaler_FixedCharArrayAnsi : public FieldMarshaler
973 FieldMarshaler_FixedCharArrayAnsi(UINT32 numElems, BOOL BestFit, BOOL ThrowOnUnmappableChar) :
974 m_numElems(numElems), m_BestFitMap(!!BestFit), m_ThrowOnUnmappableChar(!!ThrowOnUnmappableChar)
979 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
980 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
982 ELEMENT_SIZE_IMPL(m_numElems * sizeof(CHAR), sizeof(CHAR))
986 LIMITED_METHOD_CONTRACT;
990 BOOL GetThrowOnUnmappableChar()
992 LIMITED_METHOD_CONTRACT;
993 return m_ThrowOnUnmappableChar;
996 START_COPY_TO_IMPL(FieldMarshaler_FixedCharArrayAnsi)
998 pDestFieldMarshaller->m_numElems = m_numElems;
999 pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
1000 pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
1002 END_COPY_TO_IMPL(FieldMarshaler_FixedCharArrayAnsi)
1005 // # of elements for fixedchararray
1007 bool m_BestFitMap:1;
1008 bool m_ThrowOnUnmappableChar:1;
1012 //=======================================================================
1014 //=======================================================================
1015 class FieldMarshaler_FixedArray : public FieldMarshaler
1018 FieldMarshaler_FixedArray(IMDInternalImport *pMDImport, mdTypeDef cl, UINT32 numElems, VARTYPE vt, MethodTable* pElementMT);
1020 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1021 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1022 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
1023 UINT32 AlignmentRequirementImpl() const;
1025 UINT32 NativeSizeImpl() const
1027 LIMITED_METHOD_CONTRACT;
1029 return OleVariant::GetElementSizeForVarType(m_vt, GetElementMethodTable()) * m_numElems;
1032 MethodTable* GetElementMethodTable() const
1034 return GetElementTypeHandle().GetMethodTable();
1037 TypeHandle GetElementTypeHandle() const
1044 PRECONDITION(IsRestored());
1048 return m_arrayType.GetValue().AsArray()->GetArrayElementTypeHandle();
1051 VARTYPE GetElementVT() const
1053 LIMITED_METHOD_CONTRACT;
1057 #ifdef FEATURE_PREJIT
1058 void FixupImpl(DataImage *image)
1060 STANDARD_VM_CONTRACT;
1062 image->FixupTypeHandlePointer(this, &m_arrayType);
1064 FieldMarshaler::FixupImpl(image);
1066 #endif // FEATURE_PREJIT
1078 #ifdef FEATURE_PREJIT
1079 Module::RestoreTypeHandlePointer(&m_arrayType);
1080 #else // FEATURE_PREJIT
1081 // without NGEN we only have to make sure that the type is fully loaded
1082 ClassLoader::EnsureLoaded(m_arrayType.GetValue());
1083 #endif // FEATURE_PREJIT
1084 FieldMarshaler::RestoreImpl();
1087 START_COPY_TO_IMPL(FieldMarshaler_FixedArray)
1089 pDestFieldMarshaller->m_arrayType.SetValueMaybeNull(m_arrayType.GetValueMaybeNull());
1090 pDestFieldMarshaller->m_numElems = m_numElems;
1091 pDestFieldMarshaller->m_vt = m_vt;
1092 pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
1093 pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
1095 END_COPY_TO_IMPL(FieldMarshaler_FixedArray)
1098 BOOL IsRestored() const
1100 WRAPPER_NO_CONTRACT;
1102 #ifdef FEATURE_PREJIT
1103 return !m_arrayType.IsTagged() && (m_arrayType.IsNull() || m_arrayType.GetValue().IsRestored());
1104 #else // FEATURE_PREJIT
1105 return m_arrayType.IsNull() || m_arrayType.GetValue().IsFullyLoaded();
1106 #endif // FEATURE_PREJIT
1111 RelativeFixupPointer<TypeHandle> m_arrayType;
1114 bool m_BestFitMap:1; // Note: deliberately use small bools to save on working set - this is the largest FieldMarshaler and dominates the cost of the FieldMarshaler array
1115 bool m_ThrowOnUnmappableChar:1; // Note: deliberately use small bools to save on working set - this is the largest FieldMarshaler and dominates the cost of the FieldMarshaler array
1119 #ifdef FEATURE_CLASSIC_COMINTEROP
1120 //=======================================================================
1122 //=======================================================================
1123 class FieldMarshaler_SafeArray : public FieldMarshaler
1127 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1128 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1129 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
1131 ELEMENT_SIZE_IMPL(sizeof(LPSAFEARRAY), sizeof(LPSAFEARRAY))
1133 FieldMarshaler_SafeArray(VARTYPE vt, MethodTable* pMT)
1135 WRAPPER_NO_CONTRACT;
1137 m_pMT.SetValueMaybeNull(pMT);
1140 #ifdef FEATURE_PREJIT
1141 void FixupImpl(DataImage *image)
1143 STANDARD_VM_CONTRACT;
1145 image->FixupMethodTablePointer(this, &m_pMT);
1147 FieldMarshaler::FixupImpl(image);
1149 #endif // FEATURE_PREJIT
1161 RestoreHelper(&m_pMT);
1163 FieldMarshaler::RestoreImpl();
1166 START_COPY_TO_IMPL(FieldMarshaler_SafeArray)
1168 pDestFieldMarshaller->m_pMT.SetValueMaybeNull(m_pMT.GetValueMaybeNull());
1169 pDestFieldMarshaller->m_vt = m_vt;
1171 END_COPY_TO_IMPL(FieldMarshaler_SafeArray)
1174 BOOL IsRestored() const
1176 WRAPPER_NO_CONTRACT;
1178 return IsRestoredHelper(m_pMT);
1182 TypeHandle GetElementTypeHandle() const
1189 PRECONDITION(IsRestored());
1193 return TypeHandle(m_pMT.GetValue());
1196 VARTYPE GetElementVT() const
1198 LIMITED_METHOD_CONTRACT;
1203 RelativeFixupPointer<PTR_MethodTable> m_pMT;
1206 #endif //FEATURE_CLASSIC_COMINTEROP
1209 //=======================================================================
1210 // Embedded function ptr <--> Delegate
1211 //=======================================================================
1212 class FieldMarshaler_Delegate : public FieldMarshaler
1215 FieldMarshaler_Delegate(MethodTable* pMT)
1217 WRAPPER_NO_CONTRACT;
1218 m_pNestedMethodTable.SetValueMaybeNull(pMT);
1221 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1222 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1224 ELEMENT_SIZE_IMPL(sizeof(LPVOID), sizeof(LPVOID))
1226 #ifdef FEATURE_PREJIT
1227 void FixupImpl(DataImage *image)
1229 STANDARD_VM_CONTRACT;
1231 image->FixupMethodTablePointer(this, &m_pNestedMethodTable);
1233 FieldMarshaler::FixupImpl(image);
1235 #endif // FEATURE_PREJIT
1247 RestoreHelper(&m_pNestedMethodTable);
1249 FieldMarshaler::RestoreImpl();
1252 START_COPY_TO_IMPL(FieldMarshaler_Delegate)
1254 pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(m_pNestedMethodTable.GetValueMaybeNull());
1256 END_COPY_TO_IMPL(FieldMarshaler_Delegate)
1259 BOOL IsRestored() const
1261 WRAPPER_NO_CONTRACT;
1263 return IsRestoredHelper(m_pNestedMethodTable);
1267 MethodTable *GetMethodTable() const
1274 PRECONDITION(IsRestored());
1278 return m_pNestedMethodTable.GetValueMaybeNull();
1281 RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
1285 //=======================================================================
1286 // Embedded SafeHandle <--> Handle. This field really only supports
1287 // going from managed to unmanaged. In the other direction, we only
1288 // check that the handle value has not changed.
1289 //=======================================================================
1290 class FieldMarshaler_SafeHandle : public FieldMarshaler
1294 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1295 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1297 ELEMENT_SIZE_IMPL(sizeof(LPVOID), sizeof(LPVOID))
1298 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1302 //=======================================================================
1303 // Embedded CriticalHandle <--> Handle. This field really only supports
1304 // going from managed to unmanaged. In the other direction, we only
1305 // check that the handle value has not changed.
1306 //=======================================================================
1307 class FieldMarshaler_CriticalHandle : public FieldMarshaler
1311 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1312 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1314 ELEMENT_SIZE_IMPL(sizeof(LPVOID), sizeof(LPVOID))
1315 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1318 #ifdef FEATURE_COMINTEROP
1320 //=======================================================================
1321 // COM IP <--> Interface
1322 //=======================================================================
1323 class FieldMarshaler_Interface : public FieldMarshaler
1327 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1328 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1329 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
1331 ELEMENT_SIZE_IMPL(sizeof(IUnknown*), sizeof(IUnknown*))
1333 FieldMarshaler_Interface(MethodTable *pClassMT, MethodTable *pItfMT, DWORD dwFlags)
1335 WRAPPER_NO_CONTRACT;
1336 m_pClassMT.SetValueMaybeNull(pClassMT);
1337 m_pItfMT.SetValueMaybeNull(pItfMT);
1338 m_dwFlags = dwFlags;
1341 #ifdef FEATURE_PREJIT
1342 void FixupImpl(DataImage *image)
1344 STANDARD_VM_CONTRACT;
1346 image->FixupMethodTablePointer(this, &m_pClassMT);
1347 image->FixupMethodTablePointer(this, &m_pItfMT);
1349 FieldMarshaler::FixupImpl(image);
1351 #endif // FEATURE_PREJIT
1363 RestoreHelper(&m_pClassMT);
1364 RestoreHelper(&m_pItfMT);
1366 FieldMarshaler::RestoreImpl();
1369 START_COPY_TO_IMPL(FieldMarshaler_Interface)
1371 pDestFieldMarshaller->m_pClassMT.SetValueMaybeNull(m_pClassMT.GetValueMaybeNull());
1372 pDestFieldMarshaller->m_pItfMT.SetValueMaybeNull(m_pItfMT.GetValueMaybeNull());
1373 pDestFieldMarshaller->m_dwFlags = m_dwFlags;
1375 END_COPY_TO_IMPL(FieldMarshaler_Interface)
1378 BOOL IsRestored() const
1380 WRAPPER_NO_CONTRACT;
1382 return (IsRestoredHelper(m_pClassMT) && IsRestoredHelper(m_pItfMT));
1386 void GetInterfaceInfo(MethodTable **ppItfMT, DWORD* pdwFlags) const
1393 PRECONDITION(CheckPointer(ppItfMT));
1394 #ifdef FEATURE_PREJIT
1395 PRECONDITION(IsRestored());
1400 *ppItfMT = m_pItfMT.GetValue();
1401 *pdwFlags = m_dwFlags;
1404 MethodTable *GetMethodTable() const
1411 PRECONDITION(IsRestored());
1415 return m_pClassMT.GetValueMaybeNull();
1418 MethodTable *GetInterfaceMethodTable() const
1425 PRECONDITION(IsRestored());
1429 return m_pItfMT.GetValueMaybeNull();
1433 RelativeFixupPointer<PTR_MethodTable> m_pClassMT;
1434 RelativeFixupPointer<PTR_MethodTable> m_pItfMT;
1438 #endif // FEATURE_COMINTEROP
1440 #ifdef FEATURE_COMINTEROP
1441 // This compile-time assert checks that the above FieldMarshaler is the biggest
1442 // (or equal-biggest) FieldMasharler we have,
1443 // i.e. that we haven't set MAXFIELDMARSHALERSIZE to a value that is needlessly big.
1444 // Corresponding asserts in FieldMarshaler.cpp ensure that we haven't set it to a value that is needlessly
1445 // big, which would waste a whole lot of memory given the current storage scheme for FMs.
1447 // If this assert first, it probably means you have successully reduced the size of the above FieldMarshaler.
1448 // You should now place this assert on the FieldMarshaler that is the biggest, or modify MAXFIELDMARSHALERSIZE
1449 // to match the new size.
1450 static_assert_no_msg(sizeof(FieldMarshaler_Interface) == MAXFIELDMARSHALERSIZE);
1452 #endif // FEATURE_COMINTEROP
1454 #ifdef FEATURE_COMINTEROP
1456 //=======================================================================
1457 // VARIANT <--> Object
1458 //=======================================================================
1459 class FieldMarshaler_Variant : public FieldMarshaler
1463 VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
1464 VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
1465 VOID DestroyNativeImpl(LPVOID pNativeValue) const;
1467 ELEMENT_SIZE_IMPL(sizeof(VARIANT), 8)
1468 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1471 #endif // FEATURE_COMINTEROP
1474 //=======================================================================
1476 //=======================================================================
1477 class FieldMarshaler_Illegal : public FieldMarshaler
1480 FieldMarshaler_Illegal(UINT resIDWhy)
1482 WRAPPER_NO_CONTRACT;
1483 m_resIDWhy = resIDWhy;
1486 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1487 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1489 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
1490 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
1492 SCALAR_MARSHALER_IMPL(1, 1)
1494 START_COPY_TO_IMPL(FieldMarshaler_Illegal)
1496 pDestFieldMarshaller->m_resIDWhy = m_resIDWhy;
1498 END_COPY_TO_IMPL(FieldMarshaler_Illegal)
1505 #define FIELD_MARSHALER_COPY
1508 class FieldMarshaler_Copy1 : public FieldMarshaler
1512 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1513 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1515 SCALAR_MARSHALER_IMPL(1, 1)
1516 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1518 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1525 PRECONDITION(CheckPointer(pCLR));
1526 PRECONDITION(CheckPointer(pNative));
1530 *((U1*)pNative) = *((U1*)pCLR);
1534 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1541 PRECONDITION(CheckPointer(pCLR));
1542 PRECONDITION(CheckPointer(pNative));
1546 *((U1*)pCLR) = *((U1*)pNative);
1553 class FieldMarshaler_Copy2 : public FieldMarshaler
1557 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1558 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1560 SCALAR_MARSHALER_IMPL(2, 2)
1561 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1563 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1570 PRECONDITION(CheckPointer(pCLR));
1571 PRECONDITION(CheckPointer(pNative));
1575 MAYBE_UNALIGNED_WRITE(pNative, 16, MAYBE_UNALIGNED_READ(pCLR, 16));
1579 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1586 PRECONDITION(CheckPointer(pCLR));
1587 PRECONDITION(CheckPointer(pNative));
1591 MAYBE_UNALIGNED_WRITE(pCLR, 16, MAYBE_UNALIGNED_READ(pNative, 16));
1597 class FieldMarshaler_Copy4 : public FieldMarshaler
1601 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1602 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1604 SCALAR_MARSHALER_IMPL(4, 4)
1605 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1607 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1614 PRECONDITION(CheckPointer(pCLR));
1615 PRECONDITION(CheckPointer(pNative));
1619 MAYBE_UNALIGNED_WRITE(pNative, 32, MAYBE_UNALIGNED_READ(pCLR, 32));
1623 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1630 PRECONDITION(CheckPointer(pCLR));
1631 PRECONDITION(CheckPointer(pNative));
1635 MAYBE_UNALIGNED_WRITE(pCLR, 32, MAYBE_UNALIGNED_READ(pNative, 32));
1641 class FieldMarshaler_Copy8 : public FieldMarshaler
1645 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1646 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1648 #if defined(_TARGET_X86_) && defined(UNIX_X86_ABI)
1649 // The System V ABI for i386 defines 4-byte alignment for 64-bit types.
1650 SCALAR_MARSHALER_IMPL(8, 4)
1652 SCALAR_MARSHALER_IMPL(8, 8)
1653 #endif // _TARGET_X86_
1655 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1657 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1664 PRECONDITION(CheckPointer(pCLR));
1665 PRECONDITION(CheckPointer(pNative));
1669 MAYBE_UNALIGNED_WRITE(pNative, 64, MAYBE_UNALIGNED_READ(pCLR, 64));
1673 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1680 PRECONDITION(CheckPointer(pCLR));
1681 PRECONDITION(CheckPointer(pNative));
1685 MAYBE_UNALIGNED_WRITE(pCLR, 64, MAYBE_UNALIGNED_READ(pNative, 64));
1692 class FieldMarshaler_Ansi : public FieldMarshaler
1695 FieldMarshaler_Ansi(BOOL BestFitMap, BOOL ThrowOnUnmappableChar) :
1696 m_BestFitMap(!!BestFitMap), m_ThrowOnUnmappableChar(!!ThrowOnUnmappableChar)
1698 WRAPPER_NO_CONTRACT;
1701 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1702 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1704 SCALAR_MARSHALER_IMPL(sizeof(CHAR), sizeof(CHAR))
1706 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1713 PRECONDITION(CheckPointer(pCLR, NULL_OK));
1714 PRECONDITION(CheckPointer(pNative));
1719 InternalWideToAnsi((LPCWSTR)pCLR,
1724 m_ThrowOnUnmappableChar);
1726 *((char*)pNative) = c;
1729 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1736 PRECONDITION(CheckPointer(pCLR));
1737 PRECONDITION(CheckPointer(pNative));
1741 MultiByteToWideChar(CP_ACP, 0, (char*)pNative, 1, (LPWSTR)pCLR, 1);
1746 LIMITED_METHOD_CONTRACT;
1747 return m_BestFitMap;
1750 BOOL GetThrowOnUnmappableChar()
1752 LIMITED_METHOD_CONTRACT;
1753 return m_ThrowOnUnmappableChar;
1756 START_COPY_TO_IMPL(FieldMarshaler_Ansi)
1758 pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
1759 pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
1761 END_COPY_TO_IMPL(FieldMarshaler_Ansi)
1764 bool m_BestFitMap:1;
1765 bool m_ThrowOnUnmappableChar:1;
1770 class FieldMarshaler_WinBool : public FieldMarshaler
1774 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1775 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1777 SCALAR_MARSHALER_IMPL(sizeof(BOOL), sizeof(BOOL))
1778 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1780 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1787 PRECONDITION(CheckPointer(pCLR));
1788 PRECONDITION(CheckPointer(pNative));
1791 static_assert_no_msg(sizeof(BOOL) == sizeof(UINT32));
1792 MAYBE_UNALIGNED_WRITE(pNative, 32, ((*((U1 UNALIGNED*)pCLR)) ? 1 : 0));
1796 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1803 PRECONDITION(CheckPointer(pCLR));
1804 PRECONDITION(CheckPointer(pNative));
1808 static_assert_no_msg(sizeof(BOOL) == sizeof(UINT32));
1809 *((U1*)pCLR) = MAYBE_UNALIGNED_READ(pNative, 32) ? 1 : 0;
1816 #ifdef FEATURE_COMINTEROP
1818 class FieldMarshaler_VariantBool : public FieldMarshaler
1822 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1823 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1825 SCALAR_MARSHALER_IMPL(sizeof(VARIANT_BOOL), sizeof(VARIANT_BOOL))
1826 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1828 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1835 PRECONDITION(CheckPointer(pCLR));
1836 PRECONDITION(CheckPointer(pNative));
1840 static_assert_no_msg(sizeof(VARIANT_BOOL) == sizeof(BYTE) * 2);
1842 MAYBE_UNALIGNED_WRITE(pNative, 16, (*((U1*)pCLR)) ? VARIANT_TRUE : VARIANT_FALSE);
1846 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1853 PRECONDITION(CheckPointer(pCLR));
1854 PRECONDITION(CheckPointer(pNative));
1858 static_assert_no_msg(sizeof(VARIANT_BOOL) == sizeof(BYTE) * 2);
1860 *((U1*)pCLR) = MAYBE_UNALIGNED_READ(pNative, 16) ? 1 : 0;
1865 #endif // FEATURE_COMINTEROP
1869 class FieldMarshaler_CBool : public FieldMarshaler
1873 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1874 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1876 SCALAR_MARSHALER_IMPL(1, 1)
1877 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1879 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1886 PRECONDITION(CheckPointer(pCLR));
1887 PRECONDITION(CheckPointer(pNative));
1891 *((U1*)pNative) = (*((U1*)pCLR)) ? 1 : 0;
1894 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1901 PRECONDITION(CheckPointer(pCLR));
1902 PRECONDITION(CheckPointer(pNative));
1906 *((U1*)pCLR) = (*((U1*)pNative)) ? 1 : 0;
1912 class FieldMarshaler_Decimal : public FieldMarshaler
1915 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1916 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1918 SCALAR_MARSHALER_IMPL(sizeof(DECIMAL), 8);
1919 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1921 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
1928 PRECONDITION(CheckPointer(pCLR));
1929 PRECONDITION(CheckPointer(pNative));
1933 memcpyNoGCRefs(pNative, pCLR, sizeof(DECIMAL));
1936 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const
1943 PRECONDITION(CheckPointer(pCLR));
1944 PRECONDITION(CheckPointer(pNative));
1948 memcpyNoGCRefs(pCLR, pNative, sizeof(DECIMAL));
1953 class FieldMarshaler_Date : public FieldMarshaler
1957 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1958 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1960 SCALAR_MARSHALER_IMPL(sizeof(DATE), sizeof(DATE))
1961 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1963 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
1964 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
1970 #ifdef FEATURE_COMINTEROP
1972 class FieldMarshaler_Currency : public FieldMarshaler
1976 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1977 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1979 SCALAR_MARSHALER_IMPL(sizeof(CURRENCY), sizeof(CURRENCY))
1980 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1982 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
1983 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
1987 class FieldMarshaler_DateTimeOffset : public FieldMarshaler
1991 UNUSED_METHOD_IMPL(VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const)
1992 UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
1994 SCALAR_MARSHALER_IMPL(sizeof(INT64), sizeof(INT64))
1995 COPY_TO_IMPL_BASE_STRUCT_ONLY()
1997 VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
1998 VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
2002 #endif // FEATURE_COMINTEROP
2005 //========================================================================
2006 // Used to ensure that native data is properly deleted in exception cases.
2007 //========================================================================
2008 class NativeLayoutDestroyer
2011 NativeLayoutDestroyer(BYTE* pNativeData, MethodTable* pMT, UINT32 cbSize)
2018 PRECONDITION(CheckPointer(pNativeData));
2019 PRECONDITION(CheckPointer(pMT));
2023 m_pNativeData = pNativeData;
2029 ~NativeLayoutDestroyer()
2031 WRAPPER_NO_CONTRACT;
2035 LayoutDestroyNative(m_pNativeData, m_pMT);
2036 FillMemory(m_pNativeData, m_cbSize, 0);
2040 void SuppressRelease()
2046 NativeLayoutDestroyer()
2048 LIMITED_METHOD_CONTRACT;
2051 BYTE* m_pNativeData;
2057 #endif // DACCESS_COMPILE
2060 #endif // __FieldMarshaler_h__