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