Remove always defined FEATURE_CORECLR
[platform/upstream/coreclr.git] / src / vm / object.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 //
5 // OBJECT.H
6 //
7 // Definitions of a Com+ Object
8 // 
9
10 // See code:EEStartup#TableOfContents for overview
11
12
13 #ifndef _OBJECT_H_
14 #define _OBJECT_H_
15
16 #include "util.hpp"
17 #include "syncblk.h"
18 #include "gcdesc.h"
19 #include "specialstatics.h"
20 #include "sstring.h"
21 #include "daccess.h"
22 #include "fcall.h"
23
24 extern "C" void __fastcall ZeroMemoryInGCHeap(void*, size_t);
25
26 void ErectWriteBarrierForMT(MethodTable **dst, MethodTable *ref);
27
28 /*
29  #ObjectModel 
30  * COM+ Internal Object Model
31  *
32  *
33  * Object              - This is the common base part to all COM+ objects
34  *  |                        it contains the MethodTable pointer and the
35  *  |                        sync block index, which is at a negative offset
36  *  |
37  *  +-- code:StringObject       - String objects are specialized objects for string
38  *  |                        storage/retrieval for higher performance
39  *  |
40  *  +-- code:StringBufferObject - StringBuffer instance layout.  
41  *  |
42  *  +-- BaseObjectWithCachedData - Object Plus one object field for caching.
43  *  |       |
44  *  |            +-  ReflectClassBaseObject    - The base object for the RuntimeType class
45  *  |            +-  ReflectMethodObject       - The base object for the RuntimeMethodInfo class
46  *  |            +-  ReflectFieldObject        - The base object for the RtFieldInfo class
47  *  |
48  *  +-- code:ArrayBase          - Base portion of all arrays
49  *  |       |
50  *  |       +-  I1Array    - Base type arrays
51  *  |       |   I2Array
52  *  |       |   ...
53  *  |       |
54  *  |       +-  PtrArray   - Array of OBJECTREFs, different than base arrays because of pObjectClass
55  *  |              
56  *  +-- code:AppDomainBaseObject - The base object for the class AppDomain
57  *  |              
58  *  +-- code:AssemblyBaseObject - The base object for the class Assembly
59  *  |
60  *  +-- code:ContextBaseObject   - base object for class Context
61  *
62  *
63  * PLEASE NOTE THE FOLLOWING WHEN ADDING A NEW OBJECT TYPE:
64  *
65  *    The size of the object in the heap must be able to be computed
66  *    very, very quickly for GC purposes.   Restrictions on the layout
67  *    of the object guarantee this is possible.
68  *
69  *    Any object that inherits from Object must be able to
70  *    compute its complete size by using the first 4 bytes of
71  *    the object following the Object part and constants
72  *    reachable from the MethodTable...
73  *
74  *    The formula used for this calculation is:
75  *        MT->GetBaseSize() + ((OBJECTTYPEREF->GetSizeField() * MT->GetComponentSize())
76  *
77  *    So for Object, since this is of fixed size, the ComponentSize is 0, which makes the right side
78  *    of the equation above equal to 0 no matter what the value of GetSizeField(), so the size is just the base size.
79  *
80  */
81
82 // <TODO>
83 // @TODO:  #define COW         0x04     
84 // @TODO: MOO, MOO - no, not bovine, really Copy On Write bit for StringBuffer, requires 8 byte align MT
85 // @TODL: which we don't have yet</TODO>
86
87 class MethodTable;
88 class Thread;
89 class BaseDomain;
90 class Assembly;
91 class Context;
92 class CtxStaticData;
93 class DomainAssembly;
94 class AssemblyNative;
95 class WaitHandleNative;
96 class ArgDestination;
97
98 struct RCW;
99
100 #if CHECK_APP_DOMAIN_LEAKS
101
102 class Object;
103
104 class SetAppDomainAgilePendingTable
105 {
106 public:
107
108     SetAppDomainAgilePendingTable ();
109     ~SetAppDomainAgilePendingTable ();
110
111     void PushReference (Object *pObject)
112     {
113         STATIC_CONTRACT_THROWS;
114         STATIC_CONTRACT_GC_NOTRIGGER;
115
116         PendingEntry entry;
117         entry.pObject = pObject;
118
119         m_Stack.Push(entry);
120     }
121
122     void PushParent (Object *pObject)
123     {
124         STATIC_CONTRACT_THROWS;
125         STATIC_CONTRACT_GC_NOTRIGGER;
126
127         PendingEntry entry;
128         entry.pObject = (Object*)((size_t)pObject | 1);
129
130         m_Stack.Push(entry);
131     }
132
133     Object *GetPendingObject (bool *pfReturnedToParent)
134     {
135         STATIC_CONTRACT_THROWS;
136         STATIC_CONTRACT_GC_NOTRIGGER;
137
138         if (!m_Stack.Count())
139             return NULL;
140
141         PendingEntry *pPending = m_Stack.Pop();
142
143         *pfReturnedToParent = pPending->fMarked != 0;
144         return (Object*)((size_t)pPending->pObject & ~1);
145     }
146
147 private:
148
149     union PendingEntry
150     {
151         Object *pObject;
152
153         // Indicates whether the current thread set BIT_SBLK_AGILE_IN_PROGRESS
154         // on the object.  Entries without this flag set are unexplored
155         // objects.
156         size_t fMarked:1;
157     };
158
159     CStackArray<PendingEntry> m_Stack;
160 };
161
162 #endif //CHECK_APP_DOMAIN_LEAKS
163
164
165 //
166 // The generational GC requires that every object be at least 12 bytes
167 // in size.   
168
169 #define MIN_OBJECT_SIZE     (2*sizeof(BYTE*) + sizeof(ObjHeader))
170
171 #define PTRALIGNCONST (DATA_ALIGNMENT-1)
172
173 #ifndef PtrAlign
174 #define PtrAlign(size) \
175     ((size + PTRALIGNCONST) & (~PTRALIGNCONST))
176 #endif //!PtrAlign
177
178 // code:Object is the respesentation of an managed object on the GC heap.
179 //   
180 // See  code:#ObjectModel for some important subclasses of code:Object 
181 // 
182 // The only fields mandated by all objects are
183 // 
184 //     * a pointer to the code:MethodTable at offset 0
185 //     * a poiner to a code:ObjHeader at a negative offset. This is often zero.  It holds information that
186 //         any addition information that we might need to attach to arbitrary objects. 
187 // 
188 class Object
189 {
190   protected:
191     PTR_MethodTable m_pMethTab;
192
193   protected:
194     Object() { LIMITED_METHOD_CONTRACT; };
195    ~Object() { LIMITED_METHOD_CONTRACT; };
196    
197   public:
198     MethodTable *RawGetMethodTable() const
199     {
200         return m_pMethTab;
201     }
202
203 #ifndef DACCESS_COMPILE
204     void RawSetMethodTable(MethodTable *pMT)
205     {
206         LIMITED_METHOD_CONTRACT;
207         m_pMethTab = pMT;
208     }
209
210     VOID SetMethodTable(MethodTable *pMT)
211     { 
212         LIMITED_METHOD_CONTRACT;
213         m_pMethTab = pMT; 
214     }
215
216     VOID SetMethodTableForLargeObject(MethodTable *pMT)
217     {
218         // This function must be used if the allocation occurs on the large object heap, and the method table might be a collectible type
219         WRAPPER_NO_CONTRACT;
220         ErectWriteBarrierForMT(&m_pMethTab, pMT);
221     }
222  
223 #endif //!DACCESS_COMPILE
224
225     // An object might be a proxy of some sort, with a thunking VTable.  If so, we can
226     // advance to the true method table or class.
227     BOOL            IsTransparentProxy()                        
228     { 
229 #ifdef FEATURE_REMOTING
230         WRAPPER_NO_CONTRACT;
231         return( GetMethodTable()->IsTransparentProxy() );
232 #else
233         LIMITED_METHOD_CONTRACT;
234         return FALSE;
235 #endif
236     }
237
238 #define MARKED_BIT 0x1
239
240     PTR_MethodTable GetMethodTable() const              
241     { 
242         LIMITED_METHOD_DAC_CONTRACT;
243
244 #ifndef DACCESS_COMPILE
245         // We should always use GetGCSafeMethodTable() if we're running during a GC. 
246         // If the mark bit is set then we're running during a GC     
247         _ASSERTE((dac_cast<TADDR>(m_pMethTab) & MARKED_BIT) == 0);
248
249         return m_pMethTab;
250 #else //DACCESS_COMPILE
251
252         //@dbgtodo dharvey Make this a type which supports bitwise and operations
253         //when available
254         return PTR_MethodTable((dac_cast<TADDR>(m_pMethTab)) & (~MARKED_BIT));
255 #endif //DACCESS_COMPILE
256     }
257
258     DPTR(PTR_MethodTable) GetMethodTablePtr() const
259     {
260         LIMITED_METHOD_CONTRACT;
261         return dac_cast<DPTR(PTR_MethodTable)>(PTR_HOST_MEMBER_TADDR(Object, this, m_pMethTab));
262     }
263
264     MethodTable    *GetTrueMethodTable();
265     
266     TypeHandle      GetTypeHandle();
267     TypeHandle      GetTrueTypeHandle();
268
269         // Methods used to determine if an object supports a given interface.
270     static BOOL     SupportsInterface(OBJECTREF pObj, MethodTable *pInterfaceMT);
271
272     inline DWORD    GetNumComponents();
273     inline SIZE_T   GetSize();
274
275     CGCDesc*        GetSlotMap()                        
276     { 
277         WRAPPER_NO_CONTRACT;
278         return( CGCDesc::GetCGCDescFromMT(GetMethodTable())); 
279     }
280
281     // Sync Block & Synchronization services
282
283     // Access the ObjHeader which is at a negative offset on the object (because of
284     // cache lines)
285     PTR_ObjHeader   GetHeader()
286     {
287         LIMITED_METHOD_DAC_CONTRACT;
288         return dac_cast<PTR_ObjHeader>(this) - 1;
289     }
290
291     // Get the current address of the object (works for debug refs, too.)
292     PTR_BYTE      GetAddress()
293     {
294         LIMITED_METHOD_DAC_CONTRACT;
295         return dac_cast<PTR_BYTE>(this);
296     }
297
298 #ifdef _DEBUG
299     // TRUE if the header has a real SyncBlockIndex (i.e. it has an entry in the
300     // SyncTable, though it doesn't necessarily have an entry in the SyncBlockCache)
301     BOOL HasEmptySyncBlockInfo()
302     {
303         WRAPPER_NO_CONTRACT;
304         return GetHeader()->HasEmptySyncBlockInfo();
305     }
306 #endif
307
308     // retrieve or allocate a sync block for this object
309     SyncBlock *GetSyncBlock()
310     {
311         WRAPPER_NO_CONTRACT;
312         return GetHeader()->GetSyncBlock();
313     }
314
315     DWORD GetSyncBlockIndex()
316     {
317         WRAPPER_NO_CONTRACT;
318         return GetHeader()->GetSyncBlockIndex();
319     }
320
321     ADIndex GetAppDomainIndex();
322
323     // Get app domain of object, or NULL if it is agile
324     AppDomain *GetAppDomain();
325
326 #ifndef DACCESS_COMPILE
327     // Set app domain of object to current domain.
328     void SetAppDomain() { WRAPPER_NO_CONTRACT; SetAppDomain(::GetAppDomain()); }
329     BOOL SetAppDomainNoThrow();
330     
331 #endif
332
333     // Set app domain of object to given domain - it can only be set once
334     void SetAppDomain(AppDomain *pDomain);
335
336 #ifdef _DEBUG
337 #ifndef DACCESS_COMPILE
338     // For SO-tolerance contract violation purposes, define these DEBUG_ versions to identify
339     // the codepaths to SetAppDomain that are called only from DEBUG code.
340     void DEBUG_SetAppDomain()
341     {
342         WRAPPER_NO_CONTRACT;
343
344         DEBUG_SetAppDomain(::GetAppDomain());
345     }
346 #endif //!DACCESS_COMPILE
347
348     void DEBUG_SetAppDomain(AppDomain *pDomain);
349 #endif //_DEBUG
350     
351 #if CHECK_APP_DOMAIN_LEAKS
352
353     // Mark object as app domain agile
354     BOOL SetAppDomainAgile(BOOL raiseAssert=TRUE, SetAppDomainAgilePendingTable *pTable = NULL);
355     BOOL TrySetAppDomainAgile(BOOL raiseAssert=TRUE);
356
357     // Mark sync block as app domain agile
358     void SetSyncBlockAppDomainAgile();
359
360     // Check if object is app domain agile
361     BOOL IsAppDomainAgile();
362
363     // Check if object is app domain agile
364     BOOL IsAppDomainAgileRaw()
365     {
366         WRAPPER_NO_CONTRACT;
367
368         SyncBlock *psb = PassiveGetSyncBlock();
369
370         return (psb && psb->IsAppDomainAgile());
371     }
372
373     BOOL IsCheckedForAppDomainAgile()
374     {
375         WRAPPER_NO_CONTRACT;
376
377         SyncBlock *psb = PassiveGetSyncBlock();
378         return (psb && psb->IsCheckedForAppDomainAgile());
379     }
380
381     void SetIsCheckedForAppDomainAgile()
382     {
383         WRAPPER_NO_CONTRACT;
384
385         SyncBlock *psb = PassiveGetSyncBlock();
386         if (psb)
387             psb->SetIsCheckedForAppDomainAgile();
388     }
389
390     // Check object to see if it is usable in the current domain 
391     BOOL CheckAppDomain() { WRAPPER_NO_CONTRACT; return CheckAppDomain(::GetAppDomain()); }
392
393     //Check object to see if it is usable in the given domain 
394     BOOL CheckAppDomain(AppDomain *pDomain);
395
396     // Check if the object's type is app domain agile
397     BOOL IsTypeAppDomainAgile();
398
399     // Check if the object's type is conditionally app domain agile
400     BOOL IsTypeCheckAppDomainAgile();
401
402     // Check if the object's type is naturally app domain agile
403     BOOL IsTypeTypesafeAppDomainAgile();
404
405     // Check if the object's type is possibly app domain agile
406     BOOL IsTypeNeverAppDomainAgile();
407
408     // Validate object & fields to see that it's usable from the current app domain
409     BOOL ValidateAppDomain() { WRAPPER_NO_CONTRACT; return ValidateAppDomain(::GetAppDomain()); }
410
411     // Validate object & fields to see that it's usable from any app domain
412     BOOL ValidateAppDomainAgile() { WRAPPER_NO_CONTRACT; return ValidateAppDomain(NULL); }
413
414     // Validate object & fields to see that it's usable from the given app domain (or null for agile)
415     BOOL ValidateAppDomain(AppDomain *pAppDomain);
416
417     // Validate fields to see that they are usable from the object's app domain 
418     // (or from any domain if the object is agile)
419     BOOL ValidateAppDomainFields() { WRAPPER_NO_CONTRACT; return ValidateAppDomainFields(GetAppDomain()); }
420
421     // Validate fields to see that they are usable from the given app domain (or null for agile)
422     BOOL ValidateAppDomainFields(AppDomain *pAppDomain);
423
424     // Validate a value type's fields to see that it's usable from the current app domain
425     static BOOL ValidateValueTypeAppDomain(MethodTable *pMT, void *base, BOOL raiseAssert = TRUE) 
426       { WRAPPER_NO_CONTRACT; return ValidateValueTypeAppDomain(pMT, base, ::GetAppDomain(), raiseAssert); }
427
428     // Validate a value type's fields to see that it's usable from any app domain
429     static BOOL ValidateValueTypeAppDomainAgile(MethodTable *pMT, void *base, BOOL raiseAssert = TRUE) 
430       { WRAPPER_NO_CONTRACT; return ValidateValueTypeAppDomain(pMT, base, NULL, raiseAssert); }
431
432     // Validate a value type's fields to see that it's usable from the given app domain (or null for agile)
433     static BOOL ValidateValueTypeAppDomain(MethodTable *pMT, void *base, AppDomain *pAppDomain, BOOL raiseAssert = TRUE);
434
435     // Call when we are assigning this object to a dangerous field 
436     // in an object in a given app domain (or agile if null)
437     BOOL AssignAppDomain(AppDomain *pAppDomain, BOOL raiseAssert = TRUE);
438     BOOL TryAssignAppDomain(AppDomain *pAppDomain, BOOL raiseAssert = TRUE);
439
440     // Call when we are assigning to a dangerous value type field 
441     // in an object in a given app domain (or agile if null)
442     static BOOL AssignValueTypeAppDomain(MethodTable *pMT, void *base, AppDomain *pAppDomain, BOOL raiseAssert = TRUE);
443
444 #endif // CHECK_APP_DOMAIN_LEAKS
445
446     // DO NOT ADD ANY ASSERTS TO THIS METHOD.
447     // DO NOT USE THIS METHOD.
448     // Yes folks, for better or worse the debugger pokes supposed object addresses 
449     // to try to see if objects are valid, possibly firing an AccessViolation or worse,
450     // and then catches the AV and reports a failure to the debug client.  This makes
451     // the debugger slightly more robust should any corrupted object references appear
452     // in a session. Thus it is "correct" behaviour for this to AV when used with 
453     // an invalid object pointer, and incorrect behaviour for it to
454     // assert.  
455     BOOL ValidateObjectWithPossibleAV();
456
457     // Validate an object ref out of the Promote routine in the GC
458     void ValidatePromote(ScanContext *sc, DWORD flags);
459
460     // Validate an object ref out of the VerifyHeap routine in the GC
461     void ValidateHeap(Object *from, BOOL bDeep=TRUE);
462
463     PTR_SyncBlock PassiveGetSyncBlock()
464     {
465         LIMITED_METHOD_DAC_CONTRACT;
466         return GetHeader()->PassiveGetSyncBlock();
467     }
468
469     static DWORD ComputeHashCode();
470
471 #ifndef DACCESS_COMPILE    
472     INT32 GetHashCodeEx();
473 #endif // #ifndef DACCESS_COMPILE
474     
475     // Synchronization
476 #ifndef DACCESS_COMPILE
477
478     void EnterObjMonitor()
479     {
480         WRAPPER_NO_CONTRACT;
481         GetHeader()->EnterObjMonitor();
482     }
483
484     BOOL TryEnterObjMonitor(INT32 timeOut = 0)
485     {
486         WRAPPER_NO_CONTRACT;
487         return GetHeader()->TryEnterObjMonitor(timeOut);
488     }
489
490     FORCEINLINE AwareLock::EnterHelperResult EnterObjMonitorHelper(Thread* pCurThread)
491     {
492         WRAPPER_NO_CONTRACT;
493         return GetHeader()->EnterObjMonitorHelper(pCurThread);
494     }
495
496     FORCEINLINE AwareLock::EnterHelperResult EnterObjMonitorHelperSpin(Thread* pCurThread)
497     {
498         WRAPPER_NO_CONTRACT;
499         return GetHeader()->EnterObjMonitorHelperSpin(pCurThread);
500     }
501
502     BOOL LeaveObjMonitor()
503     {
504         WRAPPER_NO_CONTRACT;
505         return GetHeader()->LeaveObjMonitor();
506     }
507     
508     // should be called only from unwind code; used in the
509     // case where EnterObjMonitor failed to allocate the
510     // sync-object.
511     BOOL LeaveObjMonitorAtException()
512     {
513         WRAPPER_NO_CONTRACT;
514         return GetHeader()->LeaveObjMonitorAtException();
515     }
516
517     FORCEINLINE AwareLock::LeaveHelperAction LeaveObjMonitorHelper(Thread* pCurThread)
518     {
519         WRAPPER_NO_CONTRACT;
520         return GetHeader()->LeaveObjMonitorHelper(pCurThread);
521     }
522
523     // Returns TRUE if the lock is owned and FALSE otherwise
524     // threadId is set to the ID (Thread::GetThreadId()) of the thread which owns the lock
525     // acquisitionCount is set to the number of times the lock needs to be released before
526     // it is unowned
527     BOOL GetThreadOwningMonitorLock(DWORD *pThreadId, DWORD *pAcquisitionCount)
528     {
529         WRAPPER_NO_CONTRACT;
530         SUPPORTS_DAC;
531         return GetHeader()->GetThreadOwningMonitorLock(pThreadId, pAcquisitionCount);
532     }
533
534 #endif // #ifndef DACCESS_COMPILE
535
536     BOOL Wait(INT32 timeOut, BOOL exitContext)
537     {
538         WRAPPER_NO_CONTRACT;
539         return GetHeader()->Wait(timeOut, exitContext);
540     }
541
542     void Pulse()
543     {
544         WRAPPER_NO_CONTRACT;
545         GetHeader()->Pulse();
546     }
547
548     void PulseAll()
549     {
550         WRAPPER_NO_CONTRACT;
551         GetHeader()->PulseAll();
552     }
553
554    PTR_VOID UnBox();      // if it is a value class, get the pointer to the first field
555   
556     PTR_BYTE   GetData(void)
557     {
558         LIMITED_METHOD_CONTRACT;
559         SUPPORTS_DAC;
560         return dac_cast<PTR_BYTE>(this) + sizeof(Object);
561     }
562
563     static UINT GetOffsetOfFirstField()
564     {
565         LIMITED_METHOD_CONTRACT;
566         return sizeof(Object);
567     }
568
569     DWORD   GetOffset32(DWORD dwOffset)
570     { 
571         WRAPPER_NO_CONTRACT;
572         return * PTR_DWORD(GetData() + dwOffset);
573     }
574
575     USHORT  GetOffset16(DWORD dwOffset)
576     { 
577         WRAPPER_NO_CONTRACT;
578         return * PTR_USHORT(GetData() + dwOffset);
579     }
580
581     BYTE    GetOffset8(DWORD dwOffset)
582     { 
583         WRAPPER_NO_CONTRACT;
584         return * PTR_BYTE(GetData() + dwOffset);
585     }
586
587     __int64 GetOffset64(DWORD dwOffset)
588     { 
589         WRAPPER_NO_CONTRACT;
590         return (__int64) * PTR_ULONG64(GetData() + dwOffset);
591     }
592
593     void *GetPtrOffset(DWORD dwOffset)
594     {
595         WRAPPER_NO_CONTRACT;
596         return (void *)(TADDR)*PTR_TADDR(GetData() + dwOffset);
597     }
598
599 #ifndef DACCESS_COMPILE
600     
601     void SetOffsetObjectRef(DWORD dwOffset, size_t dwValue);
602
603     void SetOffsetPtr(DWORD dwOffset, LPVOID value)
604     {
605         WRAPPER_NO_CONTRACT;
606         *(LPVOID *) &GetData()[dwOffset] = value;
607     }
608         
609     void SetOffset32(DWORD dwOffset, DWORD dwValue)
610     { 
611         WRAPPER_NO_CONTRACT;
612         *(DWORD *) &GetData()[dwOffset] = dwValue;
613     }
614
615     void SetOffset16(DWORD dwOffset, DWORD dwValue)
616     { 
617         WRAPPER_NO_CONTRACT;
618         *(USHORT *) &GetData()[dwOffset] = (USHORT) dwValue;
619     }
620
621     void SetOffset8(DWORD dwOffset, DWORD dwValue)
622     { 
623         WRAPPER_NO_CONTRACT;
624         *(BYTE *) &GetData()[dwOffset] = (BYTE) dwValue;
625     }
626
627     void SetOffset64(DWORD dwOffset, __int64 qwValue)
628     { 
629         WRAPPER_NO_CONTRACT;
630         *(__int64 *) &GetData()[dwOffset] = qwValue;
631     }
632
633 #endif // #ifndef DACCESS_COMPILE
634
635     VOID            Validate(BOOL bDeep = TRUE, BOOL bVerifyNextHeader = TRUE, BOOL bVerifySyncBlock = TRUE);
636
637     PTR_MethodTable GetGCSafeMethodTable() const
638     {
639         LIMITED_METHOD_CONTRACT;
640         SUPPORTS_DAC;
641
642         // lose GC marking bit and the pinning bit
643         // A method table pointer should always be aligned.  During GC we set the least 
644         // significant bit for marked objects and we set the second to least significant
645         // bit for pinned objects.  So if we want the actual MT pointer during a GC
646         // we must zero out the lowest 2 bits.
647         return dac_cast<PTR_MethodTable>((dac_cast<TADDR>(m_pMethTab)) & ~((UINT_PTR)3));
648     }
649
650     // There are some cases where it is unsafe to get the type handle during a GC.
651     // This occurs when the type has already been unloaded as part of an in-progress appdomain shutdown.
652     TypeHandle GetGCSafeTypeHandleIfPossible() const;
653     
654     inline TypeHandle GetGCSafeTypeHandle() const;
655
656 #ifdef DACCESS_COMPILE
657     void EnumMemoryRegions(void);
658 #endif
659     
660  private:
661     VOID ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncBlock);
662
663 #if CHECK_APP_DOMAIN_LEAKS
664     friend class ObjHeader;
665     BOOL SetFieldsAgile(BOOL raiseAssert = TRUE, SetAppDomainAgilePendingTable *pTable = NULL);
666     static BOOL SetClassFieldsAgile(MethodTable *pMT, void *base, BOOL baseIsVT, BOOL raiseAssert = TRUE, SetAppDomainAgilePendingTable *pTable = NULL); 
667     static BOOL ValidateClassFields(MethodTable *pMT, void *base, BOOL baseIsVT, AppDomain *pAppDomain, BOOL raiseAssert = TRUE);
668     BOOL SetAppDomainAgileWorker(BOOL raiseAssert, SetAppDomainAgilePendingTable *pTable);
669     BOOL ShouldCheckAppDomainAgile(BOOL raiseAssert, BOOL *pfResult);
670 #endif
671
672 };
673
674 /*
675  * Object ref setting routines.  You must use these to do 
676  * proper write barrier support, as well as app domain 
677  * leak checking.
678  *
679  * Note that the AppDomain parameter is the app domain affinity
680  * of the object containing the field or value class.  It should
681  * be NULL if the containing object is app domain agile. Note that
682  * you typically get this value by calling obj->GetAppDomain() on 
683  * the containing object.
684  */
685
686 // SetObjectReference sets an OBJECTREF field
687
688 void SetObjectReferenceUnchecked(OBJECTREF *dst,OBJECTREF ref);
689
690 #ifdef _DEBUG
691 void EnableStressHeapHelper();
692 #endif
693
694 //Used to clear the object reference
695 inline void ClearObjectReference(OBJECTREF* dst) 
696
697     LIMITED_METHOD_CONTRACT;
698     *(void**)(dst) = NULL; 
699 }
700
701 // CopyValueClass sets a value class field
702
703 void STDCALL CopyValueClassUnchecked(void* dest, void* src, MethodTable *pMT);
704 void STDCALL CopyValueClassArgUnchecked(ArgDestination *argDest, void* src, MethodTable *pMT, int destOffset);
705
706 inline void InitValueClass(void *dest, MethodTable *pMT)
707
708     WRAPPER_NO_CONTRACT;
709     ZeroMemoryInGCHeap(dest, pMT->GetNumInstanceFieldBytes());
710 }
711
712 // Initialize value class argument
713 void InitValueClassArg(ArgDestination *argDest, MethodTable *pMT);
714
715 #if CHECK_APP_DOMAIN_LEAKS
716
717 void SetObjectReferenceChecked(OBJECTREF *dst,OBJECTREF ref, AppDomain *pAppDomain);
718 void CopyValueClassChecked(void* dest, void* src, MethodTable *pMT, AppDomain *pAppDomain);
719 void CopyValueClassArgChecked(ArgDestination *argDest, void* src, MethodTable *pMT, AppDomain *pAppDomain, int destOffset);
720
721 #define SetObjectReference(_d,_r,_a)        SetObjectReferenceChecked(_d, _r, _a)
722 #define CopyValueClass(_d,_s,_m,_a)         CopyValueClassChecked(_d,_s,_m,_a)      
723 #define CopyValueClassArg(_d,_s,_m,_a,_o)   CopyValueClassArgChecked(_d,_s,_m,_a,_o)      
724
725 #else
726
727 #define SetObjectReference(_d,_r,_a)        SetObjectReferenceUnchecked(_d, _r)
728 #define CopyValueClass(_d,_s,_m,_a)         CopyValueClassUnchecked(_d,_s,_m)       
729 #define CopyValueClassArg(_d,_s,_m,_a,_o)   CopyValueClassArgUnchecked(_d,_s,_m,_o)       
730
731 #endif
732
733 #include <pshpack4.h>
734
735
736 // There are two basic kinds of array layouts in COM+
737 //      ELEMENT_TYPE_ARRAY  - a multidimensional array with lower bounds on the dims
738 //      ELMENNT_TYPE_SZARRAY - A zero based single dimensional array
739 //
740 // In addition the layout of an array in memory is also affected by
741 // whether the method table is shared (eg in the case of arrays of object refs)
742 // or not.  In the shared case, the array has to hold the type handle of
743 // the element type.  
744 //
745 // ArrayBase encapuslates all of these details.  In theory you should never
746 // have to peek inside this abstraction
747 //
748 class ArrayBase : public Object
749 {
750     friend class GCHeap;
751     friend class CObjectHeader;
752     friend class Object;
753     friend OBJECTREF AllocateArrayEx(TypeHandle arrayClass, INT32 *pArgs, DWORD dwNumArgs, BOOL bAllocateInLargeHeap DEBUG_ARG(BOOL bDontSetAppDomain)); 
754     friend OBJECTREF FastAllocatePrimitiveArray(MethodTable* arrayType, DWORD cElements, BOOL bAllocateInLargeHeap);
755     friend FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
756     friend FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
757     friend class JIT_TrialAlloc;
758     friend class CheckAsmOffsets;
759     friend struct _DacGlobals;
760
761 private:
762     // This MUST be the first field, so that it directly follows Object.  This is because
763     // Object::GetSize() looks at m_NumComponents even though it may not be an array (the
764     // values is shifted out if not an array, so it's ok). 
765     DWORD       m_NumComponents;
766 #ifdef _WIN64
767     DWORD       pad;
768 #endif // _WIN64
769
770     SVAL_DECL(INT32, s_arrayBoundsZero); // = 0
771
772     // What comes after this conceputally is:
773     // TypeHandle elementType;        Only present if the method table is shared among many types (arrays of pointers)
774     // INT32      bounds[rank];       The bounds are only present for Multidimensional arrays   
775     // INT32      lowerBounds[rank];  Valid indexes are lowerBounds[i] <= index[i] < lowerBounds[i] + bounds[i]
776
777 public:
778     // Gets the unique type handle for this array object.
779     // This will call the loader in don't-load mode - the allocator
780     // always makes sure that the particular ArrayTypeDesc for this array
781     // type is available before allocating any instances of this array type.
782     inline TypeHandle GetTypeHandle() const;
783
784     inline static TypeHandle GetTypeHandle(MethodTable * pMT);
785
786     // Get the element type for the array, this works whether the the element
787     // type is stored in the array or not
788     inline TypeHandle GetArrayElementTypeHandle() const;
789
790         // Get the CorElementType for the elements in the array.  Avoids creating a TypeHandle
791     inline CorElementType GetArrayElementType() const;
792
793     inline unsigned GetRank() const;
794
795         // Total element count for the array
796     inline DWORD GetNumComponents() const;
797
798         // Get pointer to elements, handles any number of dimensions
799     PTR_BYTE GetDataPtr(BOOL inGC = FALSE) const {
800         LIMITED_METHOD_CONTRACT;
801         SUPPORTS_DAC;
802 #ifdef _DEBUG
803 #ifndef DACCESS_COMPILE
804         EnableStressHeapHelper();
805 #endif
806 #endif
807         return dac_cast<PTR_BYTE>(this) +
808                         GetDataPtrOffset(inGC ? GetGCSafeMethodTable() : GetMethodTable());
809     }
810
811     // The component size is actually 16-bit WORD, but this method is returning SIZE_T to ensure
812     // that SIZE_T is used everywhere for object size computation. It is necessary to support
813     // objects bigger than 2GB.
814     SIZE_T GetComponentSize() const {
815         WRAPPER_NO_CONTRACT;
816         MethodTable * pMT;
817 #if CHECK_APP_DOMAIN_LEAKS
818         pMT = GetGCSafeMethodTable();
819 #else
820         pMT = GetMethodTable();
821 #endif //CHECK_APP_DOMAIN_LEAKS
822         _ASSERTE(pMT->HasComponentSize());
823         return pMT->RawGetComponentSize();
824     }
825
826         // Note that this can be a multidimensional array of rank 1 
827         // (for example if we had a 1-D array with lower bounds
828     BOOL IsMultiDimArray() const {
829         WRAPPER_NO_CONTRACT;
830         SUPPORTS_DAC;
831         return(GetMethodTable()->IsMultiDimArray());
832     }
833
834         // Get pointer to the begining of the bounds (counts for each dim)
835         // Works for any array type 
836     PTR_INT32 GetBoundsPtr() const {
837         WRAPPER_NO_CONTRACT;
838         MethodTable * pMT = GetMethodTable();
839         if (pMT->IsMultiDimArray()) 
840         {
841             return dac_cast<PTR_INT32>(
842                 dac_cast<TADDR>(this) + sizeof(*this));
843         }
844         else
845         {
846             return dac_cast<PTR_INT32>(PTR_HOST_MEMBER_TADDR(ArrayBase, this,
847                                                    m_NumComponents));
848         }
849     }
850
851         // Works for any array type 
852     PTR_INT32 GetLowerBoundsPtr() const {
853         WRAPPER_NO_CONTRACT;
854         if (IsMultiDimArray())
855         {
856             // Lower bounds info is after total bounds info
857             // and total bounds info has rank elements
858             return GetBoundsPtr() + GetRank();
859         }
860         else
861             return dac_cast<PTR_INT32>(GVAL_ADDR(s_arrayBoundsZero));
862     }
863
864     static unsigned GetOffsetOfNumComponents() {
865         LIMITED_METHOD_CONTRACT;
866         return offsetof(ArrayBase, m_NumComponents);
867     }
868
869     inline static unsigned GetDataPtrOffset(MethodTable* pMT);
870
871     inline static unsigned GetBoundsOffset(MethodTable* pMT);
872     inline static unsigned GetLowerBoundsOffset(MethodTable* pMT);
873 };
874
875 //
876 // Template used to build all the non-object
877 // arrays of a single dimension
878 //
879
880 template < class KIND >
881 class Array : public ArrayBase
882 {
883   public:
884       
885     typedef DPTR(KIND) PTR_KIND;
886     typedef DPTR(const KIND) PTR_CKIND;
887
888     KIND          m_Array[1];
889
890     PTR_KIND        GetDirectPointerToNonObjectElements()
891     { 
892         WRAPPER_NO_CONTRACT;
893         SUPPORTS_DAC;
894         // return m_Array; 
895         return PTR_KIND(GetDataPtr()); // This also handles arrays of dim 1 with lower bounds present
896
897     }
898
899     PTR_CKIND  GetDirectConstPointerToNonObjectElements() const
900     { 
901         WRAPPER_NO_CONTRACT;
902         // return m_Array; 
903         return PTR_CKIND(GetDataPtr()); // This also handles arrays of dim 1 with lower bounds present
904     }
905 };
906
907
908 // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays.
909 class PtrArray : public ArrayBase
910 {
911     friend class GCHeap;
912     friend class ClrDataAccess;
913     friend OBJECTREF AllocateArrayEx(TypeHandle arrayClass, INT32 *pArgs, DWORD dwNumArgs, BOOL bAllocateInLargeHeap); 
914     friend class JIT_TrialAlloc;
915     friend class CheckAsmOffsets;
916
917 public:
918     TypeHandle GetArrayElementTypeHandle()
919     {
920         LIMITED_METHOD_CONTRACT;
921         return GetMethodTable()->GetApproxArrayElementTypeHandle();
922     }
923
924     static SIZE_T GetDataOffset()
925     {
926         LIMITED_METHOD_CONTRACT;
927         return offsetof(PtrArray, m_Array);
928     }
929
930     void SetAt(SIZE_T i, OBJECTREF ref)
931     {
932         CONTRACTL
933         {
934             NOTHROW;
935             GC_NOTRIGGER;
936             SO_TOLERANT;
937             MODE_COOPERATIVE;
938         }
939         CONTRACTL_END;
940         _ASSERTE(i < GetNumComponents());
941         SetObjectReference(m_Array + i, ref, GetAppDomain());
942     }
943
944     void ClearAt(SIZE_T i)
945     {
946         WRAPPER_NO_CONTRACT;
947         _ASSERTE(i < GetNumComponents());
948         ClearObjectReference(m_Array + i);
949     }
950
951     OBJECTREF GetAt(SIZE_T i)
952     {
953         LIMITED_METHOD_CONTRACT;
954         SUPPORTS_DAC;
955         _ASSERTE(i < GetNumComponents());
956
957 // DAC doesn't know the true size of this array
958 // the compiler thinks it is size 1, but really it is size N hanging off the structure
959 #ifndef DACCESS_COMPILE
960         return m_Array[i];
961 #else
962         TADDR arrayTargetAddress = dac_cast<TADDR>(this) + offsetof(PtrArray, m_Array);
963         __ArrayDPtr<OBJECTREF> targetArray = dac_cast< __ArrayDPtr<OBJECTREF> >(arrayTargetAddress);
964         return targetArray[i];
965 #endif
966     }
967
968     friend class StubLinkerCPU;
969 #ifdef FEATURE_ARRAYSTUB_AS_IL
970     friend class ArrayOpLinker;
971 #endif
972 public:
973     OBJECTREF    m_Array[1];
974 };
975
976 /* a TypedByRef is a structure that is used to implement VB's BYREF variants.  
977    it is basically a tuple of an address of some data along with a TypeHandle
978    that indicates the type of the address */
979 class TypedByRef 
980 {
981 public:
982
983     PTR_VOID data;
984     TypeHandle type;  
985 };
986
987 typedef DPTR(TypedByRef) PTR_TypedByRef;
988
989 typedef Array<I1>   I1Array;
990 typedef Array<I2>   I2Array;
991 typedef Array<I4>   I4Array;
992 typedef Array<I8>   I8Array;
993 typedef Array<R4>   R4Array;
994 typedef Array<R8>   R8Array;
995 typedef Array<U1>   U1Array;
996 typedef Array<U1>   BOOLArray;
997 typedef Array<U2>   U2Array;
998 typedef Array<WCHAR>   CHARArray;
999 typedef Array<U4>   U4Array;
1000 typedef Array<U8>   U8Array;
1001 typedef PtrArray    PTRArray;  
1002
1003 typedef DPTR(I1Array)   PTR_I1Array;
1004 typedef DPTR(I2Array)   PTR_I2Array;
1005 typedef DPTR(I4Array)   PTR_I4Array;
1006 typedef DPTR(I8Array)   PTR_I8Array;
1007 typedef DPTR(R4Array)   PTR_R4Array;
1008 typedef DPTR(R8Array)   PTR_R8Array;
1009 typedef DPTR(U1Array)   PTR_U1Array;
1010 typedef DPTR(BOOLArray) PTR_BOOLArray;
1011 typedef DPTR(U2Array)   PTR_U2Array;
1012 typedef DPTR(CHARArray) PTR_CHARArray;
1013 typedef DPTR(U4Array)   PTR_U4Array;
1014 typedef DPTR(U8Array)   PTR_U8Array;
1015 typedef DPTR(PTRArray)  PTR_PTRArray;
1016
1017 class StringObject;
1018
1019 #ifdef USE_CHECKED_OBJECTREFS
1020 typedef REF<ArrayBase>  BASEARRAYREF;
1021 typedef REF<I1Array>    I1ARRAYREF;
1022 typedef REF<I2Array>    I2ARRAYREF;
1023 typedef REF<I4Array>    I4ARRAYREF;
1024 typedef REF<I8Array>    I8ARRAYREF;
1025 typedef REF<R4Array>    R4ARRAYREF;
1026 typedef REF<R8Array>    R8ARRAYREF;
1027 typedef REF<U1Array>    U1ARRAYREF;
1028 typedef REF<BOOLArray>  BOOLARRAYREF;
1029 typedef REF<U2Array>    U2ARRAYREF;
1030 typedef REF<U4Array>    U4ARRAYREF;
1031 typedef REF<U8Array>    U8ARRAYREF;
1032 typedef REF<CHARArray>  CHARARRAYREF;
1033 typedef REF<PTRArray>   PTRARRAYREF;  // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays.
1034 typedef REF<StringObject> STRINGREF;
1035
1036 #else   // USE_CHECKED_OBJECTREFS
1037
1038 typedef PTR_ArrayBase   BASEARRAYREF;
1039 typedef PTR_I1Array     I1ARRAYREF;
1040 typedef PTR_I2Array     I2ARRAYREF;
1041 typedef PTR_I4Array     I4ARRAYREF;
1042 typedef PTR_I8Array     I8ARRAYREF;
1043 typedef PTR_R4Array     R4ARRAYREF;
1044 typedef PTR_R8Array     R8ARRAYREF;
1045 typedef PTR_U1Array     U1ARRAYREF;
1046 typedef PTR_BOOLArray   BOOLARRAYREF;
1047 typedef PTR_U2Array     U2ARRAYREF;
1048 typedef PTR_U4Array     U4ARRAYREF;
1049 typedef PTR_U8Array     U8ARRAYREF;
1050 typedef PTR_CHARArray   CHARARRAYREF;
1051 typedef PTR_PTRArray    PTRARRAYREF;  // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays.
1052 typedef PTR_StringObject STRINGREF;
1053
1054 #endif // USE_CHECKED_OBJECTREFS
1055
1056
1057 #include <poppack.h>
1058
1059
1060 /*
1061  * StringObject
1062  *
1063  * Special String implementation for performance.   
1064  *
1065  *   m_StringLength - Length of string in number of WCHARs
1066  *   m_Characters   - The string buffer
1067  *
1068  */
1069
1070
1071 /**
1072  *  The high bit state can be one of three value: 
1073  * STRING_STATE_HIGH_CHARS: We've examined the string and determined that it definitely has values greater than 0x80
1074  * STRING_STATE_FAST_OPS: We've examined the string and determined that it definitely has no chars greater than 0x80
1075  * STRING_STATE_UNDETERMINED: We've never examined this string.
1076  * We've also reserved another bit for future use.
1077  */
1078
1079 #define STRING_STATE_UNDETERMINED     0x00000000
1080 #define STRING_STATE_HIGH_CHARS       0x40000000
1081 #define STRING_STATE_FAST_OPS         0x80000000
1082 #define STRING_STATE_SPECIAL_SORT     0xC0000000
1083
1084 #ifdef _MSC_VER
1085 #pragma warning(disable : 4200)     // disable zero-sized array warning
1086 #endif
1087 class StringObject : public Object
1088 {
1089 #ifdef DACCESS_COMPILE
1090     friend class ClrDataAccess;
1091 #endif
1092     friend class GCHeap;
1093     friend class JIT_TrialAlloc;
1094     friend class CheckAsmOffsets;
1095     friend class COMString;
1096
1097   private:
1098     DWORD   m_StringLength;
1099     WCHAR   m_Characters[0];
1100     // GC will see a StringObject like this:
1101     //   DWORD m_StringLength
1102     //   WCHAR m_Characters[0]
1103     //   DWORD m_OptionalPadding (this is an optional field and will appear based on need)
1104
1105   public:
1106     VOID    SetStringLength(DWORD len)                   { LIMITED_METHOD_CONTRACT; _ASSERTE(len >= 0); m_StringLength = len; }
1107
1108   protected:
1109     StringObject() {LIMITED_METHOD_CONTRACT; }
1110    ~StringObject() {LIMITED_METHOD_CONTRACT; }
1111    
1112   public:
1113     static SIZE_T GetSize(DWORD stringLength);
1114
1115     DWORD   GetStringLength()                           { LIMITED_METHOD_DAC_CONTRACT; return( m_StringLength );}
1116     WCHAR*  GetBuffer()                                 { LIMITED_METHOD_CONTRACT; _ASSERTE(this != nullptr); return (WCHAR*)( dac_cast<TADDR>(this) + offsetof(StringObject, m_Characters) );  }
1117     WCHAR*  GetBuffer(DWORD *pdwSize)                   { LIMITED_METHOD_CONTRACT; _ASSERTE((this != nullptr) && pdwSize); *pdwSize = GetStringLength(); return GetBuffer();  }
1118     WCHAR*  GetBufferNullable()                         { LIMITED_METHOD_CONTRACT; return( (this == nullptr) ? nullptr : (WCHAR*)( dac_cast<TADDR>(this) + offsetof(StringObject, m_Characters) ) );  }
1119
1120     DWORD GetHighCharState() {
1121         WRAPPER_NO_CONTRACT;
1122         DWORD ret = GetHeader()->GetBits() & (BIT_SBLK_STRING_HIGH_CHAR_MASK);
1123         return ret;
1124     }
1125
1126     VOID SetHighCharState(DWORD value) {
1127         WRAPPER_NO_CONTRACT;
1128         _ASSERTE(value==STRING_STATE_HIGH_CHARS || value==STRING_STATE_FAST_OPS 
1129                  || value==STRING_STATE_UNDETERMINED || value==STRING_STATE_SPECIAL_SORT);
1130
1131         // you need to clear the present state before going to a new state, but we'll allow multiple threads to set it to the same thing.
1132         _ASSERTE((GetHighCharState() == STRING_STATE_UNDETERMINED) || (GetHighCharState()==value));    
1133
1134         static_assert_no_msg(BIT_SBLK_STRING_HAS_NO_HIGH_CHARS == STRING_STATE_FAST_OPS && 
1135                  STRING_STATE_HIGH_CHARS == BIT_SBLK_STRING_HIGH_CHARS_KNOWN &&
1136                  STRING_STATE_SPECIAL_SORT == BIT_SBLK_STRING_HAS_SPECIAL_SORT);
1137
1138         GetHeader()->SetBit(value);
1139     }
1140
1141     static UINT GetBufferOffset()
1142     {
1143         LIMITED_METHOD_DAC_CONTRACT;
1144         return (UINT)(offsetof(StringObject, m_Characters));
1145     }
1146     static UINT GetStringLengthOffset()
1147     {
1148         LIMITED_METHOD_CONTRACT;
1149         return (UINT)(offsetof(StringObject, m_StringLength));
1150     }
1151     VOID    GetSString(SString &result)
1152     {
1153         WRAPPER_NO_CONTRACT;
1154         result.Set(GetBuffer(), GetStringLength());
1155     }
1156     //========================================================================
1157     // Creates a System.String object. All the functions that take a length
1158     // or a count of bytes will add the null terminator after length
1159     // characters. So this means that if you have a string that has 5
1160     // characters and the null terminator you should pass in 5 and NOT 6.
1161     //========================================================================
1162     static STRINGREF NewString(int length);
1163     static STRINGREF NewString(int length, BOOL bHasTrailByte);
1164     static STRINGREF NewString(const WCHAR *pwsz);
1165     static STRINGREF NewString(const WCHAR *pwsz, int length);
1166     static STRINGREF NewString(LPCUTF8 psz);
1167     static STRINGREF NewString(LPCUTF8 psz, int cBytes);
1168
1169     static STRINGREF GetEmptyString();
1170     static STRINGREF* GetEmptyStringRefPtr();
1171
1172     static STRINGREF* InitEmptyStringRefPtr();
1173
1174     static STRINGREF __stdcall StringInitCharHelper(LPCSTR pszSource, int length);
1175     DWORD InternalCheckHighChars();
1176
1177     BOOL HasTrailByte();
1178     BOOL GetTrailByte(BYTE *bTrailByte);
1179     BOOL SetTrailByte(BYTE bTrailByte);
1180     static BOOL CaseInsensitiveCompHelper(__in_ecount(aLength) WCHAR * strA, __in_z INT8 * strB, int aLength, int bLength, int *result);
1181
1182 #ifdef VERIFY_HEAP
1183     //has to use raw object to avoid recursive validation
1184     BOOL ValidateHighChars ();
1185 #endif //VERIFY_HEAP
1186
1187     /*=================RefInterpretGetStringValuesDangerousForGC======================
1188     **N.B.: This perfoms no range checking and relies on the caller to have done this.
1189     **Args: (IN)ref -- the String to be interpretted.
1190     **      (OUT)chars -- a pointer to the characters in the buffer.
1191     **      (OUT)length -- a pointer to the length of the buffer.
1192     **Returns: void.
1193     **Exceptions: None.
1194     ==============================================================================*/
1195     // !!!! If you use this function, you have to be careful because chars is a pointer
1196     // !!!! to the data buffer of ref.  If GC happens after this call, you need to make
1197     // !!!! sure that you have a pin handle on ref, or use GCPROTECT_BEGINPINNING on ref.
1198     void RefInterpretGetStringValuesDangerousForGC(__deref_out_ecount(*length + 1) WCHAR **chars, int *length) {
1199         WRAPPER_NO_CONTRACT;
1200     
1201         _ASSERTE(GetGCSafeMethodTable() == g_pStringClass);
1202         *length = GetStringLength();
1203         *chars  = GetBuffer();
1204 #ifdef _DEBUG
1205         EnableStressHeapHelper();
1206 #endif
1207     }
1208
1209
1210 private:
1211     static INT32 FastCompareStringHelper(DWORD* strAChars, INT32 countA, DWORD* strBChars, INT32 countB);
1212
1213     static STRINGREF* EmptyStringRefPtr;
1214 };
1215
1216 //The first two macros are essentially the same.  I just define both because
1217 //having both can make the code more readable.
1218 #define IS_FAST_SORT(state) (((state) == STRING_STATE_FAST_OPS))
1219 #define IS_SLOW_SORT(state) (((state) != STRING_STATE_FAST_OPS))
1220
1221 //This macro should be used to determine things like indexing, casing, and encoding.
1222 #define IS_FAST_OPS_EXCEPT_SORT(state) (((state)==STRING_STATE_SPECIAL_SORT) || ((state)==STRING_STATE_FAST_OPS))
1223 #define IS_ASCII(state) (((state)==STRING_STATE_SPECIAL_SORT) || ((state)==STRING_STATE_FAST_OPS))
1224 #define IS_FAST_CASING(state) IS_ASCII(state)
1225 #define IS_FAST_INDEX(state)  IS_ASCII(state)
1226 #define IS_STRING_STATE_UNDETERMINED(state) ((state)==STRING_STATE_UNDETERMINED)
1227 #define HAS_HIGH_CHARS(state) ((state)==STRING_STATE_HIGH_CHARS)
1228
1229 /*================================GetEmptyString================================
1230 **Get a reference to the empty string.  If we haven't already gotten one, we
1231 **query the String class for a pointer to the empty string that we know was
1232 **created at startup.
1233 **
1234 **Args: None
1235 **Returns: A STRINGREF to the EmptyString
1236 **Exceptions: None
1237 ==============================================================================*/
1238 inline STRINGREF StringObject::GetEmptyString() {
1239
1240     CONTRACTL {
1241         THROWS;
1242         MODE_COOPERATIVE;
1243         GC_TRIGGERS;
1244     } CONTRACTL_END;
1245     STRINGREF* refptr = EmptyStringRefPtr;
1246
1247     //If we've never gotten a reference to the EmptyString, we need to go get one.
1248     if (refptr==NULL) {
1249         refptr = InitEmptyStringRefPtr();
1250     }
1251     //We've already have a reference to the EmptyString, so we can just return it.
1252     return *refptr;
1253 }
1254
1255 inline STRINGREF* StringObject::GetEmptyStringRefPtr() {
1256
1257     CONTRACTL {
1258         THROWS;
1259         MODE_ANY;
1260         GC_TRIGGERS;
1261     } CONTRACTL_END;
1262     STRINGREF* refptr = EmptyStringRefPtr;
1263
1264     //If we've never gotten a reference to the EmptyString, we need to go get one.
1265     if (refptr==NULL) {
1266         refptr = InitEmptyStringRefPtr();
1267     }
1268     //We've already have a reference to the EmptyString, so we can just return it.
1269     return refptr;
1270 }
1271
1272 // This is used to account for the remoting cache on RuntimeType, 
1273 // RuntimeMethodInfo, and RtFieldInfo.
1274 class BaseObjectWithCachedData : public Object
1275 {
1276 #ifdef FEATURE_REMOTING
1277     protected:
1278         OBJECTREF  m_CachedData;
1279 #endif //FEATURE_REMOTING
1280 };
1281
1282 // This is the Class version of the Reflection object.
1283 //  A Class has adddition information.
1284 //  For a ReflectClassBaseObject the m_pData is a pointer to a FieldDesc array that
1285 //      contains all of the final static primitives if its defined.
1286 //  m_cnt = the number of elements defined in the m_pData FieldDesc array.  -1 means
1287 //      this hasn't yet been defined.
1288 class ReflectClassBaseObject : public BaseObjectWithCachedData
1289 {
1290     friend class MscorlibBinder;
1291
1292 protected:
1293     OBJECTREF           m_keepalive;
1294     OBJECTREF           m_cache;
1295     TypeHandle          m_typeHandle;
1296 #ifdef FEATURE_APPX
1297     UINT32              m_invocationFlags;
1298 #endif
1299
1300 #ifdef _DEBUG
1301     void TypeCheck()
1302     {
1303         CONTRACTL
1304         {
1305             NOTHROW;
1306             MODE_COOPERATIVE;
1307             GC_NOTRIGGER;
1308             SO_TOLERANT;
1309         }
1310         CONTRACTL_END;
1311
1312         MethodTable *pMT = GetMethodTable();
1313         while (pMT != g_pRuntimeTypeClass && pMT != NULL)
1314         {
1315             pMT = pMT->GetParentMethodTable();
1316         }
1317         _ASSERTE(pMT == g_pRuntimeTypeClass);
1318     }
1319 #endif // _DEBUG
1320
1321 public:
1322     void SetType(TypeHandle type) {
1323         CONTRACTL
1324         {
1325             NOTHROW;
1326             MODE_COOPERATIVE;
1327             GC_NOTRIGGER;
1328             SO_TOLERANT;
1329         }
1330         CONTRACTL_END;
1331
1332         INDEBUG(TypeCheck());
1333         m_typeHandle = type;
1334     }
1335
1336     void SetKeepAlive(OBJECTREF keepalive)
1337     {
1338         CONTRACTL
1339         {
1340             NOTHROW;
1341             MODE_COOPERATIVE;
1342             GC_NOTRIGGER;
1343             SO_TOLERANT;
1344         }
1345         CONTRACTL_END;
1346
1347         INDEBUG(TypeCheck());
1348         SetObjectReference(&m_keepalive, keepalive, GetAppDomain());
1349     }
1350
1351     TypeHandle GetType() {
1352         CONTRACTL
1353         {
1354             NOTHROW;
1355             MODE_COOPERATIVE;
1356             GC_NOTRIGGER;
1357             SO_TOLERANT;
1358         }
1359         CONTRACTL_END;
1360
1361         INDEBUG(TypeCheck());
1362         return m_typeHandle;
1363     }
1364
1365 };
1366
1367 // This is the Method version of the Reflection object.
1368 //  A Method has adddition information.
1369 //   m_pMD - A pointer to the actual MethodDesc of the method.
1370 //   m_object - a field that has a reference type in it. Used only for RuntimeMethodInfoStub to keep the real type alive.
1371 // This structure matches the structure up to the m_pMD for several different managed types. 
1372 // (RuntimeConstructorInfo, RuntimeMethodInfo, and RuntimeMethodInfoStub). These types are unrelated in the type
1373 // system except that they all implement a particular interface. It is important that that interface is not attached to any
1374 // type that does not sufficiently match this data structure.
1375 class ReflectMethodObject : public BaseObjectWithCachedData
1376 {
1377     friend class MscorlibBinder;
1378
1379 protected:
1380     OBJECTREF           m_object;
1381     OBJECTREF           m_empty1;
1382     OBJECTREF           m_empty2;
1383     OBJECTREF           m_empty3;
1384     OBJECTREF           m_empty4;
1385     OBJECTREF           m_empty5;
1386     OBJECTREF           m_empty6;
1387     OBJECTREF           m_empty7;
1388     MethodDesc *        m_pMD;
1389
1390 public:
1391     void SetMethod(MethodDesc *pMethod) {
1392         LIMITED_METHOD_CONTRACT;
1393         m_pMD = pMethod;
1394     }
1395
1396     // This must only be called on instances of ReflectMethodObject that are actually RuntimeMethodInfoStub
1397     void SetKeepAlive(OBJECTREF keepalive)
1398     {
1399         WRAPPER_NO_CONTRACT;
1400         SetObjectReference(&m_object, keepalive, GetAppDomain());
1401     }
1402
1403     MethodDesc *GetMethod() {
1404         LIMITED_METHOD_CONTRACT;
1405         return m_pMD;
1406     }
1407
1408 };
1409
1410 // This is the Field version of the Reflection object.
1411 //  A Method has adddition information.
1412 //   m_pFD - A pointer to the actual MethodDesc of the method.
1413 //   m_object - a field that has a reference type in it. Used only for RuntimeFieldInfoStub to keep the real type alive.
1414 // This structure matches the structure up to the m_pFD for several different managed types. 
1415 // (RtFieldInfo and RuntimeFieldInfoStub). These types are unrelated in the type
1416 // system except that they all implement a particular interface. It is important that that interface is not attached to any
1417 // type that does not sufficiently match this data structure.
1418 class ReflectFieldObject : public BaseObjectWithCachedData
1419 {
1420     friend class MscorlibBinder;
1421
1422 protected:
1423     OBJECTREF           m_object;
1424     OBJECTREF           m_empty1;
1425     INT32               m_empty2;
1426     OBJECTREF           m_empty3;
1427     OBJECTREF           m_empty4;
1428     FieldDesc *         m_pFD;
1429
1430 public:
1431     void SetField(FieldDesc *pField) {
1432         LIMITED_METHOD_CONTRACT;
1433         m_pFD = pField;
1434     }
1435
1436     // This must only be called on instances of ReflectFieldObject that are actually RuntimeFieldInfoStub
1437     void SetKeepAlive(OBJECTREF keepalive)
1438     {
1439         WRAPPER_NO_CONTRACT;
1440         SetObjectReference(&m_object, keepalive, GetAppDomain());
1441     }
1442
1443     FieldDesc *GetField() {
1444         LIMITED_METHOD_CONTRACT;
1445         return m_pFD;
1446     }
1447 };
1448
1449 // ReflectModuleBaseObject 
1450 // This class is the base class for managed Module.
1451 //  This class will connect the Object back to the underlying VM representation
1452 //  m_ReflectClass -- This is the real Class that was used for reflection
1453 //      This class was used to get at this object
1454 //  m_pData -- this is a generic pointer which usually points CorModule
1455 //  
1456 class ReflectModuleBaseObject : public Object
1457 {
1458     friend class MscorlibBinder;
1459
1460   protected:
1461     // READ ME:
1462     // Modifying the order or fields of this object may require other changes to the
1463     //  classlib class definition of this object.
1464     OBJECTREF          m_runtimeType;    
1465     OBJECTREF          m_runtimeAssembly;
1466     void*              m_ReflectClass;  // Pointer to the ReflectClass structure
1467     Module*            m_pData;         // Pointer to the Module
1468     void*              m_pGlobals;      // Global values....
1469     void*              m_pGlobalsFlds;  // Global Fields....
1470
1471   protected:
1472     ReflectModuleBaseObject() {LIMITED_METHOD_CONTRACT;}
1473    ~ReflectModuleBaseObject() {LIMITED_METHOD_CONTRACT;}
1474    
1475   public:
1476     void SetModule(Module* p) {
1477         LIMITED_METHOD_CONTRACT;
1478         m_pData = p;
1479     }
1480     Module* GetModule() {
1481         LIMITED_METHOD_CONTRACT;
1482         return m_pData;
1483     }
1484     void SetAssembly(OBJECTREF assembly)
1485     {
1486         WRAPPER_NO_CONTRACT;
1487         SetObjectReference(&m_runtimeAssembly, assembly, GetAppDomain());
1488     }
1489 };
1490
1491 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive);
1492 #define FC_RETURN_MODULE_OBJECT(pModule, refKeepAlive) FC_INNER_RETURN(ReflectModuleBaseObject*, GetRuntimeModuleHelper(__me, pModule, refKeepAlive))
1493
1494 class SafeHandle;
1495
1496 #ifdef USE_CHECKED_OBJECTREFS
1497 typedef REF<SafeHandle> SAFEHANDLE;
1498 typedef REF<SafeHandle> SAFEHANDLEREF;
1499 #else // USE_CHECKED_OBJECTREFS
1500 typedef SafeHandle * SAFEHANDLE;
1501 typedef SafeHandle * SAFEHANDLEREF;
1502 #endif // USE_CHECKED_OBJECTREFS
1503
1504 class PermissionListSetObject: public Object
1505 {
1506     friend class MscorlibBinder;
1507
1508 private:
1509     OBJECTREF _firstPermSetTriple;
1510     OBJECTREF _permSetTriples;
1511 #ifdef FEATURE_COMPRESSEDSTACK
1512     OBJECTREF _zoneList;
1513     OBJECTREF _originList;
1514 #endif // FEATURE_COMPRESSEDSTACK
1515
1516 public:
1517     BOOL IsEmpty() 
1518     {
1519         LIMITED_METHOD_CONTRACT;
1520         return (_firstPermSetTriple == NULL &&
1521                 _permSetTriples == NULL
1522 #ifdef FEATURE_COMPRESSEDSTACK
1523                 && _zoneList == NULL &&
1524                 _originList == NULL
1525 #endif // FEATURE_COMPRESSEDSTACK
1526                 );
1527     }
1528 };
1529
1530 #ifdef USE_CHECKED_OBJECTREFS
1531 typedef REF<PermissionListSetObject> PERMISSIONLISTSETREF;
1532 #else
1533 typedef PermissionListSetObject*     PERMISSIONLISTSETREF;
1534 #endif
1535 #ifdef FEATURE_COMPRESSEDSTACK
1536 class CompressedStackObject: public Object
1537 {
1538     friend class MscorlibBinder;
1539
1540 private:
1541     // These field are also defined in the managed representation.  (CompressedStack.cs)If you
1542     // add or change these field you must also change the managed code so that
1543     // it matches these.  This is necessary so that the object is the proper
1544     // size. 
1545     PERMISSIONLISTSETREF m_pls;
1546     SAFEHANDLEREF m_compressedStackHandle;
1547
1548 public:
1549     void* GetUnmanagedCompressedStack();
1550     BOOL IsEmptyPLS() 
1551     {
1552         LIMITED_METHOD_CONTRACT;
1553         return (m_pls == NULL || m_pls->IsEmpty());
1554     }
1555 };
1556
1557 #ifdef USE_CHECKED_OBJECTREFS
1558 typedef REF<CompressedStackObject> COMPRESSEDSTACKREF;
1559 #else
1560 typedef CompressedStackObject*     COMPRESSEDSTACKREF;
1561 #endif
1562 #endif // #ifdef FEATURE_COMPRESSEDSTACK
1563     
1564 #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
1565 class SecurityContextObject: public Object
1566 {
1567     friend class MscorlibBinder;
1568
1569 private:
1570     
1571     // These field are also defined in the managed representation.  (SecurityContext.cs)If you
1572     // add or change these field you must also change the managed code so that
1573     // it matches these.  This is necessary so that the object is the proper
1574     // size. 
1575
1576     OBJECTREF               _executionContext;
1577 #ifdef FEATURE_IMPERSONATION
1578     OBJECTREF               _windowsIdentity;
1579 #endif // FEATURE_IMPERSONATION
1580 #ifdef FEATURE_COMPRESSEDSTACK
1581     COMPRESSEDSTACKREF      _compressedStack;
1582 #endif // FEATURE_COMPRESSEDSTACK
1583     INT32                   _disableFlow;
1584     CLR_BOOL                _isNewCapture;
1585 public:
1586 #ifdef FEATURE_COMPRESSEDSTACK    
1587     COMPRESSEDSTACKREF GetCompressedStack()
1588     {
1589         LIMITED_METHOD_CONTRACT;
1590         return _compressedStack;
1591     }
1592 #endif // #ifdef FEATURE_COMPRESSEDSTACK
1593 };
1594
1595 #ifdef USE_CHECKED_OBJECTREFS
1596 typedef REF<SecurityContextObject> SECURITYCONTEXTREF;
1597 #else
1598 typedef SecurityContextObject*     SECURITYCONTEXTREF;
1599 #endif
1600 #endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
1601
1602 #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
1603 #define SYNCCTXPROPS_REQUIRESWAITNOTIFICATION 0x1 // Keep in sync with SynchronizationContext.cs SynchronizationContextFlags
1604 class ThreadBaseObject;
1605 class SynchronizationContextObject: public Object
1606 {
1607     friend class MscorlibBinder;
1608 private:
1609     // These field are also defined in the managed representation.  (SecurityContext.cs)If you
1610     // add or change these field you must also change the managed code so that
1611     // it matches these.  This is necessary so that the object is the proper
1612     // size. 
1613     INT32 _props;
1614 public:
1615     BOOL IsWaitNotificationRequired()
1616     {
1617         LIMITED_METHOD_CONTRACT;
1618         if ((_props & SYNCCTXPROPS_REQUIRESWAITNOTIFICATION) != 0)
1619             return TRUE;
1620         return FALSE;
1621     }
1622 };
1623 #endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
1624
1625 #ifdef FEATURE_REMOTING
1626 class CallContextRemotingDataObject : public Object
1627 {
1628 private:
1629     // These field are also defined in the managed representation.  (SecurityContext.cs)If you
1630     // add or change these field you must also change the managed code so that
1631     // it matches these.  This is necessary so that the object is the proper
1632     // size. 
1633     OBJECTREF _logicalCallID;
1634 public:
1635     OBJECTREF GetLogicalCallID()
1636     {
1637         LIMITED_METHOD_CONTRACT;
1638         return _logicalCallID;
1639     }
1640 };
1641
1642 class CallContextSecurityDataObject : public Object
1643 {
1644 private:
1645     // These field are also defined in the managed representation.  (SecurityContext.cs)If you
1646     // add or change these field you must also change the managed code so that
1647     // it matches these.  This is necessary so that the object is the proper
1648     // size. 
1649     OBJECTREF _principal;
1650 public:
1651     OBJECTREF GetPrincipal()
1652     {
1653         LIMITED_METHOD_CONTRACT;
1654         return _principal;
1655     }
1656
1657     void SetPrincipal(OBJECTREF ref)
1658     {
1659         WRAPPER_NO_CONTRACT;
1660         SetObjectReferenceUnchecked(&_principal, ref);
1661     }
1662 };
1663
1664 #ifdef USE_CHECKED_OBJECTREFS
1665 typedef REF<CallContextSecurityDataObject> CCSECURITYDATAREF;
1666 typedef REF<CallContextRemotingDataObject> CCREMOTINGDATAREF;
1667 #else
1668 typedef CallContextSecurityDataObject*     CCSECURITYDATAREF;
1669 typedef CallContextRemotingDataObject*     CCREMOTINGDATAREF;
1670 #endif
1671
1672 class LogicalCallContextObject : public Object
1673 {
1674     friend class MscorlibBinder;
1675     
1676     // These field are also defined in the managed representation.  (CallContext.cs) If you
1677     // add or change these field you must also change the managed code so that
1678     // it matches these.  This is necessary so that the object is the proper
1679     // size.
1680 private :
1681     OBJECTREF               m_Datastore;
1682     CCREMOTINGDATAREF       m_RemotingData;
1683     CCSECURITYDATAREF       m_SecurityData;
1684     OBJECTREF               m_HostContext;
1685     OBJECTREF               _sendHeaders;
1686     OBJECTREF               _recvHeaders;
1687     CLR_BOOL                m_IsCorrelationMgr;
1688
1689 public:
1690     CCSECURITYDATAREF GetSecurityData()
1691     {
1692         LIMITED_METHOD_CONTRACT;
1693         return m_SecurityData;
1694     }
1695
1696     // This is an unmanaged equivalent of System.Runtime.Remoting.Messaging.LogicalCallContext.HasInfo
1697     BOOL ContainsDataForSerialization() 
1698     {
1699         CONTRACTL
1700         {
1701             NOTHROW;
1702             GC_NOTRIGGER;
1703             SO_TOLERANT;
1704             MODE_COOPERATIVE;
1705         }
1706         CONTRACTL_END;
1707         return (ContainsNonSecurityDataForSerialization() ||
1708                (m_SecurityData != NULL && m_SecurityData->GetPrincipal() != NULL));
1709     }
1710
1711     BOOL ContainsNonSecurityDataForSerialization() 
1712     {
1713         LIMITED_METHOD_CONTRACT;
1714
1715         // m_Datastore may contain 0 items even if it's non-NULL in which case it does
1716         // not really contain any useful data for serialization and this function could
1717         // return FALSE. However we don't waste time trying to detect this case - it will
1718         // be reset to NULL the first time a call is made due to how LogicalCallContext's
1719         // ISerializable implementation works.
1720         return (m_Datastore != NULL ||
1721                (m_RemotingData != NULL && m_RemotingData->GetLogicalCallID() != NULL) ||
1722                 m_HostContext != NULL);
1723     }
1724 };
1725
1726 #ifdef USE_CHECKED_OBJECTREFS
1727 typedef REF<LogicalCallContextObject> LOGICALCALLCONTEXTREF;
1728 #else
1729 typedef LogicalCallContextObject*     LOGICALCALLCONTEXTREF;
1730 #endif
1731
1732 #endif // FEATURE_REMOTING
1733
1734
1735
1736
1737 typedef DPTR(class CultureInfoBaseObject) PTR_CultureInfoBaseObject;
1738
1739 #ifdef USE_CHECKED_OBJECTREFS
1740 #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
1741 typedef REF<SynchronizationContextObject> SYNCHRONIZATIONCONTEXTREF;
1742 #endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
1743 typedef REF<ExecutionContextObject> EXECUTIONCONTEXTREF;
1744 typedef REF<CultureInfoBaseObject> CULTUREINFOBASEREF;
1745 typedef REF<ArrayBase> ARRAYBASEREF;
1746
1747 #else
1748 #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
1749 typedef SynchronizationContextObject*     SYNCHRONIZATIONCONTEXTREF;
1750 #endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
1751 typedef CultureInfoBaseObject*     CULTUREINFOBASEREF;
1752 typedef PTR_ArrayBase ARRAYBASEREF;
1753 #endif
1754
1755 // Note that the name must always be "" or "en-US".  Other cases and nulls
1756 // aren't allowed (we already checked.)
1757 __inline bool IsCultureEnglishOrInvariant(LPCWSTR localeName)
1758 {
1759     LIMITED_METHOD_CONTRACT;
1760     if (localeName != NULL &&
1761         (localeName[0] == W('\0') ||
1762          wcscmp(localeName, W("en-US")) == 0))
1763     {
1764         return true;
1765     }
1766     return false;
1767     }
1768
1769 class CultureInfoBaseObject : public Object
1770 {
1771     friend class MscorlibBinder;
1772
1773 private:
1774     OBJECTREF compareInfo;
1775     OBJECTREF textInfo;
1776     OBJECTREF numInfo;
1777     OBJECTREF dateTimeInfo;
1778     OBJECTREF calendar;
1779     OBJECTREF m_cultureData;
1780     OBJECTREF m_consoleFallbackCulture;
1781     STRINGREF m_name;                       // "real" name - en-US, de-DE_phoneb or fj-FJ
1782     STRINGREF m_nonSortName;                // name w/o sort info (de-DE for de-DE_phoneb)
1783     STRINGREF m_sortName;                   // Sort only name (de-DE_phoneb, en-us for fj-fj (w/us sort)
1784     CULTUREINFOBASEREF m_parent;
1785 #ifndef FEATURE_COREFX_GLOBALIZATION
1786     INT32    iDataItem;                     // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
1787     INT32    iCultureID;                    // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
1788 #endif // !FEATURE_COREFX_GLOBALIZATION
1789 #ifdef FEATURE_LEAK_CULTURE_INFO
1790     INT32 m_createdDomainID;
1791 #endif // FEATURE_LEAK_CULTURE_INFO
1792     CLR_BOOL m_isReadOnly;
1793     CLR_BOOL m_isInherited;
1794 #ifdef FEATURE_LEAK_CULTURE_INFO
1795     CLR_BOOL m_isSafeCrossDomain;
1796 #endif // FEATURE_LEAK_CULTURE_INFO
1797     CLR_BOOL m_useUserOverride;
1798
1799 public:
1800     CULTUREINFOBASEREF GetParent()
1801     {
1802         LIMITED_METHOD_CONTRACT;
1803         return m_parent;
1804     }// GetParent
1805
1806
1807     STRINGREF GetName()
1808     {
1809         LIMITED_METHOD_CONTRACT;
1810         return m_name;
1811     }// GetName
1812
1813 #ifdef FEATURE_LEAK_CULTURE_INFO
1814     BOOL IsSafeCrossDomain()
1815     {
1816         return m_isSafeCrossDomain;
1817     }// IsSafeCrossDomain
1818
1819     ADID GetCreatedDomainID()
1820     {
1821         return ADID(m_createdDomainID);
1822     }// GetCreatedDomain
1823 #endif // FEATURE_LEAK_CULTURE_INFO
1824
1825 }; // class CultureInfoBaseObject
1826
1827
1828 #ifndef FEATURE_COREFX_GLOBALIZATION
1829 typedef DPTR(class CultureDataBaseObject) PTR_CultureDataBaseObject;
1830 class CultureDataBaseObject : public Object
1831 {
1832 public:
1833         // offsets are for Silverlight
1834         /* 0x000 */ STRINGREF sRealName                ; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
1835         /* 0x008 */ STRINGREF sWindowsName             ; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))       
1836         /* 0x010 */ STRINGREF sName                    ; // locale name (ie: en-us, NO sort info, but could be neutral)
1837         /* 0x012 */ STRINGREF sParent                  ; // Parent name (which may be a custom locale/culture)        
1838         /* 0x020 */ STRINGREF sLocalizedDisplayName    ; // Localized pretty name for this locale
1839         /* 0x028 */ STRINGREF sEnglishDisplayName      ; // English pretty name for this locale
1840         /* 0x030 */ STRINGREF sNativeDisplayName       ; // Native pretty name for this locale        
1841         /* 0x038 */ STRINGREF sSpecificCulture         ; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
1842         /* 0x040 */ STRINGREF sISO639Language          ; // ISO 639 Language Name
1843         /* 0x048 */ STRINGREF sLocalizedLanguage       ; // Localized name for this language
1844         /* 0x050 */ STRINGREF sEnglishLanguage         ; // English name for this language
1845         /* 0x058 */ STRINGREF sNativeLanguage          ; // Native name of this language
1846         /* 0x060 */ STRINGREF sRegionName              ; // (RegionInfo)        
1847         /* 0x068 */ STRINGREF sLocalizedCountry        ; // localized country name
1848         /* 0x070 */ STRINGREF sEnglishCountry          ; // english country name (RegionInfo)
1849         /* 0x078 */ STRINGREF sNativeCountry           ; // native country name
1850         /* 0x080 */ STRINGREF sISO3166CountryName      ; // (RegionInfo), ie: US
1851         /* 0x088 */ STRINGREF sPositiveSign            ; // (user can override) positive sign
1852         /* 0x090 */ STRINGREF sNegativeSign            ; // (user can override) negative sign
1853
1854         /* 0x098 */ PTRARRAYREF saNativeDigits         ; // (user can override) native characters for digits 0-9
1855         /* 0x0a0 */ I4ARRAYREF  waGrouping             ; // (user can override) grouping of digits
1856
1857         /* 0x0a8 */ STRINGREF sDecimalSeparator        ; // (user can override) decimal separator
1858         /* 0x0b0 */ STRINGREF sThousandSeparator       ; // (user can override) thousands separator
1859         /* 0x0b8 */ STRINGREF sNaN                     ; // Not a Number
1860         /* 0x0c0 */ STRINGREF sPositiveInfinity        ; // + Infinity
1861         /* 0x0c8 */ STRINGREF sNegativeInfinity        ; // - Infinity
1862         /* 0x0d0 */ STRINGREF sPercent                 ; // Percent (%) symbol
1863         /* 0x0d8 */ STRINGREF sPerMille                ; // PerMille (U+2030) symbol
1864         /* 0x0e0 */ STRINGREF sCurrency                ; // (user can override) local monetary symbol
1865         /* 0x0e8 */ STRINGREF sIntlMonetarySymbol      ; // international monetary symbol (RegionInfo)
1866         /* 0x0f0 */ STRINGREF sEnglishCurrency         ; // English name for this currency
1867         /* 0x0f8 */ STRINGREF sNativeCurrency          ; // Native name for this currency
1868
1869         /* 0x100 */ I4ARRAYREF  waMonetaryGrouping     ; // (user can override) monetary grouping of digits
1870
1871         /* 0x108 */ STRINGREF sMonetaryDecimal         ; // (user can override) monetary decimal separator
1872         /* 0x110 */ STRINGREF sMonetaryThousand        ; // (user can override) monetary thousands separator
1873         /* 0x118 */ STRINGREF sListSeparator           ; // (user can override) list separator       
1874         /* 0x120 */ STRINGREF sAM1159                  ; // (user can override) AM designator
1875         /* 0x128 */ STRINGREF sPM2359                  ; // (user can override) PM designator
1876                     STRINGREF sTimeSeparator           ; // Time Separator
1877
1878         /* 0x130 */ PTRARRAYREF saLongTimes            ; // (user can override) time format
1879         /* 0x138 */ PTRARRAYREF saShortTimes           ; // short time format
1880         /* 0x140 */ PTRARRAYREF saDurationFormats      ; // time duration format 
1881
1882         /* 0x148 */ I4ARRAYREF  waCalendars            ; // all available calendar type(s).  The first one is the default calendar
1883
1884         /* 0x150 */ PTRARRAYREF calendars              ; // Store for specific calendar data
1885
1886         /* 0x158 */ STRINGREF sTextInfo                ; // Text info name to use for custom
1887         /* 0x160 */ STRINGREF sCompareInfo             ; // Compare info name (including sorting key) to use if custom
1888         /* 0x168 */ STRINGREF sScripts                 ; // Typical Scripts for this locale (latn;cyrl; etc)
1889
1890         // these are ordered correctly
1891         /* ????? */ STRINGREF sAbbrevLang              ; // abbreviated language name (Windows Language Name) ex: ENU
1892         /* ????? */ STRINGREF sAbbrevCountry           ; // abbreviated country name (RegionInfo) (Windows Region Name) ex: USA
1893         /* ????? */ STRINGREF sISO639Language2         ; // 3 char ISO 639 lang name 2 ex: eng
1894         /* ????? */ STRINGREF sISO3166CountryName2     ; // 3 char ISO 639 country name 2 2(RegionInfo) ex: USA (ISO)
1895         /* ????? */ STRINGREF sConsoleFallbackName     ; // The culture name for the console fallback UI culture
1896         /* ????? */ STRINGREF sKeyboardsToInstall      ; // Keyboard installation string.
1897         /* ????? */ STRINGREF fontSignature            ; // Font signature (16 WORDS)
1898
1899 // Unused for now:        /* ????? */ INT32    iCountry                  ; // (user can override) country code (RegionInfo)
1900         /* 0x170 */ INT32    iGeoId                    ; // GeoId
1901         /* 0x174 */ INT32    iDigitSubstitution        ; // (user can override) Digit substitution 0=context, 1=none/arabic, 2=Native/national (2 seems to be unused)
1902         /* 0x178 */ INT32    iLeadingZeros             ; // (user can override) leading zeros 0 = no leading zeros, 1 = leading zeros
1903         /* 0x17c */ INT32    iDigits                   ; // (user can override) number of fractional digits
1904         /* 0x180 */ INT32    iNegativeNumber           ; // (user can override) negative number format
1905         /* 0x184 */ INT32    iNegativePercent          ; // Negative Percent (0-3)
1906         /* 0x188 */ INT32    iPositivePercent          ; // Positive Percent (0-11)
1907         /* 0x18c */ INT32    iCurrencyDigits           ; // (user can override) # local monetary fractional digits
1908         /* 0x190 */ INT32    iCurrency                 ; // (user can override) positive currency format
1909         /* 0x194 */ INT32    iNegativeCurrency         ; // (user can override) negative currency format       
1910         /* 0x198 */ INT32    iMeasure                  ; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
1911 // Unused for now        /* ????? */ INT32    iPaperSize                ; // default paper size (RegionInfo)
1912         /* 0x19c */ INT32    iFirstDayOfWeek           ; // (user can override) first day of week (gregorian really)
1913         /* 0x1a0 */ INT32    iFirstWeekOfYear          ; // (user can override) first week of year (gregorian really)
1914
1915         /* ????? */ INT32    iReadingLayout; // Reading Layout Data (0-3)
1916
1917         // these are ordered correctly
1918         /* ????? */ INT32    iDefaultAnsiCodePage      ; // default ansi code page ID (ACP)
1919         /* ????? */ INT32    iDefaultOemCodePage       ; // default oem code page ID (OCP or OEM)
1920         /* ????? */ INT32    iDefaultMacCodePage       ; // default macintosh code page
1921         /* ????? */ INT32    iDefaultEbcdicCodePage    ; // default EBCDIC code page
1922         /* ????? */ INT32    iLanguage                 ; // locale ID (0409) - NO sort information
1923         /* ????? */ INT32    iInputLanguageHandle      ; // input language handle
1924         /* 0x1a4 */ CLR_BOOL bUseOverrides             ; // use user overrides?
1925         /* 0x1a5 */ CLR_BOOL bNeutral                  ; // Flags for the culture (ie: neutral or not right now)        
1926         /* ????? */ CLR_BOOL bWin32Installed           ; // Flags indicate if the culture is Win32 installed       
1927         /* ????? */ CLR_BOOL bFramework                ; // Flags for indicate if the culture is one of Whidbey cultures 
1928
1929 }; // class CultureDataBaseObject
1930
1931
1932
1933 typedef DPTR(class CalendarDataBaseObject) PTR_CalendarDataBaseObject;
1934 class CalendarDataBaseObject : public Object
1935 {
1936 public:   
1937     /* 0x000 */ STRINGREF   sNativeName                 ; // Calendar Name for the locale
1938     
1939     // Formats
1940     
1941     /* 0x008 */ PTRARRAYREF saShortDates                ; // Short Data format, default first
1942     /* 0x010 */ PTRARRAYREF saYearMonths                ; // Year/Month Data format, default first
1943     /* 0x018 */ PTRARRAYREF saLongDates                 ; // Long Data format, default first
1944     /* 0x020 */ STRINGREF   sMonthDay                   ; // Month/Day format
1945
1946     // Calendar Parts Names
1947     /* 0x028 */ PTRARRAYREF saEraNames                  ; // Names of Eras
1948     /* 0x030 */ PTRARRAYREF saAbbrevEraNames            ; // Abbreviated Era Names
1949     /* 0x038 */ PTRARRAYREF saAbbrevEnglishEraNames     ; // Abbreviated Era Names in English
1950     /* 0x040 */ PTRARRAYREF saDayNames                  ; // Day Names, null to use locale data, starts on Sunday
1951     /* 0x048 */ PTRARRAYREF saAbbrevDayNames            ; // Abbrev Day Names, null to use locale data, starts on Sunday
1952     /* 0x050 */ PTRARRAYREF saSuperShortDayNames        ; // Super short Day of week names
1953     /* 0x058 */ PTRARRAYREF saMonthNames                ; // Month Names (13)
1954     /* 0x060 */ PTRARRAYREF saAbbrevMonthNames          ; // Abbrev Month Names (13)
1955     /* 0x068 */ PTRARRAYREF saMonthGenitiveNames        ; // Genitive Month Names (13)
1956     /* 0x070 */ PTRARRAYREF saAbbrevMonthGenitiveNames  ; // Genitive Abbrev Month Names (13)
1957     /* 0x078 */ PTRARRAYREF saLeapYearMonthNames        ; // Multiple strings for the month names in a leap year.
1958
1959     // Integers at end to make marshaller happier
1960     /* 0x080 */ INT32       iTwoDigitYearMax            ; // Max 2 digit year (for Y2K bug data entry)
1961     /* 0x084 */ INT32       iCurrentEra                 ; // current era # (usually 1)
1962
1963     // Use overrides?
1964     /* 0x088 */ CLR_BOOL    bUseUserOverrides           ; // True if we want user overrides.
1965 }; // class CalendarDataBaseObject
1966 #endif
1967
1968
1969 typedef DPTR(class ThreadBaseObject) PTR_ThreadBaseObject;
1970 class ThreadBaseObject : public Object
1971 {
1972     friend class ClrDataAccess;
1973     friend class ThreadNative;
1974     friend class MscorlibBinder;
1975     friend class Object;
1976
1977 private:
1978
1979     // These field are also defined in the managed representation.  If you
1980     //  add or change these field you must also change the managed code so that
1981     //  it matches these.  This is necessary so that the object is the proper
1982     //  size.  The order here must match that order which the loader will choose
1983     //  when laying out the managed class.  Note that the layouts are checked
1984     //  at run time, not compile time.
1985 #ifdef FEATURE_REMOTING    
1986     OBJECTREF     m_ExposedContext;
1987 #endif    
1988     OBJECTREF     m_ExecutionContext;
1989     OBJECTREF     m_SynchronizationContext;
1990     OBJECTREF     m_Name;
1991     OBJECTREF     m_Delegate;
1992 #ifdef FEATURE_LEAK_CULTURE_INFO
1993     CULTUREINFOBASEREF     m_CurrentUserCulture;
1994     CULTUREINFOBASEREF     m_CurrentUICulture;
1995 #endif
1996 #ifdef IO_CANCELLATION_ENABLED
1997     OBJECTREF     m_CancellationSignals;
1998 #endif
1999     OBJECTREF     m_ThreadStartArg;
2000
2001     // The next field (m_InternalThread) is declared as IntPtr in the managed
2002     // definition of Thread.  The loader will sort it next.
2003
2004     // m_InternalThread is always valid -- unless the thread has finalized and been
2005     // resurrected.  (The thread stopped running before it was finalized).
2006     Thread       *m_InternalThread;
2007     INT32         m_Priority;    
2008
2009     //We need to cache the thread id in managed code for perf reasons.
2010     INT32         m_ManagedThreadId;
2011
2012     CLR_BOOL      m_ExecutionContextBelongsToCurrentScope;
2013 #ifdef _DEBUG
2014     CLR_BOOL      m_ForbidExecutionContextMutation;
2015 #endif
2016
2017 protected:
2018     // the ctor and dtor can do no useful work.
2019     ThreadBaseObject() {LIMITED_METHOD_CONTRACT;};
2020    ~ThreadBaseObject() {LIMITED_METHOD_CONTRACT;};
2021
2022 public:
2023     Thread   *GetInternal()
2024     {
2025         LIMITED_METHOD_CONTRACT;
2026         return m_InternalThread;
2027     }
2028
2029     void SetInternal(Thread *it);
2030     void ClearInternal();
2031
2032     INT32 GetManagedThreadId()
2033     {
2034         LIMITED_METHOD_CONTRACT;
2035         return m_ManagedThreadId;
2036     }
2037
2038     void SetManagedThreadId(INT32 id)
2039     {
2040         LIMITED_METHOD_CONTRACT;
2041         m_ManagedThreadId = id;
2042     }
2043
2044     OBJECTREF GetThreadStartArg() { LIMITED_METHOD_CONTRACT; return m_ThreadStartArg; }
2045     void SetThreadStartArg(OBJECTREF newThreadStartArg) 
2046     {
2047         WRAPPER_NO_CONTRACT;
2048     
2049         _ASSERTE(newThreadStartArg == NULL);
2050         // Note: this is an unchecked assignment.  We are cleaning out the ThreadStartArg field when 
2051         // a thread starts so that ADU does not cause problems
2052         SetObjectReferenceUnchecked( (OBJECTREF *)&m_ThreadStartArg, newThreadStartArg);
2053     
2054     }
2055
2056     OBJECTREF GetDelegate()                   { LIMITED_METHOD_CONTRACT; return m_Delegate; }
2057     void      SetDelegate(OBJECTREF delegate);
2058
2059 #ifndef FEATURE_LEAK_CULTURE_INFO
2060     CULTUREINFOBASEREF GetCurrentUserCulture();
2061     CULTUREINFOBASEREF GetCurrentUICulture();
2062     OBJECTREF GetManagedThreadCulture(BOOL bUICulture);
2063     void ResetManagedThreadCulture(BOOL bUICulture);
2064     void ResetCurrentUserCulture();
2065     void ResetCurrentUICulture();
2066 #endif
2067
2068 #ifdef FEATURE_REMOTING
2069     // These expose the remoting context (System\Remoting\Context)
2070     OBJECTREF GetExposedContext() { LIMITED_METHOD_CONTRACT; return m_ExposedContext; }
2071     OBJECTREF SetExposedContext(OBJECTREF newContext) 
2072     {
2073         WRAPPER_NO_CONTRACT;
2074
2075         OBJECTREF oldContext = m_ExposedContext;
2076
2077         // Note: this is a very dangerous unchecked assignment.  We are taking
2078         // responsibilty here for cleaning out the ExposedContext field when 
2079         // an app domain is unloaded.
2080         SetObjectReferenceUnchecked( (OBJECTREF *)&m_ExposedContext, newContext );
2081
2082         return oldContext;
2083     }
2084 #endif
2085
2086 #ifdef FEATURE_LEAK_CULTURE_INFO
2087     CULTUREINFOBASEREF GetCurrentUserCulture()
2088     { 
2089         LIMITED_METHOD_CONTRACT; 
2090         return m_CurrentUserCulture;
2091     }
2092
2093     void ResetCurrentUserCulture()
2094     { 
2095         WRAPPER_NO_CONTRACT; 
2096         ClearObjectReference((OBJECTREF *)&m_CurrentUserCulture);
2097     }
2098
2099     CULTUREINFOBASEREF GetCurrentUICulture() 
2100     { 
2101         LIMITED_METHOD_CONTRACT; 
2102         return m_CurrentUICulture;
2103     }
2104
2105     void ResetCurrentUICulture()
2106     { 
2107         WRAPPER_NO_CONTRACT; 
2108         ClearObjectReference((OBJECTREF *)&m_CurrentUICulture);
2109     }
2110 #endif // FEATURE_LEAK_CULTURE_INFO
2111
2112 #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
2113     OBJECTREF GetSynchronizationContext()
2114     {
2115         LIMITED_METHOD_CONTRACT;
2116         return m_SynchronizationContext;
2117     }
2118 #endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
2119
2120 #ifdef FEATURE_COMPRESSEDSTACK    
2121     COMPRESSEDSTACKREF GetCompressedStack()
2122     {
2123         WRAPPER_NO_CONTRACT;
2124         if (m_ExecutionContext != NULL)
2125             return m_ExecutionContext->GetCompressedStack();
2126         return NULL;
2127     }
2128 #endif // #ifdef FEATURE_COMPRESSEDSTACK
2129     // SetDelegate is our "constructor" for the pathway where the exposed object is
2130     // created first.  InitExisting is our "constructor" for the pathway where an
2131     // existing physical thread is later exposed.
2132     void      InitExisting();
2133
2134     void ResetCulture()
2135     {
2136         LIMITED_METHOD_CONTRACT;
2137         ResetCurrentUserCulture();
2138         ResetCurrentUICulture();
2139     }
2140
2141     void ResetName()
2142     {
2143         LIMITED_METHOD_CONTRACT;
2144         m_Name = NULL;
2145     }
2146   
2147     void SetPriority(INT32 priority)
2148     {
2149         LIMITED_METHOD_CONTRACT;
2150         m_Priority = priority;
2151     }
2152     
2153     INT32 GetPriority() const
2154     {
2155         LIMITED_METHOD_CONTRACT;
2156         return m_Priority;
2157     }
2158 };
2159
2160 // MarshalByRefObjectBaseObject 
2161 // This class is the base class for MarshalByRefObject
2162 //  
2163 class MarshalByRefObjectBaseObject : public Object
2164 {
2165 #ifdef FEATURE_REMOTING
2166     friend class MscorlibBinder;
2167
2168   public:
2169     static int GetOffsetOfServerIdentity() { LIMITED_METHOD_CONTRACT; return offsetof(MarshalByRefObjectBaseObject, m_ServerIdentity); }
2170
2171   protected:
2172     // READ ME:
2173     // Modifying the order or fields of this object may require other changes to the
2174     //  classlib class definition of this object.
2175     OBJECTREF     m_ServerIdentity;
2176
2177   protected:
2178     MarshalByRefObjectBaseObject() {LIMITED_METHOD_CONTRACT;}
2179    ~MarshalByRefObjectBaseObject() {LIMITED_METHOD_CONTRACT;}   
2180 #endif   
2181 };
2182
2183
2184 // ContextBaseObject 
2185 // This class is the base class for Contexts
2186 //  
2187 class ContextBaseObject : public Object
2188 {
2189     friend class Context;
2190     friend class MscorlibBinder;
2191
2192   private:
2193     // READ ME:
2194     // Modifying the order or fields of this object may require other changes to the
2195     //  classlib class definition of this object.
2196
2197     OBJECTREF m_ctxProps;   // array of name-value pairs of properties
2198     OBJECTREF m_dphCtx;     // dynamic property holder
2199     OBJECTREF m_localDataStore; // context local store
2200     OBJECTREF m_serverContextChain; // server context sink chain
2201     OBJECTREF m_clientContextChain; // client context sink chain
2202     OBJECTREF m_exposedAppDomain;       //appDomain ??
2203     PTRARRAYREF m_ctxStatics; // holder for context relative statics
2204     
2205     Context*  m_internalContext;            // Pointer to the VM context
2206
2207     INT32 _ctxID;
2208     INT32 _ctxFlags;
2209     INT32 _numCtxProps;     // current count of properties
2210
2211     INT32 _ctxStaticsCurrentBucket;
2212     INT32 _ctxStaticsFreeIndex;
2213
2214   protected:
2215     ContextBaseObject() { LIMITED_METHOD_CONTRACT; }
2216    ~ContextBaseObject() { LIMITED_METHOD_CONTRACT; }
2217    
2218   public:
2219
2220     void SetInternalContext(Context* pCtx) 
2221     {
2222         LIMITED_METHOD_CONTRACT;
2223         // either transitioning from NULL to non-NULL or vice versa.  
2224         // But not setting NULL to NULL or non-NULL to non-NULL.
2225         _ASSERTE((m_internalContext == NULL) != (pCtx == NULL));
2226         m_internalContext = pCtx;
2227     }
2228     
2229     Context* GetInternalContext() 
2230     {
2231         LIMITED_METHOD_CONTRACT;
2232         return m_internalContext;
2233     }
2234
2235     OBJECTREF GetExposedDomain() { return m_exposedAppDomain; }
2236     OBJECTREF SetExposedDomain(OBJECTREF newDomain) 
2237     {
2238         LIMITED_METHOD_CONTRACT;
2239         OBJECTREF oldDomain = m_exposedAppDomain;
2240         SetObjectReference( (OBJECTREF *)&m_exposedAppDomain, newDomain, GetAppDomain() );
2241         return oldDomain;
2242     }
2243
2244     PTRARRAYREF GetContextStaticsHolder() 
2245     { 
2246         LIMITED_METHOD_CONTRACT;
2247         SUPPORTS_DAC;
2248         // The code that needs this should have faulted it in by now!
2249         _ASSERTE(m_ctxStatics != NULL); 
2250
2251         return m_ctxStatics; 
2252     }
2253 };
2254
2255 typedef DPTR(ContextBaseObject) PTR_ContextBaseObject;
2256
2257 // AppDomainBaseObject 
2258 // This class is the base class for application domains
2259 //  
2260 class AppDomainBaseObject : public MarshalByRefObjectBaseObject
2261 {
2262     friend class AppDomain;
2263     friend class MscorlibBinder;
2264
2265   protected:
2266     // READ ME:
2267     // Modifying the order or fields of this object may require other changes to the
2268     //  classlib class definition of this object.
2269     OBJECTREF    m_pDomainManager;     // AppDomainManager for host settings.
2270     OBJECTREF    m_LocalStore;
2271     OBJECTREF    m_FusionTable;
2272     OBJECTREF    m_pSecurityIdentity;  // Evidence associated with this domain
2273     OBJECTREF    m_pPolicies;          // Array of context policies associated with this domain
2274     OBJECTREF    m_pAssemblyEventHandler; // Delegate for 'loading assembly' event
2275     OBJECTREF    m_pTypeEventHandler;     // Delegate for 'resolve type' event
2276     OBJECTREF    m_pResourceEventHandler; // Delegate for 'resolve resource' event
2277     OBJECTREF    m_pAsmResolveEventHandler; // Delegate for 'resolve assembly' event
2278 #ifdef FEATURE_REFLECTION_ONLY_LOAD
2279     OBJECTREF    m_pReflectionAsmResolveEventHandler; //Delegate for 'reflection resolve assembly' event
2280 #endif    
2281 #ifdef FEATURE_REMOTING
2282     OBJECTREF    m_pDefaultContext;     // Default managed context for this AD.
2283 #endif    
2284 #ifdef FEATURE_CLICKONCE
2285     OBJECTREF    m_pActivationContext;   // ClickOnce ActivationContext.
2286     OBJECTREF    m_pApplicationIdentity; // App ApplicationIdentity.
2287 #endif    
2288     OBJECTREF    m_pApplicationTrust;    // App ApplicationTrust.
2289 #ifdef FEATURE_IMPERSONATION
2290     OBJECTREF    m_pDefaultPrincipal;  // Lazily computed default principle object used by threads
2291 #endif // FEATURE_IMPERSONATION
2292 #ifdef FEATURE_REMOTING    
2293     OBJECTREF    m_pURITable;          // Identity table for remoting
2294 #endif    
2295     OBJECTREF    m_pProcessExitEventHandler; // Delegate for 'process exit' event.  Only used in Default appdomain.
2296     OBJECTREF    m_pDomainUnloadEventHandler; // Delegate for 'about to unload domain' event
2297     OBJECTREF    m_pUnhandledExceptionEventHandler; // Delegate for 'unhandled exception' event
2298
2299     OBJECTREF    m_compatFlags;
2300
2301 #ifdef FEATURE_EXCEPTION_NOTIFICATIONS
2302     OBJECTREF    m_pFirstChanceExceptionHandler; // Delegate for 'FirstChance Exception' event
2303 #endif // FEATURE_EXCEPTION_NOTIFICATIONS
2304
2305     AppDomain*   m_pDomain;            // Pointer to the BaseDomain Structure
2306 #ifdef FEATURE_CAS_POLICY
2307     INT32        m_iPrincipalPolicy;   // Type of principal to create by default
2308 #endif    
2309     CLR_BOOL     m_bHasSetPolicy;               // SetDomainPolicy has been called for this domain
2310     CLR_BOOL     m_bIsFastFullTrustDomain;      // We know for sure that this is a homogeneous full trust domain.  
2311     CLR_BOOL     m_compatFlagsInitialized;
2312
2313   protected:
2314     AppDomainBaseObject() { LIMITED_METHOD_CONTRACT; }
2315    ~AppDomainBaseObject() { LIMITED_METHOD_CONTRACT; }
2316    
2317   public:
2318
2319     void SetDomain(AppDomain* p) 
2320     {
2321         LIMITED_METHOD_CONTRACT;
2322         m_pDomain = p;
2323     }
2324     AppDomain* GetDomain() 
2325     {
2326         LIMITED_METHOD_CONTRACT;
2327         return m_pDomain;
2328     }
2329
2330     OBJECTREF GetSecurityIdentity()
2331     {
2332         LIMITED_METHOD_CONTRACT;
2333         return m_pSecurityIdentity;
2334     }
2335
2336     OBJECTREF GetAppDomainManager()
2337     {
2338         LIMITED_METHOD_CONTRACT;
2339         return m_pDomainManager;
2340     }
2341
2342     OBJECTREF GetApplicationTrust()
2343     {
2344         LIMITED_METHOD_CONTRACT;
2345         return m_pApplicationTrust;
2346     }
2347
2348     BOOL GetIsFastFullTrustDomain()
2349     {
2350         LIMITED_METHOD_CONTRACT;
2351         return !!m_bIsFastFullTrustDomain;
2352     }
2353
2354
2355     // Ref needs to be a PTRARRAYREF
2356     void SetPolicies(OBJECTREF ref)
2357     {
2358         WRAPPER_NO_CONTRACT;
2359         SetObjectReference(&m_pPolicies, ref, m_pDomain );
2360     }
2361 #ifdef FEATURE_REMOTING
2362     void SetDefaultContext(OBJECTREF ref)
2363     {
2364         WRAPPER_NO_CONTRACT;
2365         SetObjectReference(&m_pDefaultContext,ref,m_pDomain);
2366     }
2367 #endif
2368     BOOL HasSetPolicy()
2369     {
2370         LIMITED_METHOD_CONTRACT;
2371         return m_bHasSetPolicy;
2372     }
2373
2374 #ifdef FEATURE_CLICKONCE
2375     BOOL HasActivationContext()
2376     {
2377         LIMITED_METHOD_CONTRACT;
2378         return m_pActivationContext != NULL;
2379     }
2380 #endif // FEATURE_CLICKONCE
2381
2382 #ifdef FEATURE_EXCEPTION_NOTIFICATIONS
2383     // Returns the reference to the delegate of the first chance exception notification handler
2384     OBJECTREF GetFirstChanceExceptionNotificationHandler()
2385     {
2386         LIMITED_METHOD_CONTRACT;
2387
2388         return m_pFirstChanceExceptionHandler;
2389     }
2390 #endif // FEATURE_EXCEPTION_NOTIFICATIONS
2391 };
2392
2393
2394 // The managed definition of AppDomainSetup is in BCL\System\AppDomainSetup.cs
2395 class AppDomainSetupObject : public Object
2396 {
2397     friend class MscorlibBinder;
2398
2399   protected:
2400     PTRARRAYREF m_Entries;
2401     STRINGREF m_AppBase;
2402     OBJECTREF m_AppDomainInitializer;
2403     PTRARRAYREF m_AppDomainInitializerArguments;
2404 #ifdef FEATURE_CLICKONCE
2405     OBJECTREF m_ActivationArguments;
2406 #endif // FEATURE_CLICKONCE
2407     STRINGREF m_ApplicationTrust;
2408     I1ARRAYREF m_ConfigurationBytes;
2409     STRINGREF m_AppDomainManagerAssembly;
2410     STRINGREF m_AppDomainManagerType;
2411     OBJECTREF m_CompatFlags;
2412     STRINGREF m_TargetFrameworkName;
2413     INT32 m_LoaderOptimization;
2414 #ifdef FEATURE_COMINTEROP
2415     CLR_BOOL m_DisableInterfaceCache;
2416 #endif // FEATURE_COMINTEROP
2417     CLR_BOOL m_CheckedForTargetFrameworkName;
2418 #ifdef FEATURE_RANDOMIZED_STRING_HASHING
2419     CLR_BOOL m_UseRandomizedStringHashing;
2420 #endif
2421
2422
2423   protected:
2424     AppDomainSetupObject() { LIMITED_METHOD_CONTRACT; }
2425    ~AppDomainSetupObject() { LIMITED_METHOD_CONTRACT; }
2426
2427   public:
2428 #ifdef FEATURE_RANDOMIZED_STRING_HASHING
2429     BOOL UseRandomizedStringHashing() { LIMITED_METHOD_CONTRACT; return (BOOL) m_UseRandomizedStringHashing; }
2430 #endif // FEATURE_RANDOMIZED_STRING_HASHING
2431 };
2432 typedef DPTR(AppDomainSetupObject) PTR_AppDomainSetupObject;
2433 #ifdef USE_CHECKED_OBJECTREFS
2434 typedef REF<AppDomainSetupObject> APPDOMAINSETUPREF;
2435 #else
2436 typedef AppDomainSetupObject*     APPDOMAINSETUPREF;
2437 #endif
2438
2439 // AssemblyBaseObject 
2440 // This class is the base class for assemblies
2441 //  
2442 class AssemblyBaseObject : public Object
2443 {
2444     friend class Assembly;
2445     friend class MscorlibBinder;
2446
2447   protected:
2448     // READ ME:
2449     // Modifying the order or fields of this object may require other changes to the
2450     //  classlib class definition of this object.
2451     OBJECTREF     m_pModuleEventHandler;   // Delegate for 'resolve module' event
2452     STRINGREF     m_fullname;              // Slot for storing assemblies fullname
2453     OBJECTREF     m_pSyncRoot;             // Pointer to loader allocator to keep collectible types alive, and to serve as the syncroot for assembly building in ref.emit
2454     DomainAssembly* m_pAssembly;           // Pointer to the Assembly Structure
2455 #ifdef FEATURE_APPX
2456     UINT32        m_flags;
2457 #endif
2458
2459   protected:
2460     AssemblyBaseObject() { LIMITED_METHOD_CONTRACT; }
2461    ~AssemblyBaseObject() { LIMITED_METHOD_CONTRACT; }
2462    
2463   public:
2464
2465     void SetAssembly(DomainAssembly* p) 
2466     {
2467         LIMITED_METHOD_CONTRACT;
2468         m_pAssembly = p;
2469     }
2470
2471     DomainAssembly* GetDomainAssembly() 
2472     {
2473         LIMITED_METHOD_CONTRACT;
2474         return m_pAssembly;
2475     }
2476
2477     Assembly* GetAssembly();
2478
2479     void SetSyncRoot(OBJECTREF pSyncRoot)
2480     {
2481         WRAPPER_NO_CONTRACT;
2482         SetObjectReferenceUnchecked(&m_pSyncRoot, pSyncRoot);
2483     }
2484 };
2485 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive);
2486 #define FC_RETURN_ASSEMBLY_OBJECT(pAssembly, refKeepAlive) FC_INNER_RETURN(AssemblyBaseObject*, GetRuntimeAssemblyHelper(__me, pAssembly, refKeepAlive))
2487
2488 // AssemblyNameBaseObject 
2489 // This class is the base class for assembly names
2490 //  
2491 class AssemblyNameBaseObject : public Object
2492 {
2493     friend class AssemblyNative;
2494     friend class AppDomainNative;
2495     friend class MscorlibBinder;
2496
2497   protected:
2498     // READ ME:
2499     // Modifying the order or fields of this object may require other changes to the
2500     //  classlib class definition of this object.
2501
2502     OBJECTREF     m_pSimpleName; 
2503     U1ARRAYREF    m_pPublicKey;
2504     U1ARRAYREF    m_pPublicKeyToken;
2505     OBJECTREF     m_pCultureInfo;
2506     OBJECTREF     m_pCodeBase;
2507     OBJECTREF     m_pVersion;
2508     OBJECTREF     m_StrongNameKeyPair;
2509     OBJECTREF     m_siInfo;
2510     U1ARRAYREF    m_HashForControl;
2511     DWORD         m_HashAlgorithm;
2512     DWORD         m_HashAlgorithmForControl;
2513     DWORD         m_VersionCompatibility;
2514     DWORD         m_Flags;
2515
2516   protected:
2517     AssemblyNameBaseObject() { LIMITED_METHOD_CONTRACT; }
2518    ~AssemblyNameBaseObject() { LIMITED_METHOD_CONTRACT; }
2519    
2520   public:
2521     OBJECTREF GetSimpleName() { LIMITED_METHOD_CONTRACT; return m_pSimpleName; }
2522     U1ARRAYREF GetPublicKey() { LIMITED_METHOD_CONTRACT; return m_pPublicKey; }
2523     U1ARRAYREF GetPublicKeyToken() { LIMITED_METHOD_CONTRACT; return m_pPublicKeyToken; }
2524     OBJECTREF GetStrongNameKeyPair() { LIMITED_METHOD_CONTRACT; return m_StrongNameKeyPair; }
2525     OBJECTREF GetCultureInfo() { LIMITED_METHOD_CONTRACT; return m_pCultureInfo; }
2526     OBJECTREF GetAssemblyCodeBase() { LIMITED_METHOD_CONTRACT; return m_pCodeBase; }
2527     OBJECTREF GetVersion() { LIMITED_METHOD_CONTRACT; return m_pVersion; }
2528     DWORD GetAssemblyHashAlgorithm() { LIMITED_METHOD_CONTRACT; return m_HashAlgorithm; }
2529     DWORD GetFlags() { LIMITED_METHOD_CONTRACT; return m_Flags; }
2530     U1ARRAYREF GetHashForControl() { LIMITED_METHOD_CONTRACT; return m_HashForControl;}
2531     DWORD GetHashAlgorithmForControl() { LIMITED_METHOD_CONTRACT; return m_HashAlgorithmForControl; }
2532 };
2533
2534 // VersionBaseObject
2535 // This class is the base class for versions
2536 //
2537 class VersionBaseObject : public Object
2538 {
2539     friend class MscorlibBinder;
2540
2541   protected:
2542     // READ ME:
2543     // Modifying the order or fields of this object may require other changes to the
2544     //  classlib class definition of this object.
2545
2546     int m_Major;
2547     int m_Minor;
2548     int m_Build;
2549     int m_Revision;
2550  
2551     VersionBaseObject() {LIMITED_METHOD_CONTRACT;}
2552    ~VersionBaseObject() {LIMITED_METHOD_CONTRACT;}
2553
2554   public:    
2555     int GetMajor() { LIMITED_METHOD_CONTRACT; return m_Major; }
2556     int GetMinor() { LIMITED_METHOD_CONTRACT; return m_Minor; }
2557     int GetBuild() { LIMITED_METHOD_CONTRACT; return m_Build; }
2558     int GetRevision() { LIMITED_METHOD_CONTRACT; return m_Revision; }
2559 };
2560
2561 // FrameSecurityDescriptorBaseObject 
2562 // This class is the base class for the frame security descriptor
2563 //  
2564
2565 class FrameSecurityDescriptorBaseObject : public Object
2566 {
2567     friend class MscorlibBinder;
2568
2569   protected:
2570     // READ ME:
2571     // Modifying the order or fields of this object may require other changes to the
2572     //  classlib class definition of this object.
2573
2574     OBJECTREF       m_assertions;    // imperative
2575     OBJECTREF       m_denials;      // imperative
2576     OBJECTREF       m_restriction;  //  imperative
2577     OBJECTREF       m_DeclarativeAssertions;
2578     OBJECTREF       m_DeclarativeDenials;
2579     OBJECTREF       m_DeclarativeRestrictions;
2580     CLR_BOOL        m_assertFT;
2581     CLR_BOOL        m_assertAllPossible;
2582     CLR_BOOL        m_declSecComputed;
2583     
2584
2585
2586   protected:
2587     FrameSecurityDescriptorBaseObject() {LIMITED_METHOD_CONTRACT;}
2588    ~FrameSecurityDescriptorBaseObject() {LIMITED_METHOD_CONTRACT;}
2589    
2590   public:
2591
2592     INT32 GetOverridesCount()
2593     {
2594         LIMITED_METHOD_CONTRACT;
2595         INT32 ret =0;
2596         if (m_restriction != NULL)
2597             ret++;
2598         if (m_denials != NULL)
2599             ret++;        
2600         if (m_DeclarativeDenials != NULL)
2601             ret++;
2602         if (m_DeclarativeRestrictions != NULL)
2603             ret++;
2604         return ret;
2605     }
2606
2607     INT32 GetAssertCount()
2608     {
2609         LIMITED_METHOD_CONTRACT;
2610         INT32 ret =0;
2611         if (m_assertions != NULL || m_DeclarativeAssertions != NULL || HasAssertAllPossible())
2612             ret++;
2613         return ret;
2614     }  
2615
2616     BOOL HasAssertFT()
2617     {
2618         LIMITED_METHOD_CONTRACT;
2619         return m_assertFT;
2620     }
2621
2622     BOOL IsDeclSecComputed()
2623     {
2624         LIMITED_METHOD_CONTRACT;
2625         return m_declSecComputed;
2626     }
2627
2628     BOOL HasAssertAllPossible()
2629     {
2630         LIMITED_METHOD_CONTRACT;
2631         return m_assertAllPossible;
2632     }
2633
2634     OBJECTREF GetImperativeAssertions()
2635     {
2636         LIMITED_METHOD_CONTRACT;
2637         return m_assertions;
2638     }
2639    OBJECTREF GetDeclarativeAssertions()
2640     {
2641         LIMITED_METHOD_CONTRACT;
2642         return m_DeclarativeAssertions;
2643     }
2644     OBJECTREF GetImperativeDenials()
2645     {
2646         LIMITED_METHOD_CONTRACT;
2647         return m_denials;
2648     }
2649     OBJECTREF GetDeclarativeDenials()
2650     {
2651         LIMITED_METHOD_CONTRACT;
2652         return m_DeclarativeDenials;
2653     }
2654     OBJECTREF GetImperativeRestrictions()
2655     {
2656         LIMITED_METHOD_CONTRACT;
2657         return m_restriction;
2658     }
2659    OBJECTREF GetDeclarativeRestrictions()
2660     {
2661         LIMITED_METHOD_CONTRACT;
2662         return m_DeclarativeRestrictions;
2663     }
2664     void SetImperativeAssertions(OBJECTREF assertRef)
2665     {
2666         LIMITED_METHOD_CONTRACT;
2667         SetObjectReference(&m_assertions, assertRef, this->GetAppDomain());
2668     }
2669     void SetDeclarativeAssertions(OBJECTREF assertRef)
2670     {
2671         LIMITED_METHOD_CONTRACT;
2672         SetObjectReference(&m_DeclarativeAssertions, assertRef, this->GetAppDomain());
2673     }
2674     void SetImperativeDenials(OBJECTREF denialRef)
2675     {
2676         LIMITED_METHOD_CONTRACT;
2677         SetObjectReference(&m_denials, denialRef, this->GetAppDomain()); 
2678     }
2679
2680     void SetDeclarativeDenials(OBJECTREF denialRef)
2681     {
2682         LIMITED_METHOD_CONTRACT;
2683         SetObjectReference(&m_DeclarativeDenials, denialRef, this->GetAppDomain()); 
2684     }
2685
2686     void SetImperativeRestrictions(OBJECTREF restrictRef)
2687     {
2688         LIMITED_METHOD_CONTRACT;
2689         SetObjectReference(&m_restriction, restrictRef, this->GetAppDomain());
2690     }
2691
2692     void SetDeclarativeRestrictions(OBJECTREF restrictRef)
2693     {
2694         LIMITED_METHOD_CONTRACT;
2695         SetObjectReference(&m_DeclarativeRestrictions, restrictRef, this->GetAppDomain());
2696     }
2697     void SetAssertAllPossible(BOOL assertAllPossible)
2698     {
2699         LIMITED_METHOD_CONTRACT;
2700         m_assertAllPossible = !!assertAllPossible;
2701     }
2702     
2703     void SetAssertFT(BOOL assertFT)
2704     {
2705         LIMITED_METHOD_CONTRACT;
2706         m_assertFT = !!assertFT;
2707     }
2708     void SetDeclSecComputed(BOOL declSec)
2709     {
2710         LIMITED_METHOD_CONTRACT;
2711         m_declSecComputed = !!declSec;
2712     }
2713 };
2714
2715 #ifdef FEATURE_COMPRESSEDSTACK
2716 class FrameSecurityDescriptorWithResolverBaseObject : public FrameSecurityDescriptorBaseObject
2717 {
2718 public:
2719     OBJECTREF m_resolver;
2720
2721 public:
2722     void SetDynamicMethodResolver(OBJECTREF resolver)
2723     {
2724         LIMITED_METHOD_CONTRACT;
2725         SetObjectReference(&m_resolver, resolver, this->GetAppDomain());
2726     }
2727 };
2728 #endif // FEATURE_COMPRESSEDSTACK
2729
2730 class WeakReferenceObject : public Object
2731 {
2732 public:
2733     Volatile<OBJECTHANDLE> m_Handle;
2734 };
2735
2736 #ifdef USE_CHECKED_OBJECTREFS
2737
2738 typedef REF<ReflectModuleBaseObject> REFLECTMODULEBASEREF;
2739
2740 typedef REF<ReflectClassBaseObject> REFLECTCLASSBASEREF;
2741
2742 typedef REF<ReflectMethodObject> REFLECTMETHODREF;
2743
2744 typedef REF<ReflectFieldObject> REFLECTFIELDREF;
2745
2746 typedef REF<ThreadBaseObject> THREADBASEREF;
2747
2748 typedef REF<AppDomainBaseObject> APPDOMAINREF;
2749
2750 typedef REF<MarshalByRefObjectBaseObject> MARSHALBYREFOBJECTBASEREF;
2751
2752 typedef REF<ContextBaseObject> CONTEXTBASEREF;
2753
2754 typedef REF<AssemblyBaseObject> ASSEMBLYREF;
2755
2756 typedef REF<AssemblyNameBaseObject> ASSEMBLYNAMEREF;
2757
2758 typedef REF<VersionBaseObject> VERSIONREF;
2759
2760 typedef REF<FrameSecurityDescriptorBaseObject> FRAMESECDESCREF;
2761
2762 #ifdef FEATURE_COMPRESSEDSTACK
2763 typedef REF<FrameSecurityDescriptorWithResolverBaseObject> FRAMESECDESWITHRESOLVERCREF;
2764 #endif // FEATURE_COMPRESSEDSTACK
2765
2766 typedef REF<WeakReferenceObject> WEAKREFERENCEREF;
2767
2768 inline ARG_SLOT ObjToArgSlot(OBJECTREF objRef)
2769 {
2770     LIMITED_METHOD_CONTRACT;
2771     LPVOID v;
2772     v = OBJECTREFToObject(objRef);
2773     return (ARG_SLOT)(SIZE_T)v;
2774 }
2775
2776 inline OBJECTREF ArgSlotToObj(ARG_SLOT i)
2777 {
2778     LIMITED_METHOD_CONTRACT;
2779     LPVOID v;
2780     v = (LPVOID)(SIZE_T)i;
2781     return ObjectToOBJECTREF ((Object*)v);
2782 }
2783
2784 inline ARG_SLOT StringToArgSlot(STRINGREF sr)
2785 {
2786     LIMITED_METHOD_CONTRACT;
2787     LPVOID v;
2788     v = OBJECTREFToObject(sr);
2789     return (ARG_SLOT)(SIZE_T)v;
2790 }
2791
2792 inline STRINGREF ArgSlotToString(ARG_SLOT s)
2793 {
2794     LIMITED_METHOD_CONTRACT;
2795     LPVOID v;
2796     v = (LPVOID)(SIZE_T)s;
2797     return ObjectToSTRINGREF ((StringObject*)v);
2798 }
2799
2800 #else // USE_CHECKED_OBJECTREFS
2801
2802 typedef PTR_ReflectModuleBaseObject REFLECTMODULEBASEREF;
2803 typedef PTR_ReflectClassBaseObject REFLECTCLASSBASEREF;
2804 typedef PTR_ReflectMethodObject REFLECTMETHODREF;
2805 typedef PTR_ReflectFieldObject REFLECTFIELDREF;
2806 typedef PTR_ThreadBaseObject THREADBASEREF;
2807 typedef PTR_AppDomainBaseObject APPDOMAINREF;
2808 typedef PTR_AssemblyBaseObject ASSEMBLYREF;
2809 typedef PTR_AssemblyNameBaseObject ASSEMBLYNAMEREF;
2810 typedef PTR_ContextBaseObject CONTEXTBASEREF;
2811
2812 #ifndef DACCESS_COMPILE
2813 typedef MarshalByRefObjectBaseObject* MARSHALBYREFOBJECTBASEREF;
2814 typedef VersionBaseObject* VERSIONREF;
2815 typedef FrameSecurityDescriptorBaseObject* FRAMESECDESCREF;
2816
2817 #ifdef FEATURE_COMPRESSEDSTACK
2818 typedef FrameSecurityDescriptorWithResolverBaseObject* FRAMESECDESWITHRESOLVERCREF;
2819 #endif // FEATURE_COMPRESSEDSTACK
2820
2821 typedef WeakReferenceObject* WEAKREFERENCEREF;
2822 #endif // #ifndef DACCESS_COMPILE
2823
2824 #define ObjToArgSlot(objref) ((ARG_SLOT)(SIZE_T)(objref))
2825 #define ArgSlotToObj(s) ((OBJECTREF)(SIZE_T)(s))
2826
2827 #define StringToArgSlot(objref) ((ARG_SLOT)(SIZE_T)(objref))
2828 #define ArgSlotToString(s)    ((STRINGREF)(SIZE_T)(s))
2829
2830 #endif //USE_CHECKED_OBJECTREFS
2831
2832 #define PtrToArgSlot(ptr) ((ARG_SLOT)(SIZE_T)(ptr))
2833 #define ArgSlotToPtr(s)   ((LPVOID)(SIZE_T)(s))
2834
2835 #define BoolToArgSlot(b)  ((ARG_SLOT)(CLR_BOOL)(!!(b)))
2836 #define ArgSlotToBool(s)  ((BOOL)(s))
2837
2838 STRINGREF AllocateString(SString sstr);
2839 CHARARRAYREF AllocateCharArray(DWORD dwArrayLength);
2840
2841
2842 class TransparentProxyObject : public Object
2843 {
2844     friend class MscorlibBinder;
2845     friend class CheckAsmOffsets;
2846
2847 public:
2848     MethodTable * GetMethodTableBeingProxied()
2849     {
2850         LIMITED_METHOD_CONTRACT;
2851         return _pMT;
2852     }
2853     void SetMethodTableBeingProxied(MethodTable * pMT)
2854     {
2855         LIMITED_METHOD_CONTRACT;
2856         _pMT = pMT;
2857     }
2858
2859     MethodTable * GetInterfaceMethodTable()
2860     {
2861         LIMITED_METHOD_CONTRACT;
2862         return _pInterfaceMT;
2863     }
2864     void SetInterfaceMethodTable(MethodTable * pInterfaceMT)
2865     {
2866         LIMITED_METHOD_CONTRACT;
2867         _pInterfaceMT = pInterfaceMT;
2868     }
2869
2870     void * GetStub()
2871     {
2872         LIMITED_METHOD_CONTRACT;
2873         return _stub;
2874     }
2875     void SetStub(void * pStub)
2876     {
2877         LIMITED_METHOD_CONTRACT;
2878         _stub = pStub;
2879     }
2880
2881     OBJECTREF GetStubData()
2882     {
2883         LIMITED_METHOD_CONTRACT;
2884         return _stubData;
2885     }
2886     void SetStubData(OBJECTREF stubData)
2887     {
2888         LIMITED_METHOD_CONTRACT;
2889         SetObjectReference(&_stubData, stubData, GetAppDomain());
2890     }
2891
2892     OBJECTREF GetRealProxy()
2893     {
2894         LIMITED_METHOD_CONTRACT;
2895         return _rp;
2896     }
2897     void SetRealProxy(OBJECTREF realProxy)
2898     {
2899         LIMITED_METHOD_CONTRACT;
2900         SetObjectReference(&_rp, realProxy, GetAppDomain());
2901     }
2902
2903     static int GetOffsetOfRP() { LIMITED_METHOD_CONTRACT; return offsetof(TransparentProxyObject, _rp); }
2904     
2905 protected:
2906     TransparentProxyObject()
2907     {LIMITED_METHOD_CONTRACT;}; // don't instantiate this class directly
2908     ~TransparentProxyObject(){LIMITED_METHOD_CONTRACT;};
2909
2910 private:
2911     OBJECTREF       _rp;
2912     OBJECTREF       _stubData;
2913     MethodTable*    _pMT;
2914     MethodTable*    _pInterfaceMT;
2915     void*           _stub;
2916 };
2917
2918 #ifdef USE_CHECKED_OBJECTREFS
2919 typedef REF<TransparentProxyObject> TRANSPARENTPROXYREF;
2920 #else
2921 typedef TransparentProxyObject*     TRANSPARENTPROXYREF;
2922 #endif
2923
2924
2925 class RealProxyObject : public Object
2926 {
2927     friend class MscorlibBinder;
2928
2929 public:
2930     DWORD GetOptFlags()
2931     {
2932         LIMITED_METHOD_CONTRACT;
2933         return _optFlags;
2934     }
2935     VOID SetOptFlags(DWORD flags)
2936     {
2937         LIMITED_METHOD_CONTRACT;
2938         _optFlags = flags;
2939     }
2940
2941     DWORD GetDomainID()
2942     {
2943         LIMITED_METHOD_CONTRACT;
2944         return _domainID;
2945     }
2946
2947     TRANSPARENTPROXYREF GetTransparentProxy()
2948     {
2949         LIMITED_METHOD_CONTRACT;
2950         return (TRANSPARENTPROXYREF&)_tp;
2951     }
2952     void SetTransparentProxy(TRANSPARENTPROXYREF tp)
2953     {
2954         LIMITED_METHOD_CONTRACT;
2955         SetObjectReference(&_tp, (OBJECTREF)tp, GetAppDomain());
2956     }
2957
2958     static int GetOffsetOfIdentity() { LIMITED_METHOD_CONTRACT; return offsetof(RealProxyObject, _identity); }
2959     static int GetOffsetOfServerObject() { LIMITED_METHOD_CONTRACT; return offsetof(RealProxyObject, _serverObject); }
2960     static int GetOffsetOfServerIdentity() { LIMITED_METHOD_CONTRACT; return offsetof(RealProxyObject, _srvIdentity); }
2961
2962 protected:
2963     RealProxyObject()
2964     {
2965         LIMITED_METHOD_CONTRACT;
2966     }; // don't instantiate this class directly
2967     ~RealProxyObject(){ LIMITED_METHOD_CONTRACT; };
2968
2969 private:
2970     OBJECTREF       _tp;
2971     OBJECTREF       _identity;
2972     OBJECTREF       _serverObject;
2973     DWORD           _flags;
2974     DWORD           _optFlags;
2975     DWORD           _domainID;
2976     OBJECTHANDLE    _srvIdentity;
2977 };
2978
2979 #ifdef USE_CHECKED_OBJECTREFS
2980 typedef REF<RealProxyObject> REALPROXYREF;
2981 #else
2982 typedef RealProxyObject*     REALPROXYREF;
2983 #endif
2984
2985
2986 #ifdef FEATURE_COMINTEROP
2987
2988 //-------------------------------------------------------------
2989 // class ComObject, Exposed class __ComObject
2990 // 
2991 // 
2992 //-------------------------------------------------------------
2993 class ComObject : public MarshalByRefObjectBaseObject
2994 {
2995     friend class MscorlibBinder;
2996
2997 protected:
2998
2999     ComObject()
3000     {LIMITED_METHOD_CONTRACT;}; // don't instantiate this class directly
3001     ~ComObject(){LIMITED_METHOD_CONTRACT;};
3002
3003 public:
3004     OBJECTREF           m_ObjectToDataMap;
3005
3006     //--------------------------------------------------------------------
3007     // SupportsInterface
3008     static BOOL SupportsInterface(OBJECTREF oref, MethodTable* pIntfTable);
3009
3010     //--------------------------------------------------------------------
3011     // SupportsInterface
3012     static void ThrowInvalidCastException(OBJECTREF *pObj, MethodTable* pCastToMT);
3013
3014     //-----------------------------------------------------------------
3015     // GetComIPFromRCW
3016     static IUnknown* GetComIPFromRCW(OBJECTREF *pObj, MethodTable* pIntfTable);
3017
3018     //-----------------------------------------------------------------
3019     // GetComIPFromRCWThrowing
3020     static IUnknown* GetComIPFromRCWThrowing(OBJECTREF *pObj, MethodTable* pIntfTable);
3021
3022     //-----------------------------------------------------------
3023     // create an empty ComObjectRef
3024     static OBJECTREF CreateComObjectRef(MethodTable* pMT);
3025
3026     //-----------------------------------------------------------
3027     // Release all the data associated with the __ComObject.
3028     static void ReleaseAllData(OBJECTREF oref);
3029
3030     //-----------------------------------------------------------
3031     // Redirection for ToString
3032     static FCDECL1(MethodDesc *, GetRedirectedToStringMD, Object *pThisUNSAFE);
3033     static FCDECL2(StringObject *, RedirectToString, Object *pThisUNSAFE, MethodDesc *pToStringMD);    
3034
3035     //-----------------------------------------------------------
3036     // Redirection for GetHashCode
3037     static FCDECL1(MethodDesc *, GetRedirectedGetHashCodeMD, Object *pThisUNSAFE);
3038     static FCDECL2(int, RedirectGetHashCode, Object *pThisUNSAFE, MethodDesc *pGetHashCodeMD);    
3039
3040     //-----------------------------------------------------------
3041     // Redirection for Equals
3042     static FCDECL1(MethodDesc *, GetRedirectedEqualsMD, Object *pThisUNSAFE);
3043     static FCDECL3(FC_BOOL_RET, RedirectEquals, Object *pThisUNSAFE, Object *pOtherUNSAFE, MethodDesc *pEqualsMD);    
3044 };
3045
3046 #ifdef USE_CHECKED_OBJECTREFS
3047 typedef REF<ComObject> COMOBJECTREF;
3048 #else
3049 typedef ComObject*     COMOBJECTREF;
3050 #endif
3051
3052
3053 //-------------------------------------------------------------
3054 // class UnknownWrapper, Exposed class UnknownWrapper
3055 // 
3056 // 
3057 //-------------------------------------------------------------
3058 class UnknownWrapper : public Object
3059 {
3060 protected:
3061
3062     UnknownWrapper(UnknownWrapper &wrap) {LIMITED_METHOD_CONTRACT}; // dissalow copy construction.
3063     UnknownWrapper() {LIMITED_METHOD_CONTRACT;}; // don't instantiate this class directly
3064     ~UnknownWrapper() {LIMITED_METHOD_CONTRACT;};
3065
3066     OBJECTREF m_WrappedObject;
3067
3068 public:
3069     OBJECTREF GetWrappedObject()
3070     {
3071         LIMITED_METHOD_CONTRACT;
3072         return m_WrappedObject;
3073     }
3074
3075     void SetWrappedObject(OBJECTREF pWrappedObject)
3076     {
3077         LIMITED_METHOD_CONTRACT;
3078         m_WrappedObject = pWrappedObject;
3079     }
3080 };
3081
3082 #ifdef USE_CHECKED_OBJECTREFS
3083 typedef REF<UnknownWrapper> UNKNOWNWRAPPEROBJECTREF;
3084 #else
3085 typedef UnknownWrapper*     UNKNOWNWRAPPEROBJECTREF;
3086 #endif
3087
3088
3089 //-------------------------------------------------------------
3090 // class DispatchWrapper, Exposed class DispatchWrapper
3091 // 
3092 // 
3093 //-------------------------------------------------------------
3094 class DispatchWrapper : public Object
3095 {
3096 protected:
3097
3098     DispatchWrapper(DispatchWrapper &wrap) {LIMITED_METHOD_CONTRACT}; // dissalow copy construction.
3099     DispatchWrapper() {LIMITED_METHOD_CONTRACT;}; // don't instantiate this class directly
3100     ~DispatchWrapper() {LIMITED_METHOD_CONTRACT;};
3101
3102     OBJECTREF m_WrappedObject;
3103
3104 public:
3105     OBJECTREF GetWrappedObject()
3106     {
3107         LIMITED_METHOD_CONTRACT;
3108         return m_WrappedObject;
3109     }
3110
3111     void SetWrappedObject(OBJECTREF pWrappedObject)
3112     {
3113         LIMITED_METHOD_CONTRACT;
3114         m_WrappedObject = pWrappedObject;
3115     }
3116 };
3117
3118 #ifdef USE_CHECKED_OBJECTREFS
3119 typedef REF<DispatchWrapper> DISPATCHWRAPPEROBJECTREF;
3120 #else
3121 typedef DispatchWrapper*     DISPATCHWRAPPEROBJECTREF;
3122 #endif
3123
3124
3125 //-------------------------------------------------------------
3126 // class VariantWrapper, Exposed class VARIANTWRAPPEROBJECTREF
3127 // 
3128 // 
3129 //-------------------------------------------------------------
3130 class VariantWrapper : public Object
3131 {
3132 protected:
3133
3134     VariantWrapper(VariantWrapper &wrap) {LIMITED_METHOD_CONTRACT}; // dissalow copy construction.
3135     VariantWrapper() {LIMITED_METHOD_CONTRACT}; // don't instantiate this class directly
3136     ~VariantWrapper() {LIMITED_METHOD_CONTRACT};
3137
3138     OBJECTREF m_WrappedObject;
3139
3140 public:
3141     OBJECTREF GetWrappedObject()
3142     {
3143         LIMITED_METHOD_CONTRACT;
3144         return m_WrappedObject;
3145     }
3146
3147     void SetWrappedObject(OBJECTREF pWrappedObject)
3148     {
3149         LIMITED_METHOD_CONTRACT;
3150         m_WrappedObject = pWrappedObject;
3151     }
3152 };
3153
3154 #ifdef USE_CHECKED_OBJECTREFS
3155 typedef REF<VariantWrapper> VARIANTWRAPPEROBJECTREF;
3156 #else
3157 typedef VariantWrapper*     VARIANTWRAPPEROBJECTREF;
3158 #endif
3159
3160
3161 //-------------------------------------------------------------
3162 // class ErrorWrapper, Exposed class ErrorWrapper
3163 // 
3164 // 
3165 //-------------------------------------------------------------
3166 class ErrorWrapper : public Object
3167 {
3168 protected:
3169
3170     ErrorWrapper(ErrorWrapper &wrap) {LIMITED_METHOD_CONTRACT}; // dissalow copy construction.
3171     ErrorWrapper() {LIMITED_METHOD_CONTRACT;}; // don't instantiate this class directly
3172     ~ErrorWrapper() {LIMITED_METHOD_CONTRACT;};
3173
3174     INT32 m_ErrorCode;
3175
3176 public:
3177     INT32 GetErrorCode()
3178     {
3179         LIMITED_METHOD_CONTRACT;
3180         return m_ErrorCode;
3181     }
3182
3183     void SetErrorCode(int ErrorCode)
3184     {
3185         LIMITED_METHOD_CONTRACT;
3186         m_ErrorCode = ErrorCode;
3187     }
3188 };
3189
3190 #ifdef USE_CHECKED_OBJECTREFS
3191 typedef REF<ErrorWrapper> ERRORWRAPPEROBJECTREF;
3192 #else
3193 typedef ErrorWrapper*     ERRORWRAPPEROBJECTREF;
3194 #endif
3195
3196
3197 //-------------------------------------------------------------
3198 // class CurrencyWrapper, Exposed class CurrencyWrapper
3199 // 
3200 // 
3201 //-------------------------------------------------------------
3202
3203 // Keep this in sync with code:MethodTableBuilder.CheckForSystemTypes where
3204 // alignment requirement of the managed System.Decimal structure is computed.
3205 #if !defined(ALIGN_ACCESS) && !defined(FEATURE_64BIT_ALIGNMENT)
3206 #include <pshpack4.h>
3207 #endif // !ALIGN_ACCESS && !FEATURE_64BIT_ALIGNMENT
3208
3209 class CurrencyWrapper : public Object
3210 {
3211 protected:
3212
3213     CurrencyWrapper(CurrencyWrapper &wrap) {LIMITED_METHOD_CONTRACT}; // dissalow copy construction.
3214     CurrencyWrapper() {LIMITED_METHOD_CONTRACT;}; // don't instantiate this class directly
3215     ~CurrencyWrapper() {LIMITED_METHOD_CONTRACT;};
3216
3217     DECIMAL m_WrappedObject;
3218
3219 public:
3220     DECIMAL GetWrappedObject()
3221     {
3222         LIMITED_METHOD_CONTRACT;
3223         return m_WrappedObject;
3224     }
3225
3226     void SetWrappedObject(DECIMAL WrappedObj)
3227     {
3228         LIMITED_METHOD_CONTRACT;
3229         m_WrappedObject = WrappedObj;
3230     }
3231 };
3232
3233 #if !defined(ALIGN_ACCESS) && !defined(FEATURE_64BIT_ALIGNMENT)
3234 #include <poppack.h>
3235 #endif // !ALIGN_ACCESS && !FEATURE_64BIT_ALIGNMENT
3236
3237 #ifdef USE_CHECKED_OBJECTREFS
3238 typedef REF<CurrencyWrapper> CURRENCYWRAPPEROBJECTREF;
3239 #else
3240 typedef CurrencyWrapper*     CURRENCYWRAPPEROBJECTREF;
3241 #endif
3242
3243 //-------------------------------------------------------------
3244 // class BStrWrapper, Exposed class BSTRWRAPPEROBJECTREF
3245 // 
3246 // 
3247 //-------------------------------------------------------------
3248 class BStrWrapper : public Object
3249 {
3250 protected:
3251
3252     BStrWrapper(BStrWrapper &wrap) {LIMITED_METHOD_CONTRACT}; // dissalow copy construction.
3253     BStrWrapper() {LIMITED_METHOD_CONTRACT}; // don't instantiate this class directly
3254     ~BStrWrapper() {LIMITED_METHOD_CONTRACT};
3255
3256     STRINGREF m_WrappedObject;
3257
3258 public:
3259     STRINGREF GetWrappedObject()
3260     {
3261         LIMITED_METHOD_CONTRACT;
3262         return m_WrappedObject;
3263     }
3264
3265     void SetWrappedObject(STRINGREF pWrappedObject)
3266     {
3267         LIMITED_METHOD_CONTRACT;
3268         m_WrappedObject = pWrappedObject;
3269     }
3270 };
3271
3272 #ifdef USE_CHECKED_OBJECTREFS
3273 typedef REF<BStrWrapper> BSTRWRAPPEROBJECTREF;
3274 #else
3275 typedef BStrWrapper*     BSTRWRAPPEROBJECTREF;
3276 #endif
3277
3278 #endif // FEATURE_COMINTEROP
3279
3280 class StringBufferObject;
3281 #ifdef USE_CHECKED_OBJECTREFS
3282 typedef REF<StringBufferObject> STRINGBUFFERREF;
3283 #else   // USE_CHECKED_OBJECTREFS
3284 typedef StringBufferObject * STRINGBUFFERREF;
3285 #endif  // USE_CHECKED_OBJECTREFS
3286
3287 //
3288 // StringBufferObject
3289 //
3290 // Note that the "copy on write" bit is buried within the implementation
3291 // of the object in order to make the implementation smaller.
3292 //
3293
3294
3295 class StringBufferObject : public Object
3296 {
3297     friend class MscorlibBinder;
3298
3299   private:
3300     CHARARRAYREF m_ChunkChars;
3301     StringBufferObject *m_ChunkPrevious;
3302     UINT32 m_ChunkLength;
3303     UINT32 m_ChunkOffset;
3304     INT32 m_MaxCapacity;
3305
3306     WCHAR* GetBuffer()
3307     {
3308         LIMITED_METHOD_CONTRACT;
3309         return (WCHAR *)m_ChunkChars->GetDirectPointerToNonObjectElements();
3310     }
3311         
3312     // This function assumes that requiredLength will be less 
3313     // than the max capacity of the StringBufferObject   
3314     DWORD GetAllocationLength(DWORD dwRequiredLength)
3315     {
3316         LIMITED_METHOD_CONTRACT;
3317         _ASSERTE((INT32)dwRequiredLength <= m_MaxCapacity);
3318         DWORD dwCurrentLength = GetArrayLength();
3319
3320         // round the current length to the nearest multiple of 2
3321         // that is >= the required length
3322         if(dwCurrentLength < dwRequiredLength)
3323         {
3324             dwCurrentLength = (dwRequiredLength + 1) & ~1;        
3325         }
3326         return dwCurrentLength;
3327     }
3328
3329   protected:
3330    StringBufferObject() { LIMITED_METHOD_CONTRACT; };
3331    ~StringBufferObject() { LIMITED_METHOD_CONTRACT; };
3332
3333   public:
3334     INT32 GetMaxCapacity()
3335     {
3336         return m_MaxCapacity;
3337     }
3338
3339     DWORD GetArrayLength() 
3340     {
3341         LIMITED_METHOD_CONTRACT;
3342         _ASSERTE(m_ChunkChars);
3343         return m_ChunkOffset + m_ChunkChars->GetNumComponents();
3344     }
3345
3346     // Given an ANSI string, use it to replace the StringBufferObject's internal buffer
3347     VOID ReplaceBufferWithAnsi(CHARARRAYREF *newArrayRef, __in CHAR *newChars, DWORD dwNewCapacity)
3348     {
3349 #ifndef DACCESS_COMPILE
3350         SetObjectReference((OBJECTREF *)&m_ChunkChars, (OBJECTREF)(*newArrayRef), GetAppDomain());
3351 #endif //!DACCESS_COMPILE
3352         WCHAR *thisChars = GetBuffer();
3353         // NOTE: This call to MultiByte also writes out the null terminator
3354         // which is currently part of the String representation.
3355         INT32 ncWritten = MultiByteToWideChar(CP_ACP,
3356                                               MB_PRECOMPOSED,
3357                                               newChars,
3358                                               -1,
3359                                               (LPWSTR)thisChars,
3360                                               dwNewCapacity+1);
3361
3362         if (ncWritten == 0)
3363         {
3364             // Normally, we'd throw an exception if the string couldn't be converted.
3365             // In this particular case, we paper over it instead. The reason is
3366             // that most likely reason a P/Invoke-called api returned a
3367             // poison string is that the api failed for some reason, and hence
3368             // exercised its right to leave the buffer in a poison state.
3369             // Because P/Invoke cannot discover if an api failed, it cannot
3370             // know to ignore the buffer on the out marshaling path.
3371             // Because normal P/Invoke procedure is for the caller to check error
3372             // codes manually, we don't want to throw an exception on him.
3373             // We certainly don't want to randomly throw or not throw based on the
3374             // nondeterministic contents of a buffer passed to a failing api.
3375             *thisChars = W('\0');
3376             ncWritten++;
3377         }
3378
3379         m_ChunkOffset = 0;
3380         m_ChunkLength = ncWritten-1;
3381         m_ChunkPrevious = NULL;
3382     }
3383
3384     // Given a Unicode string, use it to replace the StringBufferObject's internal buffer
3385     VOID ReplaceBuffer(CHARARRAYREF *newArrayRef, __in_ecount(dwNewCapacity) WCHAR *newChars, DWORD dwNewCapacity)
3386     {
3387         CONTRACTL
3388         {
3389             NOTHROW;
3390             GC_NOTRIGGER;
3391             SO_TOLERANT;
3392             MODE_COOPERATIVE;
3393         }
3394         CONTRACTL_END;
3395 #ifndef DACCESS_COMPILE
3396         SetObjectReference((OBJECTREF *)&m_ChunkChars, (OBJECTREF)(*newArrayRef), GetAppDomain());
3397 #endif //!DACCESS_COMPILE
3398         WCHAR *thisChars = GetBuffer();
3399         memcpyNoGCRefs(thisChars, newChars, sizeof(WCHAR)*dwNewCapacity);
3400         thisChars[dwNewCapacity] = W('\0');
3401         m_ChunkLength = dwNewCapacity;
3402         m_ChunkPrevious = NULL;
3403         m_ChunkOffset = 0; 
3404     }
3405
3406     static void ReplaceBuffer(STRINGBUFFERREF *thisRef, __in_ecount(newLength) WCHAR *newBuffer, INT32 newLength);
3407     static void ReplaceBufferAnsi(STRINGBUFFERREF *thisRef, __in_ecount(newCapacity) CHAR *newBuffer, INT32 newCapacity);    
3408     static INT32 LocalIndexOfString(__in_ecount(strLength) WCHAR *base, __in_ecount(patternLength) WCHAR *search, int strLength, int patternLength, int startPos);
3409 };
3410
3411 class SafeHandle : public Object
3412 {
3413     friend class MscorlibBinder;
3414
3415   private:
3416     // READ ME:
3417     //   Modifying the order or fields of this object may require
3418     //   other changes to the classlib class definition of this
3419     //   object or special handling when loading this system class.
3420 #ifdef _DEBUG
3421     STRINGREF m_debugStackTrace;   // Where we allocated this SafeHandle
3422 #endif
3423     Volatile<LPVOID> m_handle;
3424     Volatile<INT32> m_state;        // Combined ref count and closed/disposed state (for atomicity)
3425     Volatile<CLR_BOOL> m_ownsHandle;
3426     Volatile<CLR_BOOL> m_fullyInitialized;  // Did constructor finish?
3427
3428     // Describe the bits in the m_state field above.
3429     enum StateBits
3430     {
3431         SH_State_Closed     = 0x00000001,
3432         SH_State_Disposed   = 0x00000002,
3433         SH_State_RefCount   = 0xfffffffc,
3434         SH_RefCountOne      = 4,            // Amount to increment state field to yield a ref count increment of 1
3435     };
3436
3437     static WORD s_IsInvalidHandleMethodSlot;
3438     static WORD s_ReleaseHandleMethodSlot;
3439
3440     static void RunReleaseMethod(SafeHandle* psh);
3441     BOOL IsFullyInitialized() const { LIMITED_METHOD_CONTRACT; return m_fullyInitialized; }
3442
3443   public:
3444     static void Init();
3445
3446     // To use the SafeHandle from native, look at the SafeHandleHolder, which
3447     // will do the AddRef & Release for you.
3448     LPVOID GetHandle() const { 
3449         LIMITED_METHOD_CONTRACT;
3450         _ASSERTE(((unsigned int) m_state) >= SH_RefCountOne);
3451         return m_handle;
3452     }
3453
3454     BOOL OwnsHandle() const
3455     {
3456         LIMITED_METHOD_CONTRACT;
3457         return m_ownsHandle;
3458     }
3459
3460     static size_t GetHandleOffset() { LIMITED_METHOD_CONTRACT; return offsetof(SafeHandle, m_handle); }
3461
3462     void AddRef();
3463     void Release(bool fDispose = false);
3464     void Dispose();
3465     void SetHandle(LPVOID handle);
3466
3467     static FCDECL1(void, DisposeNative, SafeHandle* refThisUNSAFE);
3468     static FCDECL1(void, Finalize, SafeHandle* refThisUNSAFE);
3469     static FCDECL1(void, SetHandleAsInvalid, SafeHandle* refThisUNSAFE);
3470     static FCDECL2(void, DangerousAddRef, SafeHandle* refThisUNSAFE, CLR_BOOL *pfSuccess);
3471     static FCDECL1(void, DangerousRelease, SafeHandle* refThisUNSAFE);
3472 };
3473
3474 // SAFEHANDLEREF defined above because CompressedStackObject needs it
3475
3476 void AcquireSafeHandle(SAFEHANDLEREF* s);
3477 void ReleaseSafeHandle(SAFEHANDLEREF* s);
3478
3479 typedef Holder<SAFEHANDLEREF*, AcquireSafeHandle, ReleaseSafeHandle> SafeHandleHolder;
3480
3481 class CriticalHandle : public Object
3482 {
3483     friend class MscorlibBinder;
3484
3485   private:
3486     // READ ME:
3487     //   Modifying the order or fields of this object may require
3488     //   other changes to the classlib class definition of this
3489     //   object or special handling when loading this system class.
3490 #ifdef _DEBUG
3491     STRINGREF m_debugStackTrace;   // Where we allocated this CriticalHandle
3492 #endif
3493     Volatile<LPVOID> m_handle;
3494     Volatile<CLR_BOOL> m_isClosed;
3495
3496   public:
3497     LPVOID GetHandle() const { LIMITED_METHOD_CONTRACT; return m_handle; }
3498     static size_t GetHandleOffset() { LIMITED_METHOD_CONTRACT; return offsetof(CriticalHandle, m_handle); }
3499
3500     void SetHandle(LPVOID handle) { LIMITED_METHOD_CONTRACT; m_handle = handle; }
3501
3502     static FCDECL1(void, FireCustomerDebugProbe, CriticalHandle* refThisUNSAFE);
3503 };
3504
3505
3506 class ReflectClassBaseObject;
3507
3508 class SafeBuffer : SafeHandle
3509 {
3510   private:
3511     size_t m_numBytes;
3512
3513   public:
3514     static FCDECL1(UINT, SizeOfType, ReflectClassBaseObject* typeUNSAFE);
3515     static FCDECL1(UINT, AlignedSizeOfType, ReflectClassBaseObject* typeUNSAFE);
3516     static FCDECL3(void, PtrToStructure, BYTE* ptr, FC_TypedByRef structure, UINT32 sizeofT);
3517     static FCDECL3(void, StructureToPtr, FC_TypedByRef structure, BYTE* ptr, UINT32 sizeofT);
3518 };
3519
3520 #ifdef USE_CHECKED_OBJECTREFS
3521 typedef REF<CriticalHandle> CRITICALHANDLE;
3522 typedef REF<CriticalHandle> CRITICALHANDLEREF;
3523 #else // USE_CHECKED_OBJECTREFS
3524 typedef CriticalHandle * CRITICALHANDLE;
3525 typedef CriticalHandle * CRITICALHANDLEREF;
3526 #endif // USE_CHECKED_OBJECTREFS
3527
3528 // WaitHandleBase
3529 // Base class for WaitHandle 
3530 class WaitHandleBase :public MarshalByRefObjectBaseObject
3531 {
3532     friend class WaitHandleNative;
3533     friend class MscorlibBinder;
3534
3535 public:
3536     __inline LPVOID GetWaitHandle() {LIMITED_METHOD_CONTRACT; return m_handle;}
3537     __inline SAFEHANDLEREF GetSafeHandle() {LIMITED_METHOD_CONTRACT; return m_safeHandle;}
3538
3539 private:
3540     SAFEHANDLEREF   m_safeHandle;
3541     LPVOID          m_handle;
3542     CLR_BOOL        m_hasThreadAffinity;
3543 };
3544
3545 #ifdef USE_CHECKED_OBJECTREFS
3546 typedef REF<WaitHandleBase> WAITHANDLEREF;
3547 #else // USE_CHECKED_OBJECTREFS
3548 typedef WaitHandleBase* WAITHANDLEREF;
3549 #endif // USE_CHECKED_OBJECTREFS
3550
3551 // This class corresponds to FileStreamAsyncResult on the managed side.
3552 class AsyncResultBase :public Object
3553 {
3554     friend class MscorlibBinder;
3555
3556 public: 
3557     WAITHANDLEREF GetWaitHandle() { LIMITED_METHOD_CONTRACT; return _waitHandle;}
3558     void SetErrorCode(int errcode) { LIMITED_METHOD_CONTRACT; _errorCode = errcode;}
3559     void SetNumBytes(int numBytes) { LIMITED_METHOD_CONTRACT; _numBytes = numBytes;}
3560     void SetIsComplete() { LIMITED_METHOD_CONTRACT; _isComplete = TRUE; }
3561     void SetCompletedAsynchronously() { LIMITED_METHOD_CONTRACT; _completedSynchronously = FALSE; }
3562
3563     // README:
3564     // If you modify the order of these fields, make sure to update the definition in 
3565     // BCL for this object.
3566 private:
3567     OBJECTREF _userCallback;
3568     OBJECTREF _userStateObject;
3569
3570     WAITHANDLEREF _waitHandle;
3571     SAFEHANDLEREF _fileHandle;     // For cancellation.
3572     LPOVERLAPPED  _overlapped;
3573     int _EndXxxCalled;             // Whether we've called EndXxx already.
3574     int _numBytes;                 // number of bytes read OR written
3575     int _errorCode;
3576     int _numBufferedBytes;
3577
3578     CLR_BOOL _isWrite;                 // Whether this is a read or a write
3579     CLR_BOOL _isComplete;
3580     CLR_BOOL _completedSynchronously;  // Which thread called callback
3581 };
3582
3583 #ifdef USE_CHECKED_OBJECTREFS
3584 typedef REF<AsyncResultBase> ASYNCRESULTREF;
3585 #else // USE_CHECKED_OBJECTREFS
3586 typedef AsyncResultBase* ASYNCRESULTREF;
3587 #endif // USE_CHECKED_OBJECTREFS
3588
3589 // This class corresponds to System.MulticastDelegate on the managed side.
3590 class DelegateObject : public Object
3591 {
3592     friend class CheckAsmOffsets;
3593     friend class MscorlibBinder;
3594
3595 public:
3596     BOOL IsWrapperDelegate() { LIMITED_METHOD_CONTRACT; return _methodPtrAux == NULL; }
3597     
3598     OBJECTREF GetTarget() { LIMITED_METHOD_CONTRACT; return _target; }
3599     void SetTarget(OBJECTREF target) { WRAPPER_NO_CONTRACT; SetObjectReference(&_target, target, GetAppDomain()); }
3600     static int GetOffsetOfTarget() { LIMITED_METHOD_CONTRACT; return offsetof(DelegateObject, _target); }
3601
3602     PCODE GetMethodPtr() { LIMITED_METHOD_CONTRACT; return _methodPtr; }
3603     void SetMethodPtr(PCODE methodPtr) { LIMITED_METHOD_CONTRACT; _methodPtr = methodPtr; }
3604     static int GetOffsetOfMethodPtr() { LIMITED_METHOD_CONTRACT; return offsetof(DelegateObject, _methodPtr); }
3605
3606     PCODE GetMethodPtrAux() { LIMITED_METHOD_CONTRACT; return _methodPtrAux; }
3607     void SetMethodPtrAux(PCODE methodPtrAux) { LIMITED_METHOD_CONTRACT; _methodPtrAux = methodPtrAux; }
3608     static int GetOffsetOfMethodPtrAux() { LIMITED_METHOD_CONTRACT; return offsetof(DelegateObject, _methodPtrAux); }
3609
3610     OBJECTREF GetInvocationList() { LIMITED_METHOD_CONTRACT; return _invocationList; }
3611     void SetInvocationList(OBJECTREF invocationList) { WRAPPER_NO_CONTRACT; SetObjectReference(&_invocationList, invocationList, GetAppDomain()); }
3612     static int GetOffsetOfInvocationList() { LIMITED_METHOD_CONTRACT; return offsetof(DelegateObject, _invocationList); }
3613
3614     INT_PTR GetInvocationCount() { LIMITED_METHOD_CONTRACT; return _invocationCount; }
3615     void SetInvocationCount(INT_PTR invocationCount) { LIMITED_METHOD_CONTRACT; _invocationCount = invocationCount; }
3616     static int GetOffsetOfInvocationCount() { LIMITED_METHOD_CONTRACT; return offsetof(DelegateObject, _invocationCount); }
3617
3618     void SetMethodBase(OBJECTREF newMethodBase) { LIMITED_METHOD_CONTRACT; SetObjectReference((OBJECTREF*)&_methodBase, newMethodBase, GetAppDomain()); }
3619
3620     // README:
3621     // If you modify the order of these fields, make sure to update the definition in 
3622     // BCL for this object.
3623 private:
3624     // System.Delegate
3625     OBJECTREF   _target;
3626     OBJECTREF   _methodBase;
3627     PCODE       _methodPtr;
3628     PCODE       _methodPtrAux;
3629     // System.MulticastDelegate
3630     OBJECTREF   _invocationList;
3631     INT_PTR     _invocationCount;
3632 };
3633
3634 #ifdef USE_CHECKED_OBJECTREFS
3635 typedef REF<DelegateObject> DELEGATEREF;
3636 #else // USE_CHECKED_OBJECTREFS
3637 typedef DelegateObject* DELEGATEREF;
3638 #endif // USE_CHECKED_OBJECTREFS
3639
3640
3641 struct StackTraceElement;
3642 class ClrDataAccess;
3643
3644
3645 typedef DPTR(StackTraceElement) PTR_StackTraceElement;
3646
3647 class StackTraceArray
3648 {
3649     struct ArrayHeader
3650     {
3651         size_t m_size;
3652         Thread * m_thread;
3653     };
3654
3655     typedef DPTR(ArrayHeader) PTR_ArrayHeader;
3656
3657 public:
3658     StackTraceArray()
3659         : m_array(static_cast<I1Array *>(NULL))
3660     {
3661         WRAPPER_NO_CONTRACT;
3662     }
3663     
3664     StackTraceArray(I1ARRAYREF array)
3665         : m_array(array)
3666     {
3667         LIMITED_METHOD_CONTRACT;
3668     }
3669
3670     void Swap(StackTraceArray & rhs)
3671     {
3672         CONTRACTL
3673         {
3674             NOTHROW;
3675             GC_NOTRIGGER;
3676             SO_TOLERANT;
3677             MODE_COOPERATIVE;
3678         }
3679         CONTRACTL_END;
3680         SUPPORTS_DAC;
3681         I1ARRAYREF t = m_array;
3682         m_array = rhs.m_array;
3683         rhs.m_array = t;
3684     }
3685     
3686     size_t Size() const
3687     {
3688         WRAPPER_NO_CONTRACT;
3689         if (!m_array)
3690             return 0;
3691         else
3692             return GetSize();
3693     }
3694     
3695     StackTraceElement const & operator[](size_t index) const;
3696     StackTraceElement & operator[](size_t index);
3697
3698     void Append(StackTraceElement const * begin, StackTraceElement const * end);
3699     void AppendSkipLast(StackTraceElement const * begin, StackTraceElement const * end);
3700
3701     I1ARRAYREF Get() const
3702     {
3703         LIMITED_METHOD_DAC_CONTRACT;
3704         return m_array;
3705     }
3706
3707     // Deep copies the array
3708     void CopyFrom(StackTraceArray const & src);
3709     
3710 private:
3711     StackTraceArray(StackTraceArray const & rhs);
3712
3713     StackTraceArray & operator=(StackTraceArray const & rhs)
3714     {
3715         WRAPPER_NO_CONTRACT;
3716         StackTraceArray copy(rhs);
3717         this->Swap(copy);
3718         return *this;
3719     }
3720
3721     void Grow(size_t size);
3722     void EnsureThreadAffinity();
3723     void CheckState() const;
3724
3725     size_t Capacity() const
3726     {
3727         WRAPPER_NO_CONTRACT;
3728         assert(!!m_array);
3729
3730         return m_array->GetNumComponents();
3731     }
3732     
3733     size_t GetSize() const
3734     {
3735         WRAPPER_NO_CONTRACT;
3736         return GetHeader()->m_size;
3737     }
3738
3739     void SetSize(size_t size)
3740     {
3741         WRAPPER_NO_CONTRACT;
3742         GetHeader()->m_size = size;
3743     }
3744
3745     Thread * GetObjectThread() const
3746     {
3747         WRAPPER_NO_CONTRACT;
3748         return GetHeader()->m_thread;
3749     }
3750
3751     void SetObjectThread()
3752     {
3753         WRAPPER_NO_CONTRACT;
3754         GetHeader()->m_thread = GetThread();
3755     }
3756
3757     StackTraceElement const * GetData() const
3758     {
3759         WRAPPER_NO_CONTRACT;
3760         SUPPORTS_DAC;
3761         return dac_cast<PTR_StackTraceElement>(GetRaw() + sizeof(ArrayHeader));
3762     }
3763
3764     PTR_StackTraceElement GetData()
3765     {
3766         WRAPPER_NO_CONTRACT;
3767         SUPPORTS_DAC;
3768         return dac_cast<PTR_StackTraceElement>(GetRaw() + sizeof(ArrayHeader));
3769     }
3770
3771     I1 const * GetRaw() const
3772     {
3773         WRAPPER_NO_CONTRACT;
3774         assert(!!m_array);
3775
3776         return const_cast<I1ARRAYREF &>(m_array)->GetDirectPointerToNonObjectElements();
3777     }
3778
3779     PTR_I1 GetRaw()
3780     {
3781         WRAPPER_NO_CONTRACT;
3782         SUPPORTS_DAC;
3783         assert(!!m_array);
3784
3785         return dac_cast<PTR_I1>(m_array->GetDirectPointerToNonObjectElements());
3786     }
3787
3788     ArrayHeader const * GetHeader() const
3789     {
3790         WRAPPER_NO_CONTRACT;
3791         SUPPORTS_DAC;
3792         return dac_cast<PTR_ArrayHeader>(GetRaw());
3793     }
3794
3795     PTR_ArrayHeader GetHeader()
3796     {
3797         WRAPPER_NO_CONTRACT;
3798         SUPPORTS_DAC;
3799         return dac_cast<PTR_ArrayHeader>(GetRaw());
3800     }
3801
3802     void SetArray(I1ARRAYREF const & arr)
3803     {
3804         LIMITED_METHOD_CONTRACT;
3805         m_array = arr;
3806     }
3807
3808 private:
3809     // put only things here that can be protected with GCPROTECT
3810     I1ARRAYREF m_array;
3811 };
3812
3813 #ifdef FEATURE_COLLECTIBLE_TYPES
3814
3815 class LoaderAllocatorScoutObject : public Object
3816 {
3817     friend class MscorlibBinder;
3818     friend class LoaderAllocatorObject;
3819
3820 protected:
3821     LoaderAllocator * m_nativeLoaderAllocator;
3822 };
3823
3824 #ifdef USE_CHECKED_OBJECTREFS
3825 typedef REF<LoaderAllocatorScoutObject> LOADERALLOCATORSCOUTREF;
3826 #else // USE_CHECKED_OBJECTREFS
3827 typedef LoaderAllocatorScoutObject* LOADERALLOCATORSCOUTREF;
3828 #endif // USE_CHECKED_OBJECTREFS
3829
3830 class LoaderAllocatorObject : public Object
3831 {
3832     friend class MscorlibBinder;
3833
3834 public:
3835     PTRARRAYREF GetHandleTable()
3836     {
3837         LIMITED_METHOD_DAC_CONTRACT;
3838         return (PTRARRAYREF)m_pSlots;
3839     }
3840
3841     void SetHandleTable(PTRARRAYREF handleTable)
3842     {
3843         LIMITED_METHOD_CONTRACT;
3844         SetObjectReferenceUnchecked(&m_pSlots, (OBJECTREF)handleTable);
3845     }
3846
3847     INT32 GetSlotsUsed()
3848     {
3849         LIMITED_METHOD_CONTRACT;
3850         return m_slotsUsed;
3851     }
3852
3853     void SetSlotsUsed(INT32 newSlotsUsed)
3854     {
3855         LIMITED_METHOD_CONTRACT;
3856         m_slotsUsed = newSlotsUsed;
3857     }
3858
3859     void SetNativeLoaderAllocator(LoaderAllocator * pLoaderAllocator)
3860     {
3861         LIMITED_METHOD_CONTRACT;
3862         m_pLoaderAllocatorScout->m_nativeLoaderAllocator = pLoaderAllocator;
3863     }
3864
3865     // README:
3866     // If you modify the order of these fields, make sure to update the definition in 
3867     // BCL for this object.
3868 protected:
3869     LOADERALLOCATORSCOUTREF m_pLoaderAllocatorScout;
3870     OBJECTREF   m_pSlots;
3871     INT32       m_slotsUsed;
3872     OBJECTREF   m_methodInstantiationsTable;
3873 };
3874
3875 #ifdef USE_CHECKED_OBJECTREFS
3876 typedef REF<LoaderAllocatorObject> LOADERALLOCATORREF;
3877 #else // USE_CHECKED_OBJECTREFS
3878 typedef DPTR(LoaderAllocatorObject) PTR_LoaderAllocatorObject;
3879 typedef PTR_LoaderAllocatorObject LOADERALLOCATORREF;
3880 #endif // USE_CHECKED_OBJECTREFS
3881
3882 #endif // FEATURE_COLLECTIBLE_TYPES
3883
3884 #if !defined(DACCESS_COMPILE)
3885 // Define the lock used to access stacktrace from an exception object
3886 EXTERN_C SpinLock g_StackTraceArrayLock;
3887 #endif // !defined(DACCESS_COMPILE)
3888
3889 // This class corresponds to Exception on the managed side.
3890 typedef DPTR(class ExceptionObject) PTR_ExceptionObject;
3891 #include "pshpack4.h"
3892 class ExceptionObject : public Object
3893 {
3894     friend class MscorlibBinder;
3895
3896 public:
3897     void SetHResult(HRESULT hr)
3898     {
3899         LIMITED_METHOD_CONTRACT;
3900         _HResult = hr;
3901     }
3902
3903     HRESULT GetHResult()
3904     {
3905         LIMITED_METHOD_CONTRACT;
3906         return _HResult;
3907     }
3908
3909     void SetXCode(DWORD code)
3910     {
3911         LIMITED_METHOD_CONTRACT;
3912         _xcode = code;
3913     }
3914
3915     DWORD GetXCode()
3916     {
3917         LIMITED_METHOD_CONTRACT;
3918         return _xcode;
3919     }
3920
3921     void SetXPtrs(void* xptrs)
3922     {
3923         LIMITED_METHOD_CONTRACT;
3924         _xptrs = xptrs;
3925     }
3926
3927     void* GetXPtrs()
3928     {
3929         LIMITED_METHOD_CONTRACT;
3930         return _xptrs;
3931     }
3932
3933     void SetStackTrace(StackTraceArray const & stackTrace, PTRARRAYREF dynamicMethodArray);
3934     void SetNullStackTrace();
3935
3936     void GetStackTrace(StackTraceArray & stackTrace, PTRARRAYREF * outDynamicMethodArray = NULL) const;
3937
3938 #ifdef DACCESS_COMPILE
3939     I1ARRAYREF GetStackTraceArrayObject() const
3940     {
3941         LIMITED_METHOD_DAC_CONTRACT;
3942         return _stackTrace;
3943     }
3944 #endif // DACCESS_COMPILE
3945
3946     void SetInnerException(OBJECTREF innerException)
3947     {
3948         WRAPPER_NO_CONTRACT;
3949         SetObjectReference((OBJECTREF*)&_innerException, (OBJECTREF)innerException, GetAppDomain());
3950     }
3951
3952     OBJECTREF GetInnerException()
3953     {
3954         LIMITED_METHOD_DAC_CONTRACT;
3955         return _innerException;
3956     }
3957
3958     // Returns the innermost exception object - equivalent of the
3959     // managed System.Exception.GetBaseException method.
3960     OBJECTREF GetBaseException()
3961     {
3962         LIMITED_METHOD_CONTRACT;
3963
3964         // Loop and get the innermost exception object
3965         OBJECTREF oInnerMostException = NULL;
3966         OBJECTREF oCurrent = NULL;
3967
3968         oCurrent = _innerException;
3969         while(oCurrent != NULL)
3970         {
3971             oInnerMostException = oCurrent;
3972             oCurrent = ((ExceptionObject*)(Object *)OBJECTREFToObject(oCurrent))->GetInnerException();
3973         }
3974
3975         // return the innermost exception
3976         return oInnerMostException;
3977     }
3978
3979     void SetMessage(STRINGREF message)
3980     {
3981         WRAPPER_NO_CONTRACT;
3982         SetObjectReference((OBJECTREF*)&_message, (OBJECTREF)message, GetAppDomain());
3983     }
3984
3985     STRINGREF GetMessage()
3986     {
3987         LIMITED_METHOD_DAC_CONTRACT;
3988         return _message;
3989     }
3990
3991     void SetStackTraceString(STRINGREF stackTraceString)
3992     {
3993         WRAPPER_NO_CONTRACT;
3994         SetObjectReference((OBJECTREF*)&_stackTraceString, (OBJECTREF)stackTraceString, GetAppDomain());
3995     }
3996
3997     STRINGREF GetStackTraceString()
3998     {
3999         LIMITED_METHOD_DAC_CONTRACT;
4000         return _stackTraceString;
4001     }
4002
4003     STRINGREF GetRemoteStackTraceString()
4004     {
4005         LIMITED_METHOD_DAC_CONTRACT;
4006         return _remoteStackTraceString;
4007     }
4008
4009     void SetHelpURL(STRINGREF helpURL)
4010     {
4011         WRAPPER_NO_CONTRACT;
4012         SetObjectReference((OBJECTREF*)&_helpURL, (OBJECTREF)helpURL, GetAppDomain());
4013     }
4014
4015     void SetSource(STRINGREF source)
4016     {
4017         WRAPPER_NO_CONTRACT;
4018         SetObjectReference((OBJECTREF*)&_source, (OBJECTREF)source, GetAppDomain());
4019     }
4020
4021     void ClearStackTraceForThrow()
4022     {
4023         WRAPPER_NO_CONTRACT;
4024         SetObjectReferenceUnchecked((OBJECTREF*)&_remoteStackTraceString, NULL);
4025         SetObjectReferenceUnchecked((OBJECTREF*)&_stackTrace, NULL);
4026         SetObjectReferenceUnchecked((OBJECTREF*)&_stackTraceString, NULL);
4027     }
4028
4029     void ClearStackTracePreservingRemoteStackTrace()
4030     {
4031         WRAPPER_NO_CONTRACT;
4032         SetObjectReferenceUnchecked((OBJECTREF*)&_stackTrace, NULL);
4033         SetObjectReferenceUnchecked((OBJECTREF*)&_stackTraceString, NULL);
4034     }
4035
4036     // This method will set the reference to the array
4037     // containing the watson bucket information (in byte[] form).
4038     void SetWatsonBucketReference(OBJECTREF oWatsonBucketArray)
4039     {
4040         WRAPPER_NO_CONTRACT;
4041         SetObjectReference((OBJECTREF*)&_watsonBuckets, (OBJECTREF)oWatsonBucketArray, GetAppDomain());
4042     }
4043
4044     // This method will return the reference to the array
4045     // containing the watson buckets
4046     U1ARRAYREF GetWatsonBucketReference()
4047     {
4048         LIMITED_METHOD_CONTRACT;
4049         return _watsonBuckets;
4050     }
4051
4052     // This method will return a BOOL to indicate if the 
4053     // watson buckets are present or not.
4054     BOOL AreWatsonBucketsPresent()
4055     {
4056         LIMITED_METHOD_CONTRACT;
4057         return (_watsonBuckets != NULL)?TRUE:FALSE;
4058     }
4059
4060     // This method will save the IP to be used for watson bucketing.
4061     void SetIPForWatsonBuckets(UINT_PTR ip)
4062     {
4063         LIMITED_METHOD_CONTRACT;
4064
4065         _ipForWatsonBuckets = ip;
4066     }
4067
4068     // This method will return a BOOL to indicate if Watson bucketing IP
4069     // is present (or not).
4070     BOOL IsIPForWatsonBucketsPresent()
4071     {
4072         LIMITED_METHOD_CONTRACT;
4073
4074         return (_ipForWatsonBuckets != NULL);
4075     }
4076
4077     // This method returns the IP for Watson Buckets.
4078     UINT_PTR GetIPForWatsonBuckets()
4079     {
4080         LIMITED_METHOD_CONTRACT;
4081
4082         return _ipForWatsonBuckets;
4083     }
4084
4085     // README:
4086     // If you modify the order of these fields, make sure to update the definition in 
4087     // BCL for this object.
4088 private:
4089     STRINGREF   _className;  //Needed for serialization.
4090     OBJECTREF   _exceptionMethod;  //Needed for serialization.
4091     STRINGREF   _exceptionMethodString; //Needed for serialization.
4092     STRINGREF   _message;
4093     OBJECTREF   _data;
4094     OBJECTREF   _innerException;
4095     STRINGREF   _helpURL;
4096     I1ARRAYREF  _stackTrace;
4097     U1ARRAYREF  _watsonBuckets;
4098     STRINGREF   _stackTraceString; //Needed for serialization.
4099     STRINGREF   _remoteStackTraceString;
4100     PTRARRAYREF _dynamicMethods;
4101     STRINGREF   _source;         // Mainly used by VB.
4102 #ifdef FEATURE_SERIALIZATION
4103     OBJECTREF   _safeSerializationManager;
4104 #endif // FEATURE_SERIALIZATION
4105     IN_WIN64(void* _xptrs;)
4106     IN_WIN64(UINT_PTR    _ipForWatsonBuckets;) // Contains the IP of exception for watson bucketing
4107     INT32       _remoteStackIndex;
4108     INT32       _HResult;
4109     IN_WIN32(void* _xptrs;)
4110     INT32       _xcode;
4111     IN_WIN32(UINT_PTR    _ipForWatsonBuckets;) // Contains the IP of exception for watson bucketing
4112 };
4113
4114 // Defined in Contracts.cs
4115 enum ContractFailureKind
4116 {
4117     CONTRACT_FAILURE_PRECONDITION = 0,
4118     CONTRACT_FAILURE_POSTCONDITION,
4119     CONTRACT_FAILURE_POSTCONDITION_ON_EXCEPTION,
4120     CONTRACT_FAILURE_INVARIANT,
4121     CONTRACT_FAILURE_ASSERT,
4122     CONTRACT_FAILURE_ASSUME,
4123 };
4124
4125 typedef DPTR(class ContractExceptionObject) PTR_ContractExceptionObject;
4126 class ContractExceptionObject : public ExceptionObject
4127 {
4128     friend class MscorlibBinder;
4129
4130 public:
4131     ContractFailureKind GetContractFailureKind()
4132     {
4133         LIMITED_METHOD_CONTRACT;
4134
4135         return static_cast<ContractFailureKind>(_Kind);
4136     }
4137
4138 private:
4139     // keep these in sync with ndp/clr/src/bcl/system/diagnostics/contracts/contractsbcl.cs
4140     IN_WIN64(INT32 _Kind;)
4141     STRINGREF _UserMessage;
4142     STRINGREF _Condition;
4143     IN_WIN32(INT32 _Kind;)
4144 };
4145 #include "poppack.h"
4146
4147 #ifdef USE_CHECKED_OBJECTREFS
4148 typedef REF<ContractExceptionObject> CONTRACTEXCEPTIONREF;
4149 #else // USE_CHECKED_OBJECTREFS
4150 typedef PTR_ContractExceptionObject CONTRACTEXCEPTIONREF;
4151 #endif // USE_CHECKED_OBJECTREFS
4152
4153 class NumberFormatInfo: public Object
4154 {
4155 public:
4156     // C++ data members                 // Corresponding data member in NumberFormatInfo.cs
4157                                         // Also update mscorlib.h when you add/remove fields
4158
4159     I4ARRAYREF cNumberGroup;        // numberGroupSize
4160     I4ARRAYREF cCurrencyGroup;      // currencyGroupSize
4161     I4ARRAYREF cPercentGroup;       // percentGroupSize
4162     
4163     STRINGREF sPositive;            // positiveSign
4164     STRINGREF sNegative;            // negativeSign
4165     STRINGREF sNumberDecimal;       // numberDecimalSeparator
4166     STRINGREF sNumberGroup;         // numberGroupSeparator
4167     STRINGREF sCurrencyGroup;       // currencyDecimalSeparator
4168     STRINGREF sCurrencyDecimal;     // currencyGroupSeparator
4169     STRINGREF sCurrency;            // currencySymbol
4170 #ifndef FEATURE_COREFX_GLOBALIZATION
4171     STRINGREF sAnsiCurrency;        // ansiCurrencySymbol
4172 #endif
4173     STRINGREF sNaN;                 // nanSymbol
4174     STRINGREF sPositiveInfinity;    // positiveInfinitySymbol
4175     STRINGREF sNegativeInfinity;    // negativeInfinitySymbol
4176     STRINGREF sPercentDecimal;      // percentDecimalSeparator
4177     STRINGREF sPercentGroup;        // percentGroupSeparator
4178     STRINGREF sPercent;             // percentSymbol
4179     STRINGREF sPerMille;            // perMilleSymbol
4180
4181     PTRARRAYREF sNativeDigits;      // nativeDigits (a string array)
4182
4183 #ifndef FEATURE_COREFX_GLOBALIZATION    
4184     INT32 iDataItem;                // Index into the CultureInfo Table.  Only used from managed code.
4185 #endif
4186     INT32 cNumberDecimals;          // numberDecimalDigits
4187     INT32 cCurrencyDecimals;        // currencyDecimalDigits
4188     INT32 cPosCurrencyFormat;       // positiveCurrencyFormat
4189     INT32 cNegCurrencyFormat;       // negativeCurrencyFormat
4190     INT32 cNegativeNumberFormat;    // negativeNumberFormat
4191     INT32 cPositivePercentFormat;   // positivePercentFormat
4192     INT32 cNegativePercentFormat;   // negativePercentFormat
4193     INT32 cPercentDecimals;         // percentDecimalDigits
4194     INT32 iDigitSubstitution;       // digitSubstitution
4195
4196     CLR_BOOL bIsReadOnly;              // Is this NumberFormatInfo ReadOnly?
4197 #ifndef FEATURE_COREFX_GLOBALIZATION
4198     CLR_BOOL bUseUserOverride;         // Flag to use user override. Only used from managed code.
4199 #endif
4200     CLR_BOOL bIsInvariant;             // Is this the NumberFormatInfo for the Invariant Culture?
4201 #ifndef FEATURE_COREFX_GLOBALIZATION
4202     CLR_BOOL bvalidForParseAsNumber;   // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
4203     CLR_BOOL bvalidForParseAsCurrency; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
4204 #endif
4205 };
4206
4207 typedef NumberFormatInfo * NUMFMTREF;
4208
4209 //===============================================================================
4210 // #NullableFeature
4211 // #NullableArchitecture
4212 // 
4213 // In a nutshell it is counterintuitive to have a boxed Nullable<T>, since a boxed
4214 // object already has a representation for null (the null pointer), and having 
4215 // multiple representations for the 'not present' value just causes grief.  Thus the
4216 // feature is build make Nullable<T> box to a boxed<T> (not boxed<Nullable<T>).
4217 //
4218 // We want to do this in a way that does not impact the perf of the runtime in the 
4219 // non-nullable case.  
4220 //
4221 // To do this we need to 
4222 //     * Modify the boxing helper code:JIT_Box (we don't need a special one because
4223 //           the JIT inlines the common case, so this only gets call in uncommon cases)
4224 //     * Make a new helper for the Unbox case (see code:JIT_Unbox_Nullable)
4225 //     * Plumb the JIT to ask for what kind of Boxing helper is needed 
4226 //          (see code:CEEInfo.getBoxHelper, code:CEEInfo.getUnBoxHelper
4227 //     * change all the places in the CLR where we box or unbox by hand, and force
4228 //          them to use code:MethodTable.Box, and code:MethodTable.Unbox which in 
4229 //          turn call code:Nullable.Box and code:Nullable.UnBox, most of these 
4230 //          are in reflection, and remoting (passing and returning value types).
4231 //
4232 // #NullableVerification
4233 //
4234 // Sadly, the IL Verifier also needs to know about this change.  Basically the 'box'
4235 // instruction returns a boxed(T) (not a boxed(Nullable<T>)) for the purposes of 
4236 // verfication.  The JIT finds out what box returns by calling back to the EE with
4237 // the code:CEEInfo.getTypeForBox API.  
4238 //
4239 // #NullableDebugging 
4240 //
4241 // Sadly, because the debugger also does its own boxing 'by hand' for expression 
4242 // evaluation inside visual studio, it measn that debuggers also need to be aware
4243 // of the fact that Nullable<T> boxes to a boxed<T>.  It is the responcibility of
4244 // debuggers to follow this convention (which is why this is sad). 
4245 // 
4246
4247 //===============================================================================
4248 // Nullable represents the managed generic value type Nullable<T> 
4249 //
4250 // The runtime has special logic for this value class.  When it is boxed
4251 // it becomes either null or a boxed T.   Similarly a boxed T can be unboxed
4252 // either as a T (as normal), or as a Nullable<T>
4253 //
4254 // See code:Nullable#NullableArchitecture for more. 
4255 //
4256 class Nullable {
4257     Nullable();   // This is purposefully undefined.  Do not make instances
4258                   // of this class.  
4259 public:
4260     static void CheckFieldOffsets(TypeHandle nullableType);
4261     static BOOL IsNullableType(TypeHandle nullableType);
4262     static BOOL IsNullableForType(TypeHandle nullableType, MethodTable* paramMT);
4263     static BOOL IsNullableForTypeNoGC(TypeHandle nullableType, MethodTable* paramMT);
4264
4265     static OBJECTREF Box(void* src, MethodTable* nullable);
4266     static BOOL UnBox(void* dest, OBJECTREF boxedVal, MethodTable* destMT);
4267     static BOOL UnBoxNoGC(void* dest, OBJECTREF boxedVal, MethodTable* destMT);
4268     static BOOL UnBoxIntoArgNoGC(ArgDestination *argDest, OBJECTREF boxedVal, MethodTable* destMT);
4269     static void UnBoxNoCheck(void* dest, OBJECTREF boxedVal, MethodTable* destMT);
4270     static OBJECTREF BoxedNullableNull(TypeHandle nullableType) { return 0; }
4271
4272     // if 'Obj' is a true boxed nullable, return the form we want (either null or a boxed T)
4273     static OBJECTREF NormalizeBox(OBJECTREF obj);
4274
4275     static inline CLR_BOOL HasValue(void *src, MethodTable *nullableMT)
4276     {
4277         Nullable *nullable = (Nullable *)src;
4278         return *(nullable->HasValueAddr(nullableMT));
4279     }
4280
4281     static inline void *Value(void *src, MethodTable *nullableMT)
4282     {
4283         Nullable *nullable = (Nullable *)src;
4284         return nullable->ValueAddr(nullableMT);        
4285     }
4286     
4287 private:
4288     static BOOL IsNullableForTypeHelper(MethodTable* nullableMT, MethodTable* paramMT);
4289     static BOOL IsNullableForTypeHelperNoGC(MethodTable* nullableMT, MethodTable* paramMT);
4290
4291     CLR_BOOL* HasValueAddr(MethodTable* nullableMT);
4292     void* ValueAddr(MethodTable* nullableMT);
4293 };
4294
4295 #ifdef USE_CHECKED_OBJECTREFS
4296 typedef REF<ExceptionObject> EXCEPTIONREF;
4297 #else // USE_CHECKED_OBJECTREFS
4298 typedef PTR_ExceptionObject EXCEPTIONREF;
4299 #endif // USE_CHECKED_OBJECTREFS
4300
4301 #endif // _OBJECT_H_