68eec6b57e3efc389f1fa07459b32d51073972f7
[platform/upstream/coreclr.git] / src / inc / corinfo.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 // 
6
7 /*****************************************************************************\
8 *                                                                             *
9 * CorInfo.h -    EE / Code generator interface                                *
10 *                                                                             *
11 *******************************************************************************
12 *
13 * This file exposes CLR runtime functionality. It can be used by compilers,
14 * both Just-in-time and ahead-of-time, to generate native code which
15 * executes in the runtime environment.
16 *******************************************************************************
17
18 //////////////////////////////////////////////////////////////////////////////////////////////////////////
19 //
20 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
21 //
22 // The JIT/EE interface is versioned. By "interface", we mean mean any and all communication between the
23 // JIT and the EE. Any time a change is made to the interface, the JIT/EE interface version identifier
24 // must be updated. See code:JITEEVersionIdentifier for more information.
25 // 
26 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
27 //
28 //////////////////////////////////////////////////////////////////////////////////////////////////////////
29
30 #EEJitContractDetails
31
32 The semantic contract between the EE and the JIT should be documented here It is incomplete, but as time goes
33 on, that hopefully will change
34
35 See file:../../doc/BookOfTheRuntime/JIT/JIT%20Design.doc for details on the JIT compiler. See
36 code:EEStartup#TableOfContents for information on the runtime as a whole.
37
38 -------------------------------------------------------------------------------
39 #Tokens
40
41 The tokens in IL stream needs to be resolved to EE handles (CORINFO_CLASS/METHOD/FIELD_HANDLE) that 
42 the runtime operates with. ICorStaticInfo::resolveToken is the method that resolves the found in IL stream 
43 to set of EE handles (CORINFO_RESOLVED_TOKEN). All other APIs take resolved token as input. This design 
44 avoids redundant token resolutions.
45
46 The token validation is done as part of token resolution. The JIT is not required to do explicit upfront
47 token validation.
48
49 -------------------------------------------------------------------------------
50 #ClassConstruction
51
52 First of all class contruction comes in two flavors precise and 'beforeFieldInit'. In C# you get the former
53 if you declare an explicit class constructor method and the later if you declaratively initialize static
54 fields. Precise class construction guarentees that the .cctor is run precisely before the first access to any
55 method or field of the class. 'beforeFieldInit' semantics guarentees only that the .cctor will be run some
56 time before the first static field access (note that calling methods (static or insance) or accessing
57 instance fields does not cause .cctors to be run).
58
59 Next you need to know that there are two kinds of code generation that can happen in the JIT: appdomain
60 neutral and appdomain specialized. The difference between these two kinds of code is how statics are handled.
61 For appdomain specific code, the address of a particular static variable is embeded in the code. This makes
62 it usable only for one appdomain (since every appdomain gets a own copy of its statics). Appdomain neutral
63 code calls a helper that looks up static variables off of a thread local variable. Thus the same code can be
64 used by mulitple appdomains in the same process.  
65
66 Generics also introduce a similar issue. Code for generic classes might be specialised for a particular set
67 of type arguments, or it could use helpers to access data that depends on type parameters and thus be shared
68 across several instantiations of the generic type.
69
70 Thus there four cases
71
72     * BeforeFieldInitCCtor - Unshared code. Cctors are only called when static fields are fetched. At the
73         time the method that touches the static field is JITed (or fixed up in the case of NGENed code), the
74         .cctor is called.
75     * BeforeFieldInitCCtor - Shared code. Since the same code is used for multiple classes, the act of JITing
76         the code can not be used as a hook. However, it is also the case that since the code is shared, it
77         can not wire in a particular address for the static and thus needs to use a helper that looks up the
78         correct address based on the thread ID. This helper does the .cctor check, and thus no additional
79         cctor logic is needed.
80     * PreciseCCtor - Unshared code. Any time a method is JITTed (or fixed up in the case of NGEN), a cctor
81         check for the class of the method being JITTed is done. In addition the JIT inserts explicit checks
82         before any static field accesses. Instance methods and fields do NOT have hooks because a .ctor
83         method must be called before the instance can be created.
84     * PreciseCctor - Shared code .cctor checks are placed in the prolog of every .ctor and static method. All
85         methods that access static fields have an explicit .cctor check before use. Again instance methods
86         don't have hooks because a .ctor would have to be called first.
87
88 Technically speaking, however the optimization of avoiding checks on instance methods is flawed. It requires
89 that a .ctor always preceed a call to an instance methods. This break down when
90
91     * A NULL is passed to an instance method.
92     * A .ctor does not call its superclasses .ctor. This allows an instance to be created without necessarily
93         calling all the .cctors of all the superclasses. A virtual call can then be made to a instance of a
94         superclass without necessarily calling the superclass's .cctor.
95     * The class is a value class (which exists without a .ctor being called)
96
97 Nevertheless, the cost of plugging these holes is considered to high and the benefit is low.
98
99 ----------------------------------------------------------------------
100
101 #ClassConstructionFlags 
102
103 Thus the JIT's cctor responsibilities require it to check with the EE on every static field access using
104 initClass and before jitting any method to see if a .cctor check must be placed in the prolog.
105
106     * CORINFO_FLG_BEFOREFIELDINIT indicate the class has beforeFieldInit semantics. The jit does not strictly
107         need this information however, it is valuable in optimizing static field fetch helper calls. Helper
108         call for classes with BeforeFieldInit semantics can be hoisted before other side effects where
109         classes with precise .cctor semantics do not allow this optimization.
110
111 Inlining also complicates things. Because the class could have precise semantics it is also required that the
112 inlining of any constructor or static method must also do the initClass check. The inliner has the option of 
113 inserting any required runtime check or simply not inlining the function.
114
115 -------------------------------------------------------------------------------
116
117 #StaticFields
118
119 The first 4 options are mutially exclusive 
120
121     * CORINFO_FLG_HELPER If the field has this set, then the JIT must call getFieldHelper and call the
122         returned helper with the object ref (for an instance field) and a fieldDesc. Note that this should be
123         able to handle ANY field so to get a JIT up quickly, it has the option of using helper calls for all
124         field access (and skip the complexity below). Note that for statics it is assumed that you will
125         alwasy ask for the ADDRESSS helper and to the fetch in the JIT.
126
127     * CORINFO_FLG_SHARED_HELPER This is currently only used for static fields. If this bit is set it means
128         that the field is feched by a helper call that takes a module identifier (see getModuleDomainID) and
129         a class identifier (see getClassDomainID) as arguments. The exact helper to call is determined by
130         getSharedStaticBaseHelper. The return value is of this function is the base of all statics in the
131         module. The offset from getFieldOffset must be added to this value to get the address of the field
132         itself. (see also CORINFO_FLG_STATIC_IN_HEAP).
133
134
135     * CORINFO_FLG_GENERICS_STATIC This is currently only used for static fields (of generic type). This
136         function is intended to be called with a Generic handle as a argument (from embedGenericHandle). The
137         exact helper to call is determined by getSharedStaticBaseHelper. The returned value is the base of
138         all statics in the class. The offset from getFieldOffset must be added to this value to get the
139         address of the (see also CORINFO_FLG_STATIC_IN_HEAP).
140
141     * CORINFO_FLG_TLS This indicate that the static field is a Windows style Thread Local Static. (We also
142         have managed thread local statics, which work through the HELPER. Support for this is considered
143         legacy, and going forward, the EE should
144
145     * <NONE> This is a normal static field. Its address in in memory is determined by getFieldAddress. (see
146         also CORINFO_FLG_STATIC_IN_HEAP).
147
148
149 This last field can modify any of the cases above except CORINFO_FLG_HELPER
150
151 CORINFO_FLG_STATIC_IN_HEAP This is currently only used for static fields of value classes. If the field has
152 this set then after computing what would normally be the field, what you actually get is a object pointer
153 (that must be reported to the GC) to a boxed version of the value. Thus the actual field address is computed
154 by addr = (*addr+sizeof(OBJECTREF))
155
156 Instance fields
157
158     * CORINFO_FLG_HELPER This is used if the class is MarshalByRef, which means that the object might be a
159         proxyt to the real object in some other appdomain or process. If the field has this set, then the JIT
160         must call getFieldHelper and call the returned helper with the object ref. If the helper returned is
161         helpers that are for structures the args are as follows
162
163     * CORINFO_HELP_GETFIELDSTRUCT - args are: retBuff, object, fieldDesc 
164     * CORINFO_HELP_SETFIELDSTRUCT - args are object fieldDesc value
165
166 The other GET helpers take an object fieldDesc and return the value The other SET helpers take an object
167 fieldDesc and value
168
169     Note that unlike static fields there is no helper to take the address of a field because in general there
170     is no address for proxies (LDFLDA is illegal on proxies).
171
172     CORINFO_FLG_EnC This is to support adding new field for edit and continue. This field also indicates that
173     a helper is needed to access this field. However this helper is always CORINFO_HELP_GETFIELDADDR, and
174     this helper always takes the object and field handle and returns the address of the field. It is the
175                             JIT's responcibility to do the fetch or set. 
176
177 -------------------------------------------------------------------------------
178
179 TODO: Talk about initializing strutures before use 
180
181
182 *******************************************************************************
183 */
184
185 #ifndef _COR_INFO_H_
186 #define _COR_INFO_H_
187
188 #include <corhdr.h>
189 #include <specstrings.h>
190
191 //////////////////////////////////////////////////////////////////////////////////////////////////////////
192 //
193 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
194 //
195 // #JITEEVersionIdentifier
196 //
197 // This GUID represents the version of the JIT/EE interface. Any time the interface between the JIT and
198 // the EE changes (by adding or removing methods to any interface shared between them), this GUID should
199 // be changed. This is the identifier verified by ICorJitCompiler::getVersionIdentifier().
200 //
201 // You can use "uuidgen.exe -s" to generate this value.
202 //
203 // **** NOTE TO INTEGRATORS:
204 //
205 // If there is a merge conflict here, because the version changed in two different places, you must
206 // create a **NEW** GUID, not simply choose one or the other!
207 //
208 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
209 //
210 //////////////////////////////////////////////////////////////////////////////////////////////////////////
211
212 #if !defined(SELECTANY)
213     #define SELECTANY extern __declspec(selectany)
214 #endif
215
216 SELECTANY const GUID JITEEVersionIdentifier = { /* 09F7AAE2-07DF-4433-B8C5-BA864CCABDA3 */
217     0x9f7aae2,
218     0x7df,
219     0x4433,
220     {0xb8, 0xc5, 0xba, 0x86, 0x4c, 0xca, 0xbd, 0xa3}
221 };
222
223 //////////////////////////////////////////////////////////////////////////////////////////////////////////
224 //
225 // END JITEEVersionIdentifier
226 //
227 //////////////////////////////////////////////////////////////////////////////////////////////////////////
228
229 // For System V on the CLR type system number of registers to pass in and return a struct is the same.
230 // The CLR type system allows only up to 2 eightbytes to be passed in registers. There is no SSEUP classification types.
231 #define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS   2 
232 #define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_RETURN_IN_REGISTERS 2
233 #define CLR_SYSTEMV_MAX_STRUCT_BYTES_TO_PASS_IN_REGISTERS       16
234
235 // System V struct passing
236 // The Classification types are described in the ABI spec at http://www.x86-64.org/documentation/abi.pdf
237 enum SystemVClassificationType : unsigned __int8
238 {
239     SystemVClassificationTypeUnknown            = 0,
240     SystemVClassificationTypeStruct             = 1,
241     SystemVClassificationTypeNoClass            = 2,
242     SystemVClassificationTypeMemory             = 3,
243     SystemVClassificationTypeInteger            = 4,
244     SystemVClassificationTypeIntegerReference   = 5,
245     SystemVClassificationTypeIntegerByRef       = 6,
246     SystemVClassificationTypeSSE                = 7,
247     // SystemVClassificationTypeSSEUp           = Unused, // Not supported by the CLR.
248     // SystemVClassificationTypeX87             = Unused, // Not supported by the CLR.
249     // SystemVClassificationTypeX87Up           = Unused, // Not supported by the CLR.
250     // SystemVClassificationTypeComplexX87      = Unused, // Not supported by the CLR.
251
252     // Internal flags - never returned outside of the classification implementation.
253
254     // This value represents a very special type with two eightbytes. 
255     // First ByRef, second Integer (platform int).
256     // The VM has a special Elem type for this type - ELEMENT_TYPE_TYPEDBYREF.
257     // This is the classification counterpart for that element type. It is used to detect 
258     // the special TypedReference type and specialize its classification.
259     // This type is represented as a struct with two fields. The classification needs to do
260     // special handling of it since the source/methadata type of the fieds is IntPtr. 
261     // The VM changes the first to ByRef. The second is left as IntPtr (TYP_I_IMPL really). The classification needs to match this and
262     // special handling is warranted (similar thing is done in the getGCLayout function for this type).
263     SystemVClassificationTypeTypedReference     = 8,
264     SystemVClassificationTypeMAX                = 9,
265 };
266
267 // Represents classification information for a struct.
268 struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
269 {
270     SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR()
271     {
272         Initialize();
273     }
274
275     bool                        passedInRegisters; // Whether the struct is passable/passed (this includes struct returning) in registers.
276     unsigned __int8             eightByteCount;    // Number of eightbytes for this struct.
277     SystemVClassificationType   eightByteClassifications[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The eightbytes type classification.
278     unsigned __int8             eightByteSizes[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS];           // The size of the eightbytes (an eightbyte could include padding. This represents the no padding size of the eightbyte).
279     unsigned __int8             eightByteOffsets[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS];         // The start offset of the eightbytes (in bytes).
280
281     // Members
282
283     //------------------------------------------------------------------------
284     // CopyFrom: Copies a struct classification into this one.
285     //
286     // Arguments:
287     //    'copyFrom' the struct classification to copy from.
288     //
289     void CopyFrom(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& copyFrom)
290     {
291         passedInRegisters = copyFrom.passedInRegisters;
292         eightByteCount = copyFrom.eightByteCount;
293
294         for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
295         {
296             eightByteClassifications[i] = copyFrom.eightByteClassifications[i];
297             eightByteSizes[i] = copyFrom.eightByteSizes[i];
298             eightByteOffsets[i] = copyFrom.eightByteOffsets[i];
299         }
300     }
301
302     //------------------------------------------------------------------------
303     // IsIntegralSlot: Returns whether the eightbyte at slotIndex is of integral type.
304     //
305     // Arguments:
306     //    'slotIndex' the slot number we are determining if it is of integral type.
307     //
308     // Return value:
309     //     returns true if we the eightbyte at index slotIndex is of integral type.
310     // 
311
312     bool IsIntegralSlot(unsigned slotIndex) const
313     {
314         return ((eightByteClassifications[slotIndex] == SystemVClassificationTypeInteger) ||
315                 (eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerReference) ||
316                 (eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerByRef));
317     }
318
319     //------------------------------------------------------------------------
320     // IsSseSlot: Returns whether the eightbyte at slotIndex is SSE type.
321     //
322     // Arguments:
323     //    'slotIndex' the slot number we are determining if it is of SSE type.
324     //
325     // Return value:
326     //     returns true if we the eightbyte at index slotIndex is of SSE type.
327     // 
328     // Follows the rules of the AMD64 System V ABI specification at www.x86-64.org/documentation/abi.pdf.
329     // Please reffer to it for definitions/examples.
330     //
331     bool IsSseSlot(unsigned slotIndex) const
332     {
333         return (eightByteClassifications[slotIndex] == SystemVClassificationTypeSSE);
334     }
335
336 private:
337     void Initialize()
338     {
339         passedInRegisters = false;
340         eightByteCount = 0;
341
342         for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
343         {
344             eightByteClassifications[i] = SystemVClassificationTypeUnknown;
345             eightByteSizes[i] = 0;
346             eightByteOffsets[i] = 0;
347         }
348     }
349 };
350
351 // CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
352 // These helpers can be called by native code which executes in the runtime.
353 // Compilers can emit calls to these helpers.
354 //
355 // The signatures of the helpers are below (see RuntimeHelperArgumentCheck)
356
357 enum CorInfoHelpFunc
358 {
359     CORINFO_HELP_UNDEF,         // invalid value. This should never be used
360
361     /* Arithmetic helpers */
362
363     CORINFO_HELP_DIV,           // For the ARM 32-bit integer divide uses a helper call :-(
364     CORINFO_HELP_MOD,
365     CORINFO_HELP_UDIV,
366     CORINFO_HELP_UMOD,
367
368     CORINFO_HELP_LLSH,
369     CORINFO_HELP_LRSH,
370     CORINFO_HELP_LRSZ,
371     CORINFO_HELP_LMUL,
372     CORINFO_HELP_LMUL_OVF,
373     CORINFO_HELP_ULMUL_OVF,
374     CORINFO_HELP_LDIV,
375     CORINFO_HELP_LMOD,
376     CORINFO_HELP_ULDIV,
377     CORINFO_HELP_ULMOD,
378     CORINFO_HELP_LNG2DBL,               // Convert a signed int64 to a double
379     CORINFO_HELP_ULNG2DBL,              // Convert a unsigned int64 to a double
380     CORINFO_HELP_DBL2INT,
381     CORINFO_HELP_DBL2INT_OVF,
382     CORINFO_HELP_DBL2LNG,
383     CORINFO_HELP_DBL2LNG_OVF,
384     CORINFO_HELP_DBL2UINT,
385     CORINFO_HELP_DBL2UINT_OVF,
386     CORINFO_HELP_DBL2ULNG,
387     CORINFO_HELP_DBL2ULNG_OVF,
388     CORINFO_HELP_FLTREM,
389     CORINFO_HELP_DBLREM,
390     CORINFO_HELP_FLTROUND,
391     CORINFO_HELP_DBLROUND,
392
393     /* Allocating a new object. Always use ICorClassInfo::getNewHelper() to decide 
394        which is the right helper to use to allocate an object of a given type. */
395
396     CORINFO_HELP_NEW_CROSSCONTEXT,  // cross context new object
397     CORINFO_HELP_NEWFAST,
398     CORINFO_HELP_NEWSFAST,          // allocator for small, non-finalizer, non-array object
399     CORINFO_HELP_NEWSFAST_ALIGN8,   // allocator for small, non-finalizer, non-array object, 8 byte aligned
400     CORINFO_HELP_NEW_MDARR,         // multi-dim array helper (with or without lower bounds - dimensions passed in as vararg)
401     CORINFO_HELP_NEW_MDARR_NONVARARG,// multi-dim array helper (with or without lower bounds - dimensions passed in as unmanaged array)
402     CORINFO_HELP_NEWARR_1_DIRECT,   // helper for any one dimensional array creation
403     CORINFO_HELP_NEWARR_1_R2R_DIRECT, // wrapper for R2R direct call, which extracts method table from ArrayTypeDesc
404     CORINFO_HELP_NEWARR_1_OBJ,      // optimized 1-D object arrays
405     CORINFO_HELP_NEWARR_1_VC,       // optimized 1-D value class arrays
406     CORINFO_HELP_NEWARR_1_ALIGN8,   // like VC, but aligns the array start
407
408     CORINFO_HELP_STRCNS,            // create a new string literal
409     CORINFO_HELP_STRCNS_CURRENT_MODULE, // create a new string literal from the current module (used by NGen code)
410
411     /* Object model */
412
413     CORINFO_HELP_INITCLASS,         // Initialize class if not already initialized
414     CORINFO_HELP_INITINSTCLASS,     // Initialize class for instantiated type
415
416     // Use ICorClassInfo::getCastingHelper to determine
417     // the right helper to use
418
419     CORINFO_HELP_ISINSTANCEOFINTERFACE, // Optimized helper for interfaces
420     CORINFO_HELP_ISINSTANCEOFARRAY,  // Optimized helper for arrays
421     CORINFO_HELP_ISINSTANCEOFCLASS, // Optimized helper for classes
422     CORINFO_HELP_ISINSTANCEOFANY,   // Slow helper for any type
423
424     CORINFO_HELP_CHKCASTINTERFACE,
425     CORINFO_HELP_CHKCASTARRAY,
426     CORINFO_HELP_CHKCASTCLASS,
427     CORINFO_HELP_CHKCASTANY,
428     CORINFO_HELP_CHKCASTCLASS_SPECIAL, // Optimized helper for classes. Assumes that the trivial cases 
429                                     // has been taken care of by the inlined check
430
431     CORINFO_HELP_BOX,
432     CORINFO_HELP_BOX_NULLABLE,      // special form of boxing for Nullable<T>
433     CORINFO_HELP_UNBOX,
434     CORINFO_HELP_UNBOX_NULLABLE,    // special form of unboxing for Nullable<T>
435     CORINFO_HELP_GETREFANY,         // Extract the byref from a TypedReference, checking that it is the expected type
436
437     CORINFO_HELP_ARRADDR_ST,        // assign to element of object array with type-checking
438     CORINFO_HELP_LDELEMA_REF,       // does a precise type comparision and returns address
439
440     /* Exceptions */
441
442     CORINFO_HELP_THROW,             // Throw an exception object
443     CORINFO_HELP_RETHROW,           // Rethrow the currently active exception
444     CORINFO_HELP_USER_BREAKPOINT,   // For a user program to break to the debugger
445     CORINFO_HELP_RNGCHKFAIL,        // array bounds check failed
446     CORINFO_HELP_OVERFLOW,          // throw an overflow exception
447     CORINFO_HELP_THROWDIVZERO,      // throw a divide by zero exception
448     CORINFO_HELP_THROWNULLREF,      // throw a null reference exception
449
450     CORINFO_HELP_INTERNALTHROW,     // Support for really fast jit
451     CORINFO_HELP_VERIFICATION,      // Throw a VerificationException
452     CORINFO_HELP_SEC_UNMGDCODE_EXCPT, // throw a security unmanaged code exception
453     CORINFO_HELP_FAIL_FAST,         // Kill the process avoiding any exceptions or stack and data dependencies (use for GuardStack unsafe buffer checks)
454
455     CORINFO_HELP_METHOD_ACCESS_EXCEPTION,//Throw an access exception due to a failed member/class access check.
456     CORINFO_HELP_FIELD_ACCESS_EXCEPTION,
457     CORINFO_HELP_CLASS_ACCESS_EXCEPTION,
458
459     CORINFO_HELP_ENDCATCH,          // call back into the EE at the end of a catch block
460
461     /* Synchronization */
462
463     CORINFO_HELP_MON_ENTER,
464     CORINFO_HELP_MON_EXIT,
465     CORINFO_HELP_MON_ENTER_STATIC,
466     CORINFO_HELP_MON_EXIT_STATIC,
467
468     CORINFO_HELP_GETCLASSFROMMETHODPARAM, // Given a generics method handle, returns a class handle
469     CORINFO_HELP_GETSYNCFROMCLASSHANDLE,  // Given a generics class handle, returns the sync monitor 
470                                           // in its ManagedClassObject
471
472     /* Security callout support */
473     
474     CORINFO_HELP_SECURITY_PROLOG,   // Required if CORINFO_FLG_SECURITYCHECK is set, or CORINFO_FLG_NOSECURITYWRAP is not set
475     CORINFO_HELP_SECURITY_PROLOG_FRAMED, // Slow version of CORINFO_HELP_SECURITY_PROLOG. Used for instrumentation.
476
477     CORINFO_HELP_METHOD_ACCESS_CHECK, // Callouts to runtime security access checks
478     CORINFO_HELP_FIELD_ACCESS_CHECK,
479     CORINFO_HELP_CLASS_ACCESS_CHECK,
480
481     CORINFO_HELP_DELEGATE_SECURITY_CHECK, // Callout to delegate security transparency check
482
483      /* Verification runtime callout support */
484
485     CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, // Do a Demand for UnmanagedCode permission at runtime
486
487     /* GC support */
488
489     CORINFO_HELP_STOP_FOR_GC,       // Call GC (force a GC)
490     CORINFO_HELP_POLL_GC,           // Ask GC if it wants to collect
491
492     CORINFO_HELP_STRESS_GC,         // Force a GC, but then update the JITTED code to be a noop call
493     CORINFO_HELP_CHECK_OBJ,         // confirm that ECX is a valid object pointer (debugging only)
494
495     /* GC Write barrier support */
496
497     CORINFO_HELP_ASSIGN_REF,        // universal helpers with F_CALL_CONV calling convention
498     CORINFO_HELP_CHECKED_ASSIGN_REF,
499     CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP,  // Do the store, and ensure that the target was not in the heap.
500
501     CORINFO_HELP_ASSIGN_BYREF,
502     CORINFO_HELP_ASSIGN_STRUCT,
503
504
505     /* Accessing fields */
506
507     // For COM object support (using COM get/set routines to update object)
508     // and EnC and cross-context support
509     CORINFO_HELP_GETFIELD8,
510     CORINFO_HELP_SETFIELD8,
511     CORINFO_HELP_GETFIELD16,
512     CORINFO_HELP_SETFIELD16,
513     CORINFO_HELP_GETFIELD32,
514     CORINFO_HELP_SETFIELD32,
515     CORINFO_HELP_GETFIELD64,
516     CORINFO_HELP_SETFIELD64,
517     CORINFO_HELP_GETFIELDOBJ,
518     CORINFO_HELP_SETFIELDOBJ,
519     CORINFO_HELP_GETFIELDSTRUCT,
520     CORINFO_HELP_SETFIELDSTRUCT,
521     CORINFO_HELP_GETFIELDFLOAT,
522     CORINFO_HELP_SETFIELDFLOAT,
523     CORINFO_HELP_GETFIELDDOUBLE,
524     CORINFO_HELP_SETFIELDDOUBLE,
525
526     CORINFO_HELP_GETFIELDADDR,
527
528     CORINFO_HELP_GETSTATICFIELDADDR_CONTEXT,    // Helper for context-static fields
529     CORINFO_HELP_GETSTATICFIELDADDR_TLS,        // Helper for PE TLS fields
530
531     // There are a variety of specialized helpers for accessing static fields. The JIT should use 
532     // ICorClassInfo::getSharedStaticsOrCCtorHelper to determine which helper to use
533
534     // Helpers for regular statics
535     CORINFO_HELP_GETGENERICS_GCSTATIC_BASE,
536     CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE,
537     CORINFO_HELP_GETSHARED_GCSTATIC_BASE,
538     CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE,
539     CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR,
540     CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,
541     CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS,
542     CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_DYNAMICCLASS,
543     // Helper to class initialize shared generic with dynamicclass, but not get static field address
544     CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS,
545
546     // Helpers for thread statics
547     CORINFO_HELP_GETGENERICS_GCTHREADSTATIC_BASE,
548     CORINFO_HELP_GETGENERICS_NONGCTHREADSTATIC_BASE,
549     CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE,
550     CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE,
551     CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR,
552     CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR,
553     CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS,
554     CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS,
555
556     /* Debugger */
557
558     CORINFO_HELP_DBG_IS_JUST_MY_CODE,    // Check if this is "JustMyCode" and needs to be stepped through.
559
560     /* Profiling enter/leave probe addresses */
561     CORINFO_HELP_PROF_FCN_ENTER,        // record the entry to a method (caller)
562     CORINFO_HELP_PROF_FCN_LEAVE,        // record the completion of current method (caller)
563     CORINFO_HELP_PROF_FCN_TAILCALL,     // record the completionof current method through tailcall (caller)
564
565     /* Miscellaneous */
566
567     CORINFO_HELP_BBT_FCN_ENTER,         // record the entry to a method for collecting Tuning data
568
569     CORINFO_HELP_PINVOKE_CALLI,         // Indirect pinvoke call
570     CORINFO_HELP_TAILCALL,              // Perform a tail call
571     
572     CORINFO_HELP_GETCURRENTMANAGEDTHREADID,
573
574     CORINFO_HELP_INIT_PINVOKE_FRAME,   // initialize an inlined PInvoke Frame for the JIT-compiler
575
576     CORINFO_HELP_MEMSET,                // Init block of memory
577     CORINFO_HELP_MEMCPY,                // Copy block of memory
578
579     CORINFO_HELP_RUNTIMEHANDLE_METHOD,          // determine a type/field/method handle at run-time
580     CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG,      // determine a type/field/method handle at run-time, with IBC logging
581     CORINFO_HELP_RUNTIMEHANDLE_CLASS,           // determine a type/field/method handle at run-time
582     CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG,       // determine a type/field/method handle at run-time, with IBC logging
583
584     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time
585     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time, the type may be null
586     CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD, // Convert from a MethodDesc (native structure pointer) to RuntimeMethodHandle at run-time
587     CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD, // Convert from a FieldDesc (native structure pointer) to RuntimeFieldHandle at run-time
588     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time
589     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type
590
591     CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent
592
593     CORINFO_HELP_VIRTUAL_FUNC_PTR,      // look up a virtual method at run-time
594     //CORINFO_HELP_VIRTUAL_FUNC_PTR_LOG,  // look up a virtual method at run-time, with IBC logging
595
596     // Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper.
597     CORINFO_HELP_READYTORUN_NEW,
598     CORINFO_HELP_READYTORUN_NEWARR_1,
599     CORINFO_HELP_READYTORUN_ISINSTANCEOF,
600     CORINFO_HELP_READYTORUN_CHKCAST,
601     CORINFO_HELP_READYTORUN_STATIC_BASE,
602     CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,
603     CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
604     CORINFO_HELP_READYTORUN_DELEGATE_CTOR,
605     CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE,
606
607     CORINFO_HELP_EE_PRESTUB,            // Not real JIT helper. Used in native images.
608
609     CORINFO_HELP_EE_PRECODE_FIXUP,      // Not real JIT helper. Used for Precode fixup in native images.
610     CORINFO_HELP_EE_PINVOKE_FIXUP,      // Not real JIT helper. Used for PInvoke target fixup in native images.
611     CORINFO_HELP_EE_VSD_FIXUP,          // Not real JIT helper. Used for VSD cell fixup in native images.
612     CORINFO_HELP_EE_EXTERNAL_FIXUP,     // Not real JIT helper. Used for to fixup external method thunks in native images.
613     CORINFO_HELP_EE_VTABLE_FIXUP,       // Not real JIT helper. Used for inherited vtable slot fixup in native images.
614
615     CORINFO_HELP_EE_REMOTING_THUNK,     // Not real JIT helper. Used for remoting precode in native images.
616
617     CORINFO_HELP_EE_PERSONALITY_ROUTINE,// Not real JIT helper. Used in native images.
618     CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET,// Not real JIT helper. Used in native images to detect filter funclets.
619
620     // ASSIGN_REF_EAX - CHECKED_ASSIGN_REF_EBP: NOGC_WRITE_BARRIERS JIT helper calls
621     //
622     // For unchecked versions EDX is required to point into GC heap.
623     //
624     // NOTE: these helpers are only used for x86.
625     CORINFO_HELP_ASSIGN_REF_EAX,    // EAX holds GC ptr, do a 'mov [EDX], EAX' and inform GC
626     CORINFO_HELP_ASSIGN_REF_EBX,    // EBX holds GC ptr, do a 'mov [EDX], EBX' and inform GC
627     CORINFO_HELP_ASSIGN_REF_ECX,    // ECX holds GC ptr, do a 'mov [EDX], ECX' and inform GC
628     CORINFO_HELP_ASSIGN_REF_ESI,    // ESI holds GC ptr, do a 'mov [EDX], ESI' and inform GC
629     CORINFO_HELP_ASSIGN_REF_EDI,    // EDI holds GC ptr, do a 'mov [EDX], EDI' and inform GC
630     CORINFO_HELP_ASSIGN_REF_EBP,    // EBP holds GC ptr, do a 'mov [EDX], EBP' and inform GC
631
632     CORINFO_HELP_CHECKED_ASSIGN_REF_EAX,  // These are the same as ASSIGN_REF above ...
633     CORINFO_HELP_CHECKED_ASSIGN_REF_EBX,  // ... but also check if EDX points into heap.
634     CORINFO_HELP_CHECKED_ASSIGN_REF_ECX,
635     CORINFO_HELP_CHECKED_ASSIGN_REF_ESI,
636     CORINFO_HELP_CHECKED_ASSIGN_REF_EDI,
637     CORINFO_HELP_CHECKED_ASSIGN_REF_EBP,
638
639     CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress.
640     CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode.
641
642     CORINFO_HELP_THROW_ARGUMENTEXCEPTION,           // throw ArgumentException
643     CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION, // throw ArgumentOutOfRangeException
644     CORINFO_HELP_THROW_NOT_IMPLEMENTED,             // throw NotImplementedException
645     CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED,      // throw PlatformNotSupportedException
646     CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED,          // throw TypeNotSupportedException
647
648     CORINFO_HELP_JIT_PINVOKE_BEGIN, // Transition to preemptive mode before a P/Invoke, frame is the first argument
649     CORINFO_HELP_JIT_PINVOKE_END,   // Transition to cooperative mode after a P/Invoke, frame is the first argument
650
651     CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, // Transition to cooperative mode in reverse P/Invoke prolog, frame is the first argument
652     CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT,  // Transition to preemptive mode in reverse P/Invoke epilog, frame is the first argument
653
654     CORINFO_HELP_GVMLOOKUP_FOR_SLOT,        // Resolve a generic virtual method target from this pointer and runtime method handle 
655
656     CORINFO_HELP_COUNT,
657 };
658
659 #define CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE 0x40000000
660
661 //This describes the signature for a helper method.
662 enum CorInfoHelpSig
663 {
664     CORINFO_HELP_SIG_UNDEF,
665     CORINFO_HELP_SIG_NO_ALIGN_STUB,
666     CORINFO_HELP_SIG_NO_UNWIND_STUB,
667     CORINFO_HELP_SIG_REG_ONLY,
668     CORINFO_HELP_SIG_4_STACK,
669     CORINFO_HELP_SIG_8_STACK,
670     CORINFO_HELP_SIG_12_STACK,
671     CORINFO_HELP_SIG_16_STACK,
672     CORINFO_HELP_SIG_8_VA, //2 arguments plus varargs
673
674     CORINFO_HELP_SIG_EBPCALL, //special calling convention that uses EDX and
675                               //EBP as arguments
676
677     CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB,
678
679     CORINFO_HELP_SIG_COUNT
680 };
681
682 // The enumeration is returned in 'getSig','getType', getArgType methods
683 enum CorInfoType
684 {
685     CORINFO_TYPE_UNDEF           = 0x0,
686     CORINFO_TYPE_VOID            = 0x1,
687     CORINFO_TYPE_BOOL            = 0x2,
688     CORINFO_TYPE_CHAR            = 0x3,
689     CORINFO_TYPE_BYTE            = 0x4,
690     CORINFO_TYPE_UBYTE           = 0x5,
691     CORINFO_TYPE_SHORT           = 0x6,
692     CORINFO_TYPE_USHORT          = 0x7,
693     CORINFO_TYPE_INT             = 0x8,
694     CORINFO_TYPE_UINT            = 0x9,
695     CORINFO_TYPE_LONG            = 0xa,
696     CORINFO_TYPE_ULONG           = 0xb,
697     CORINFO_TYPE_NATIVEINT       = 0xc,
698     CORINFO_TYPE_NATIVEUINT      = 0xd,
699     CORINFO_TYPE_FLOAT           = 0xe,
700     CORINFO_TYPE_DOUBLE          = 0xf,
701     CORINFO_TYPE_STRING          = 0x10,         // Not used, should remove
702     CORINFO_TYPE_PTR             = 0x11,
703     CORINFO_TYPE_BYREF           = 0x12,
704     CORINFO_TYPE_VALUECLASS      = 0x13,
705     CORINFO_TYPE_CLASS           = 0x14,
706     CORINFO_TYPE_REFANY          = 0x15,
707
708     // CORINFO_TYPE_VAR is for a generic type variable.
709     // Generic type variables only appear when the JIT is doing
710     // verification (not NOT compilation) of generic code
711     // for the EE, in which case we're running
712     // the JIT in "import only" mode.
713
714     CORINFO_TYPE_VAR             = 0x16,
715     CORINFO_TYPE_COUNT,                         // number of jit types
716 };
717
718 enum CorInfoTypeWithMod
719 {
720     CORINFO_TYPE_MASK            = 0x3F,        // lower 6 bits are type mask
721     CORINFO_TYPE_MOD_PINNED      = 0x40,        // can be applied to CLASS, or BYREF to indiate pinned
722 };
723
724 inline CorInfoType strip(CorInfoTypeWithMod val) {
725     return CorInfoType(val & CORINFO_TYPE_MASK);
726 }
727
728 // The enumeration is returned in 'getSig'
729
730 enum CorInfoCallConv
731 {
732     // These correspond to CorCallingConvention
733
734     CORINFO_CALLCONV_DEFAULT    = 0x0,
735     CORINFO_CALLCONV_C          = 0x1,
736     CORINFO_CALLCONV_STDCALL    = 0x2,
737     CORINFO_CALLCONV_THISCALL   = 0x3,
738     CORINFO_CALLCONV_FASTCALL   = 0x4,
739     CORINFO_CALLCONV_VARARG     = 0x5,
740     CORINFO_CALLCONV_FIELD      = 0x6,
741     CORINFO_CALLCONV_LOCAL_SIG  = 0x7,
742     CORINFO_CALLCONV_PROPERTY   = 0x8,
743     CORINFO_CALLCONV_NATIVEVARARG = 0xb,    // used ONLY for IL stub PInvoke vararg calls
744
745     CORINFO_CALLCONV_MASK       = 0x0f,     // Calling convention is bottom 4 bits
746     CORINFO_CALLCONV_GENERIC    = 0x10,
747     CORINFO_CALLCONV_HASTHIS    = 0x20,
748     CORINFO_CALLCONV_EXPLICITTHIS=0x40,
749     CORINFO_CALLCONV_PARAMTYPE  = 0x80,     // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
750 };
751
752 #ifdef UNIX_X86_ABI
753 inline bool IsCallerPop(CorInfoCallConv callConv)
754 {
755     unsigned int umask = CORINFO_CALLCONV_STDCALL
756                        | CORINFO_CALLCONV_THISCALL
757                        | CORINFO_CALLCONV_FASTCALL;
758
759     return !(callConv & umask);
760 }
761 #endif // UNIX_X86_ABI
762
763 enum CorInfoUnmanagedCallConv
764 {
765     // These correspond to CorUnmanagedCallingConvention
766
767     CORINFO_UNMANAGED_CALLCONV_UNKNOWN,
768     CORINFO_UNMANAGED_CALLCONV_C,
769     CORINFO_UNMANAGED_CALLCONV_STDCALL,
770     CORINFO_UNMANAGED_CALLCONV_THISCALL,
771     CORINFO_UNMANAGED_CALLCONV_FASTCALL
772 };
773
774 // These are returned from getMethodOptions
775 enum CorInfoOptions
776 {
777     CORINFO_OPT_INIT_LOCALS                 = 0x00000010, // zero initialize all variables
778
779     CORINFO_GENERICS_CTXT_FROM_THIS         = 0x00000020, // is this shared generic code that access the generic context from the this pointer?  If so, then if the method has SEH then the 'this' pointer must always be reported and kept alive.
780     CORINFO_GENERICS_CTXT_FROM_METHODDESC   = 0x00000040, // is this shared generic code that access the generic context from the ParamTypeArg(that is a MethodDesc)?  If so, then if the method has SEH then the 'ParamTypeArg' must always be reported and kept alive. Same as CORINFO_CALLCONV_PARAMTYPE
781     CORINFO_GENERICS_CTXT_FROM_METHODTABLE  = 0x00000080, // is this shared generic code that access the generic context from the ParamTypeArg(that is a MethodTable)?  If so, then if the method has SEH then the 'ParamTypeArg' must always be reported and kept alive. Same as CORINFO_CALLCONV_PARAMTYPE
782     CORINFO_GENERICS_CTXT_MASK              = (CORINFO_GENERICS_CTXT_FROM_THIS |
783                                                CORINFO_GENERICS_CTXT_FROM_METHODDESC |
784                                                CORINFO_GENERICS_CTXT_FROM_METHODTABLE),
785     CORINFO_GENERICS_CTXT_KEEP_ALIVE        = 0x00000100, // Keep the generics context alive throughout the method even if there is no explicit use, and report its location to the CLR
786
787 };
788
789 //
790 // what type of code region we are in
791 //
792 enum CorInfoRegionKind
793 {
794     CORINFO_REGION_NONE,
795     CORINFO_REGION_HOT,
796     CORINFO_REGION_COLD,
797     CORINFO_REGION_JIT,
798 };
799
800
801 // these are the attribute flags for fields and methods (getMethodAttribs)
802 enum CorInfoFlag
803 {
804 //  CORINFO_FLG_UNUSED                = 0x00000001,
805 //  CORINFO_FLG_UNUSED                = 0x00000002,
806     CORINFO_FLG_PROTECTED             = 0x00000004,
807     CORINFO_FLG_STATIC                = 0x00000008,
808     CORINFO_FLG_FINAL                 = 0x00000010,
809     CORINFO_FLG_SYNCH                 = 0x00000020,
810     CORINFO_FLG_VIRTUAL               = 0x00000040,
811 //  CORINFO_FLG_UNUSED                = 0x00000080,
812     CORINFO_FLG_NATIVE                = 0x00000100,
813     CORINFO_FLG_INTRINSIC_TYPE        = 0x00000200, // This type is marked by [Intrinsic]
814     CORINFO_FLG_ABSTRACT              = 0x00000400,
815
816     CORINFO_FLG_EnC                   = 0x00000800, // member was added by Edit'n'Continue
817
818     // These are internal flags that can only be on methods
819     CORINFO_FLG_FORCEINLINE           = 0x00010000, // The method should be inlined if possible.
820     CORINFO_FLG_SHAREDINST            = 0x00020000, // the code for this method is shared between different generic instantiations (also set on classes/types)
821     CORINFO_FLG_DELEGATE_INVOKE       = 0x00040000, // "Delegate
822     CORINFO_FLG_PINVOKE               = 0x00080000, // Is a P/Invoke call
823     CORINFO_FLG_SECURITYCHECK         = 0x00100000, // Is one of the security routines that does a stackwalk (e.g. Assert, Demand)
824     CORINFO_FLG_NOGCCHECK             = 0x00200000, // This method is FCALL that has no GC check.  Don't put alone in loops
825     CORINFO_FLG_INTRINSIC             = 0x00400000, // This method MAY have an intrinsic ID
826     CORINFO_FLG_CONSTRUCTOR           = 0x00800000, // This method is an instance or type initializer
827     CORINFO_FLG_AGGRESSIVE_OPT        = 0x01000000, // The method may contain hot code and should be aggressively optimized if possible
828 //  CORINFO_FLG_UNUSED                = 0x02000000,
829     CORINFO_FLG_NOSECURITYWRAP        = 0x04000000, // The method requires no security checks
830     CORINFO_FLG_DONT_INLINE           = 0x10000000, // The method should not be inlined
831     CORINFO_FLG_DONT_INLINE_CALLER    = 0x20000000, // The method should not be inlined, nor should its callers. It cannot be tail called.
832     CORINFO_FLG_JIT_INTRINSIC         = 0x40000000, // Method is a potential jit intrinsic; verify identity by name check
833
834     // These are internal flags that can only be on Classes
835     CORINFO_FLG_VALUECLASS            = 0x00010000, // is the class a value class
836 //  This flag is define din the Methods section, but is also valid on classes.
837 //  CORINFO_FLG_SHAREDINST            = 0x00020000, // This class is satisfies TypeHandle::IsCanonicalSubtype
838     CORINFO_FLG_VAROBJSIZE            = 0x00040000, // the object size varies depending of constructor args
839     CORINFO_FLG_ARRAY                 = 0x00080000, // class is an array class (initialized differently)
840     CORINFO_FLG_OVERLAPPING_FIELDS    = 0x00100000, // struct or class has fields that overlap (aka union)
841     CORINFO_FLG_INTERFACE             = 0x00200000, // it is an interface
842     CORINFO_FLG_CONTEXTFUL            = 0x00400000, // is this a contextful class?
843     CORINFO_FLG_CUSTOMLAYOUT          = 0x00800000, // does this struct have custom layout?
844     CORINFO_FLG_CONTAINS_GC_PTR       = 0x01000000, // does the class contain a gc ptr ?
845     CORINFO_FLG_DELEGATE              = 0x02000000, // is this a subclass of delegate or multicast delegate ?
846     CORINFO_FLG_MARSHAL_BYREF         = 0x04000000, // is this a subclass of MarshalByRef ?
847     CORINFO_FLG_CONTAINS_STACK_PTR    = 0x08000000, // This class has a stack pointer inside it
848     CORINFO_FLG_VARIANCE              = 0x10000000, // MethodTable::HasVariance (sealed does *not* mean uncast-able)
849     CORINFO_FLG_BEFOREFIELDINIT       = 0x20000000, // Additional flexibility for when to run .cctor (see code:#ClassConstructionFlags)
850     CORINFO_FLG_GENERIC_TYPE_VARIABLE = 0x40000000, // This is really a handle for a variable type
851     CORINFO_FLG_UNSAFE_VALUECLASS     = 0x80000000, // Unsafe (C++'s /GS) value type
852 };
853
854 // Flags computed by a runtime compiler
855 enum CorInfoMethodRuntimeFlags
856 {
857     CORINFO_FLG_BAD_INLINEE         = 0x00000001, // The method is not suitable for inlining
858     CORINFO_FLG_VERIFIABLE          = 0x00000002, // The method has verifiable code
859     CORINFO_FLG_UNVERIFIABLE        = 0x00000004, // The method has unverifiable code
860 };
861
862
863 enum CORINFO_ACCESS_FLAGS
864 {
865     CORINFO_ACCESS_ANY        = 0x0000, // Normal access
866     CORINFO_ACCESS_THIS       = 0x0001, // Accessed via the this reference
867     CORINFO_ACCESS_UNWRAP     = 0x0002, // Accessed via an unwrap reference
868
869     CORINFO_ACCESS_NONNULL    = 0x0004, // Instance is guaranteed non-null
870
871     CORINFO_ACCESS_LDFTN      = 0x0010, // Accessed via ldftn
872
873     // Field access flags
874     CORINFO_ACCESS_GET        = 0x0100, // Field get (ldfld)
875     CORINFO_ACCESS_SET        = 0x0200, // Field set (stfld)
876     CORINFO_ACCESS_ADDRESS    = 0x0400, // Field address (ldflda)
877     CORINFO_ACCESS_INIT_ARRAY = 0x0800, // Field use for InitializeArray
878     CORINFO_ACCESS_ATYPICAL_CALLSITE = 0x4000, // Atypical callsite that cannot be disassembled by delay loading helper
879     CORINFO_ACCESS_INLINECHECK= 0x8000, // Return fieldFlags and fieldAccessor only. Used by JIT64 during inlining.
880 };
881
882 // These are the flags set on an CORINFO_EH_CLAUSE
883 enum CORINFO_EH_CLAUSE_FLAGS
884 {
885     CORINFO_EH_CLAUSE_NONE      = 0,
886     CORINFO_EH_CLAUSE_FILTER    = 0x0001, // If this bit is on, then this EH entry is for a filter
887     CORINFO_EH_CLAUSE_FINALLY   = 0x0002, // This clause is a finally clause
888     CORINFO_EH_CLAUSE_FAULT     = 0x0004, // This clause is a fault clause
889     CORINFO_EH_CLAUSE_DUPLICATE = 0x0008, // Duplicated clause. This clause was duplicated to a funclet which was pulled out of line
890     CORINFO_EH_CLAUSE_SAMETRY   = 0x0010, // This clause covers same try block as the previous one. (Used by CoreRT ABI.)
891 };
892
893 // This enumeration is passed to InternalThrow
894 enum CorInfoException
895 {
896     CORINFO_NullReferenceException,
897     CORINFO_DivideByZeroException,
898     CORINFO_InvalidCastException,
899     CORINFO_IndexOutOfRangeException,
900     CORINFO_OverflowException,
901     CORINFO_SynchronizationLockException,
902     CORINFO_ArrayTypeMismatchException,
903     CORINFO_RankException,
904     CORINFO_ArgumentNullException,
905     CORINFO_ArgumentException,
906     CORINFO_Exception_Count,
907 };
908
909
910 // This enumeration is returned by getIntrinsicID. Methods corresponding to
911 // these values will have "well-known" specified behavior. Calls to these
912 // methods could be replaced with inlined code corresponding to the
913 // specified behavior (without having to examine the IL beforehand).
914
915 enum CorInfoIntrinsics
916 {
917     CORINFO_INTRINSIC_Sin,
918     CORINFO_INTRINSIC_Cos,
919     CORINFO_INTRINSIC_Cbrt,
920     CORINFO_INTRINSIC_Sqrt,
921     CORINFO_INTRINSIC_Abs,
922     CORINFO_INTRINSIC_Round,
923     CORINFO_INTRINSIC_Cosh,
924     CORINFO_INTRINSIC_Sinh,
925     CORINFO_INTRINSIC_Tan,
926     CORINFO_INTRINSIC_Tanh,
927     CORINFO_INTRINSIC_Asin,
928     CORINFO_INTRINSIC_Asinh,
929     CORINFO_INTRINSIC_Acos,
930     CORINFO_INTRINSIC_Acosh,
931     CORINFO_INTRINSIC_Atan,
932     CORINFO_INTRINSIC_Atan2,
933     CORINFO_INTRINSIC_Atanh,
934     CORINFO_INTRINSIC_Log10,
935     CORINFO_INTRINSIC_Pow,
936     CORINFO_INTRINSIC_Exp,
937     CORINFO_INTRINSIC_Ceiling,
938     CORINFO_INTRINSIC_Floor,
939     CORINFO_INTRINSIC_GetChar,              // fetch character out of string
940     CORINFO_INTRINSIC_Array_GetDimLength,   // Get number of elements in a given dimension of an array
941     CORINFO_INTRINSIC_Array_Get,            // Get the value of an element in an array
942     CORINFO_INTRINSIC_Array_Address,        // Get the address of an element in an array
943     CORINFO_INTRINSIC_Array_Set,            // Set the value of an element in an array
944     CORINFO_INTRINSIC_StringGetChar,        // fetch character out of string
945     CORINFO_INTRINSIC_StringLength,         // get the length
946     CORINFO_INTRINSIC_InitializeArray,      // initialize an array from static data
947     CORINFO_INTRINSIC_GetTypeFromHandle,
948     CORINFO_INTRINSIC_RTH_GetValueInternal,
949     CORINFO_INTRINSIC_TypeEQ,
950     CORINFO_INTRINSIC_TypeNEQ,
951     CORINFO_INTRINSIC_Object_GetType,
952     CORINFO_INTRINSIC_StubHelpers_GetStubContext,
953     CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr,
954     CORINFO_INTRINSIC_StubHelpers_GetNDirectTarget,
955     CORINFO_INTRINSIC_InterlockedAdd32,
956     CORINFO_INTRINSIC_InterlockedAdd64,
957     CORINFO_INTRINSIC_InterlockedXAdd32,
958     CORINFO_INTRINSIC_InterlockedXAdd64,
959     CORINFO_INTRINSIC_InterlockedXchg32,
960     CORINFO_INTRINSIC_InterlockedXchg64,
961     CORINFO_INTRINSIC_InterlockedCmpXchg32,
962     CORINFO_INTRINSIC_InterlockedCmpXchg64,
963     CORINFO_INTRINSIC_MemoryBarrier,
964     CORINFO_INTRINSIC_GetCurrentManagedThread,
965     CORINFO_INTRINSIC_GetManagedThreadId,
966     CORINFO_INTRINSIC_ByReference_Ctor,
967     CORINFO_INTRINSIC_ByReference_Value,
968     CORINFO_INTRINSIC_Span_GetItem,
969     CORINFO_INTRINSIC_ReadOnlySpan_GetItem,
970     CORINFO_INTRINSIC_GetRawHandle,
971
972     CORINFO_INTRINSIC_Count,
973     CORINFO_INTRINSIC_Illegal = -1,         // Not a true intrinsic,
974 };
975
976 // Can a value be accessed directly from JITed code.
977 enum InfoAccessType
978 {
979     IAT_VALUE,      // The info value is directly available
980     IAT_PVALUE,     // The value needs to be accessed via an         indirection
981     IAT_PPVALUE,    // The value needs to be accessed via a double   indirection
982     IAT_RELPVALUE   // The value needs to be accessed via a relative indirection
983 };
984
985 enum CorInfoGCType
986 {
987     TYPE_GC_NONE,   // no embedded objectrefs
988     TYPE_GC_REF,    // Is an object ref
989     TYPE_GC_BYREF,  // Is an interior pointer - promote it but don't scan it
990     TYPE_GC_OTHER   // requires type-specific treatment
991 };
992
993 enum CorInfoClassId
994 {
995     CLASSID_SYSTEM_OBJECT,
996     CLASSID_TYPED_BYREF,
997     CLASSID_TYPE_HANDLE,
998     CLASSID_FIELD_HANDLE,
999     CLASSID_METHOD_HANDLE,
1000     CLASSID_STRING,
1001     CLASSID_ARGUMENT_HANDLE,
1002     CLASSID_RUNTIME_TYPE,
1003 };
1004
1005 enum CorInfoInline
1006 {
1007     INLINE_PASS                 = 0,    // Inlining OK
1008
1009     // failures are negative
1010     INLINE_FAIL                 = -1,   // Inlining not OK for this case only
1011     INLINE_NEVER                = -2,   // This method should never be inlined, regardless of context
1012 };
1013
1014 enum CorInfoInlineRestrictions
1015 {
1016     INLINE_RESPECT_BOUNDARY = 0x00000001, // You can inline if there are no calls from the method being inlined
1017     INLINE_NO_CALLEE_LDSTR  = 0x00000002, // You can inline only if you guarantee that if inlinee does an ldstr
1018                                           // inlinee's module will never see that string (by any means).
1019                                           // This is due to how we implement the NoStringInterningAttribute
1020                                           // (by reusing the fixup table).
1021     INLINE_SAME_THIS        = 0x00000004, // You can inline only if the callee is on the same this reference as caller
1022 };
1023
1024 enum CorInfoInlineTypeCheck
1025 {
1026     CORINFO_INLINE_TYPECHECK_NONE       = 0x00000000, // It's not okay to compare type's vtable with a native type handle
1027     CORINFO_INLINE_TYPECHECK_PASS       = 0x00000001, // It's okay to compare type's vtable with a native type handle
1028     CORINFO_INLINE_TYPECHECK_USE_HELPER = 0x00000002, // Use a specialized helper to compare type's vtable with native type handle
1029 };
1030
1031 enum CorInfoInlineTypeCheckSource
1032 {
1033     CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE = 0x00000000, // Type handle comes from the vtable
1034     CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN  = 0x00000001, // Type handle comes from an ldtoken
1035 };
1036
1037 // If you add more values here, keep it in sync with TailCallTypeMap in ..\vm\ClrEtwAll.man
1038 // and the string enum in CEEInfo::reportTailCallDecision in ..\vm\JITInterface.cpp
1039 enum CorInfoTailCall
1040 {
1041     TAILCALL_OPTIMIZED      = 0,    // Optimized tail call (epilog + jmp)
1042     TAILCALL_RECURSIVE      = 1,    // Optimized into a loop (only when a method tail calls itself)
1043     TAILCALL_HELPER         = 2,    // Helper assisted tail call (call to JIT_TailCall)
1044
1045     // failures are negative
1046     TAILCALL_FAIL           = -1,   // Couldn't do a tail call
1047 };
1048
1049 enum CorInfoCanSkipVerificationResult
1050 {
1051     CORINFO_VERIFICATION_CANNOT_SKIP    = 0,    // Cannot skip verification during jit time.
1052     CORINFO_VERIFICATION_CAN_SKIP       = 1,    // Can skip verification during jit time.
1053     CORINFO_VERIFICATION_RUNTIME_CHECK  = 2,    // Cannot skip verification during jit time,
1054                                                 //     but need to insert a callout to the VM to ask during runtime 
1055                                                 //     whether to raise a verification or not (if the method is unverifiable).
1056     CORINFO_VERIFICATION_DONT_JIT       = 3,    // Cannot skip verification during jit time,
1057                                                 //     but do not jit the method if is is unverifiable.
1058 };
1059
1060 enum CorInfoInitClassResult
1061 {
1062     CORINFO_INITCLASS_NOT_REQUIRED  = 0x00, // No class initialization required, but the class is not actually initialized yet 
1063                                             // (e.g. we are guaranteed to run the static constructor in method prolog)
1064     CORINFO_INITCLASS_INITIALIZED   = 0x01, // Class initialized
1065     CORINFO_INITCLASS_SPECULATIVE   = 0x02, // Class may be initialized speculatively
1066     CORINFO_INITCLASS_USE_HELPER    = 0x04, // The JIT must insert class initialization helper call.
1067     CORINFO_INITCLASS_DONT_INLINE   = 0x08, // The JIT should not inline the method requesting the class initialization. The class 
1068                                             // initialization requires helper class now, but will not require initialization 
1069                                             // if the method is compiled standalone. Or the method cannot be inlined due to some
1070                                             // requirement around class initialization such as shared generics.
1071 };
1072
1073 // Reason codes for making indirect calls
1074 #define INDIRECT_CALL_REASONS() \
1075     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_UNKNOWN) \
1076     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_EXOTIC) \
1077     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_PINVOKE) \
1078     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_GENERIC) \
1079     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_NO_CODE) \
1080     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_FIXUPS) \
1081     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_STUB) \
1082     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_REMOTING) \
1083     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_CER) \
1084     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_METHOD) \
1085     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_FIRST_CALL) \
1086     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_VALUE_TYPE) \
1087     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE) \
1088     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_CANT_PATCH) \
1089     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_PROFILING) \
1090     INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_OTHER_LOADER_MODULE) \
1091
1092 enum CorInfoIndirectCallReason
1093 {
1094     #undef INDIRECT_CALL_REASON_FUNC
1095     #define INDIRECT_CALL_REASON_FUNC(x) x,
1096     INDIRECT_CALL_REASONS()
1097
1098     #undef INDIRECT_CALL_REASON_FUNC
1099
1100     CORINFO_INDIRECT_CALL_COUNT
1101 };
1102
1103 // This is for use when the JIT is compiling an instantiation
1104 // of generic code.  The JIT needs to know if the generic code itself
1105 // (which can be verified once and for all independently of the
1106 // instantiations) passed verification.
1107 enum CorInfoInstantiationVerification
1108 {
1109     // The method is NOT a concrete instantiation (eg. List<int>.Add()) of a method 
1110     // in a generic class or a generic method. It is either the typical instantiation 
1111     // (eg. List<T>.Add()) or entirely non-generic.
1112     INSTVER_NOT_INSTANTIATION           = 0,
1113
1114     // The method is an instantiation of a method in a generic class or a generic method, 
1115     // and the generic class was successfully verified
1116     INSTVER_GENERIC_PASSED_VERIFICATION = 1,
1117
1118     // The method is an instantiation of a method in a generic class or a generic method, 
1119     // and the generic class failed verification
1120     INSTVER_GENERIC_FAILED_VERIFICATION = 2,
1121 };
1122
1123 // When using CORINFO_HELPER_TAILCALL, the JIT needs to pass certain special
1124 // calling convention/argument passing/handling details to the helper
1125 enum CorInfoHelperTailCallSpecialHandling
1126 {
1127     CORINFO_TAILCALL_NORMAL =               0x00000000,
1128     CORINFO_TAILCALL_STUB_DISPATCH_ARG =    0x00000001,
1129 };
1130
1131
1132 inline bool dontInline(CorInfoInline val) {
1133     return(val < 0);
1134 }
1135
1136 // Cookie types consumed by the code generator (these are opaque values
1137 // not inspected by the code generator):
1138
1139 typedef struct CORINFO_ASSEMBLY_STRUCT_*    CORINFO_ASSEMBLY_HANDLE;
1140 typedef struct CORINFO_MODULE_STRUCT_*      CORINFO_MODULE_HANDLE;
1141 typedef struct CORINFO_DEPENDENCY_STRUCT_*  CORINFO_DEPENDENCY_HANDLE;
1142 typedef struct CORINFO_CLASS_STRUCT_*       CORINFO_CLASS_HANDLE;
1143 typedef struct CORINFO_METHOD_STRUCT_*      CORINFO_METHOD_HANDLE;
1144 typedef struct CORINFO_FIELD_STRUCT_*       CORINFO_FIELD_HANDLE;
1145 typedef struct CORINFO_ARG_LIST_STRUCT_*    CORINFO_ARG_LIST_HANDLE;    // represents a list of argument types
1146 typedef struct CORINFO_JUST_MY_CODE_HANDLE_*CORINFO_JUST_MY_CODE_HANDLE;
1147 typedef struct CORINFO_PROFILING_STRUCT_*   CORINFO_PROFILING_HANDLE;   // a handle guaranteed to be unique per process
1148 typedef struct CORINFO_GENERIC_STRUCT_*     CORINFO_GENERIC_HANDLE;     // a generic handle (could be any of the above)
1149
1150 // what is actually passed on the varargs call
1151 typedef struct CORINFO_VarArgInfo *         CORINFO_VARARGS_HANDLE;
1152
1153 // Generic tokens are resolved with respect to a context, which is usually the method
1154 // being compiled. The CORINFO_CONTEXT_HANDLE indicates which exact instantiation
1155 // (or the open instantiation) is being referred to.
1156 // CORINFO_CONTEXT_HANDLE is more tightly scoped than CORINFO_MODULE_HANDLE. For cases 
1157 // where the exact instantiation does not matter, CORINFO_MODULE_HANDLE is used.
1158 typedef CORINFO_METHOD_HANDLE               CORINFO_CONTEXT_HANDLE;
1159
1160 typedef struct CORINFO_DEPENDENCY_STRUCT_
1161 {
1162     CORINFO_MODULE_HANDLE moduleFrom;
1163     CORINFO_MODULE_HANDLE moduleTo; 
1164 } CORINFO_DEPENDENCY;
1165
1166 // Bit-twiddling of contexts assumes word-alignment of method handles and type handles
1167 // If this ever changes, some other encoding will be needed
1168 enum CorInfoContextFlags
1169 {
1170     CORINFO_CONTEXTFLAGS_METHOD = 0x00, // CORINFO_CONTEXT_HANDLE is really a CORINFO_METHOD_HANDLE
1171     CORINFO_CONTEXTFLAGS_CLASS  = 0x01, // CORINFO_CONTEXT_HANDLE is really a CORINFO_CLASS_HANDLE
1172     CORINFO_CONTEXTFLAGS_MASK   = 0x01
1173 };
1174
1175 #define MAKE_CLASSCONTEXT(c)  (CORINFO_CONTEXT_HANDLE((size_t) (c) | CORINFO_CONTEXTFLAGS_CLASS))
1176 #define MAKE_METHODCONTEXT(m) (CORINFO_CONTEXT_HANDLE((size_t) (m) | CORINFO_CONTEXTFLAGS_METHOD))
1177
1178 enum CorInfoSigInfoFlags
1179 {
1180     CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01,
1181     CORINFO_SIGFLAG_IL_STUB      = 0x02,
1182 };
1183
1184 struct CORINFO_SIG_INST
1185 {
1186     unsigned                classInstCount;
1187     CORINFO_CLASS_HANDLE *  classInst; // (representative, not exact) instantiation for class type variables in signature
1188     unsigned                methInstCount;
1189     CORINFO_CLASS_HANDLE *  methInst; // (representative, not exact) instantiation for method type variables in signature
1190 };
1191
1192 struct CORINFO_SIG_INFO
1193 {
1194     CorInfoCallConv         callConv;
1195     CORINFO_CLASS_HANDLE    retTypeClass;   // if the return type is a value class, this is its handle (enums are normalized)
1196     CORINFO_CLASS_HANDLE    retTypeSigClass;// returns the value class as it is in the sig (enums are not converted to primitives)
1197     CorInfoType             retType : 8;
1198     unsigned                flags   : 8;    // used by IL stubs code
1199     unsigned                numArgs : 16;
1200     struct CORINFO_SIG_INST sigInst;  // information about how type variables are being instantiated in generic code
1201     CORINFO_ARG_LIST_HANDLE args;
1202     PCCOR_SIGNATURE         pSig;
1203     unsigned                cbSig;
1204     CORINFO_MODULE_HANDLE   scope;          // passed to getArgClass
1205     mdToken                 token;
1206
1207     CorInfoCallConv     getCallConv()       { return CorInfoCallConv((callConv & CORINFO_CALLCONV_MASK)); }
1208     bool                hasThis()           { return ((callConv & CORINFO_CALLCONV_HASTHIS) != 0); }
1209     bool                hasExplicitThis()   { return ((callConv & CORINFO_CALLCONV_EXPLICITTHIS) != 0); }
1210     unsigned            totalILArgs()       { return (numArgs + hasThis()); }
1211     bool                isVarArg()          { return ((getCallConv() == CORINFO_CALLCONV_VARARG) || (getCallConv() == CORINFO_CALLCONV_NATIVEVARARG)); }
1212     bool                hasTypeArg()        { return ((callConv & CORINFO_CALLCONV_PARAMTYPE) != 0); }
1213 };
1214
1215 struct CORINFO_METHOD_INFO
1216 {
1217     CORINFO_METHOD_HANDLE       ftn;
1218     CORINFO_MODULE_HANDLE       scope;
1219     BYTE *                      ILCode;
1220     unsigned                    ILCodeSize;
1221     unsigned                    maxStack;
1222     unsigned                    EHcount;
1223     CorInfoOptions              options;
1224     CorInfoRegionKind           regionKind;
1225     CORINFO_SIG_INFO            args;
1226     CORINFO_SIG_INFO            locals;
1227 };
1228
1229 //----------------------------------------------------------------------------
1230 // Looking up handles and addresses.
1231 //
1232 // When the JIT requests a handle, the EE may direct the JIT that it must
1233 // access the handle in a variety of ways.  These are packed as
1234 //    CORINFO_CONST_LOOKUP
1235 // or CORINFO_LOOKUP (contains either a CORINFO_CONST_LOOKUP or a CORINFO_RUNTIME_LOOKUP)
1236 //
1237 // Constant Lookups v. Runtime Lookups (i.e. when will Runtime Lookups be generated?)
1238 // -----------------------------------------------------------------------------------
1239 //
1240 // CORINFO_LOOKUP_KIND is part of the result type of embedGenericHandle,
1241 // getVirtualCallInfo and any other functions that may require a
1242 // runtime lookup when compiling shared generic code.
1243 //
1244 // CORINFO_LOOKUP_KIND indicates whether a particular token in the instruction stream can be:
1245 // (a) Mapped to a handle (type, field or method) at compile-time (!needsRuntimeLookup)
1246 // (b) Must be looked up at run-time, and if so which runtime lookup technique should be used (see below)
1247 //
1248 // If the JIT or EE does not support code sharing for generic code, then
1249 // all CORINFO_LOOKUP results will be "constant lookups", i.e.
1250 // the needsRuntimeLookup of CORINFO_LOOKUP.lookupKind.needsRuntimeLookup
1251 // will be false.
1252 //
1253 // Constant Lookups
1254 // ----------------
1255 //
1256 // Constant Lookups are either:
1257 //     IAT_VALUE: immediate (relocatable) values,
1258 //     IAT_PVALUE: immediate values access via an indirection through an immediate (relocatable) address
1259 //     IAT_RELPVALUE: immediate values access via a relative indirection through an immediate offset
1260 //     IAT_PPVALUE: immediate values access via a double indirection through an immediate (relocatable) address
1261 //
1262 // Runtime Lookups
1263 // ---------------
1264 //
1265 // CORINFO_LOOKUP_KIND is part of the result type of embedGenericHandle,
1266 // getVirtualCallInfo and any other functions that may require a
1267 // runtime lookup when compiling shared generic code.
1268 //
1269 // CORINFO_LOOKUP_KIND indicates whether a particular token in the instruction stream can be:
1270 // (a) Mapped to a handle (type, field or method) at compile-time (!needsRuntimeLookup)
1271 // (b) Must be looked up at run-time using the class dictionary
1272 //     stored in the vtable of the this pointer (needsRuntimeLookup && THISOBJ)
1273 // (c) Must be looked up at run-time using the method dictionary
1274 //     stored in the method descriptor parameter passed to a generic
1275 //     method (needsRuntimeLookup && METHODPARAM)
1276 // (d) Must be looked up at run-time using the class dictionary stored
1277 //     in the vtable parameter passed to a method in a generic
1278 //     struct (needsRuntimeLookup && CLASSPARAM)
1279
1280 struct CORINFO_CONST_LOOKUP
1281 {
1282     // If the handle is obtained at compile-time, then this handle is the "exact" handle (class, method, or field)
1283     // Otherwise, it's a representative... 
1284     // If accessType is
1285     //     IAT_VALUE     --> "handle" stores the real handle or "addr " stores the computed address
1286     //     IAT_PVALUE    --> "addr" stores a pointer to a location which will hold the real handle
1287     //     IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
1288     //     IAT_PPVALUE   --> "addr" stores a double indirection to a location which will hold the real handle
1289
1290     InfoAccessType              accessType;
1291     union
1292     {
1293         CORINFO_GENERIC_HANDLE  handle;
1294         void *                  addr;
1295     };
1296 };
1297
1298 enum CORINFO_RUNTIME_LOOKUP_KIND
1299 {
1300     CORINFO_LOOKUP_THISOBJ,
1301     CORINFO_LOOKUP_METHODPARAM,
1302     CORINFO_LOOKUP_CLASSPARAM,
1303 };
1304
1305 struct CORINFO_LOOKUP_KIND
1306 {
1307     bool                        needsRuntimeLookup;
1308     CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind;
1309
1310     // The 'runtimeLookupFlags' and 'runtimeLookupArgs' fields
1311     // are just for internal VM / ZAP communication, not to be used by the JIT.
1312     WORD                        runtimeLookupFlags;
1313     void *                      runtimeLookupArgs;
1314 } ;
1315
1316
1317 // CORINFO_RUNTIME_LOOKUP indicates the details of the runtime lookup
1318 // operation to be performed.
1319 //
1320 // CORINFO_MAXINDIRECTIONS is the maximum number of
1321 // indirections used by runtime lookups.
1322 // This accounts for up to 2 indirections to get at a dictionary followed by a possible spill slot
1323 //
1324 #define CORINFO_MAXINDIRECTIONS 4
1325 #define CORINFO_USEHELPER ((WORD) 0xffff)
1326
1327 struct CORINFO_RUNTIME_LOOKUP
1328 {
1329     // This is signature you must pass back to the runtime lookup helper
1330     LPVOID                  signature;
1331
1332     // Here is the helper you must call. It is one of CORINFO_HELP_RUNTIMEHANDLE_* helpers.
1333     CorInfoHelpFunc         helper;
1334
1335     // Number of indirections to get there
1336     // CORINFO_USEHELPER = don't know how to get it, so use helper function at run-time instead
1337     // 0 = use the this pointer itself (e.g. token is C<!0> inside code in sealed class C)
1338     //     or method desc itself (e.g. token is method void M::mymeth<!!0>() inside code in M::mymeth)
1339     // Otherwise, follow each byte-offset stored in the "offsets[]" array (may be negative)
1340     WORD                    indirections;
1341
1342     // If set, test for null and branch to helper if null
1343     bool                    testForNull;
1344
1345     // If set, test the lowest bit and dereference if set (see code:FixupPointer)
1346     bool                    testForFixup;
1347
1348     SIZE_T                  offsets[CORINFO_MAXINDIRECTIONS];
1349
1350     // If set, first offset is indirect.
1351     // 0 means that value stored at first offset (offsets[0]) from pointer is next pointer, to which the next offset
1352     // (offsets[1]) is added and so on.
1353     // 1 means that value stored at first offset (offsets[0]) from pointer is offset1, and the next pointer is
1354     // stored at pointer+offsets[0]+offset1.
1355     bool                indirectFirstOffset;
1356
1357     // If set, second offset is indirect.
1358     // 0 means that value stored at second offset (offsets[1]) from pointer is next pointer, to which the next offset
1359     // (offsets[2]) is added and so on.
1360     // 1 means that value stored at second offset (offsets[1]) from pointer is offset2, and the next pointer is
1361     // stored at pointer+offsets[1]+offset2.
1362     bool                indirectSecondOffset;
1363 } ;
1364
1365 // Result of calling embedGenericHandle
1366 struct CORINFO_LOOKUP
1367 {
1368     CORINFO_LOOKUP_KIND     lookupKind;
1369
1370     union
1371     {
1372         // If kind.needsRuntimeLookup then this indicates how to do the lookup
1373         CORINFO_RUNTIME_LOOKUP  runtimeLookup;
1374
1375         // If the handle is obtained at compile-time, then this handle is the "exact" handle (class, method, or field)
1376         // Otherwise, it's a representative...  If accessType is
1377         //     IAT_VALUE --> "handle" stores the real handle or "addr " stores the computed address
1378         //     IAT_PVALUE --> "addr" stores a pointer to a location which will hold the real handle
1379         //     IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
1380         //     IAT_PPVALUE --> "addr" stores a double indirection to a location which will hold the real handle
1381         CORINFO_CONST_LOOKUP    constLookup;
1382     };
1383 };
1384
1385 enum CorInfoGenericHandleType
1386 {
1387     CORINFO_HANDLETYPE_UNKNOWN,
1388     CORINFO_HANDLETYPE_CLASS,
1389     CORINFO_HANDLETYPE_METHOD,
1390     CORINFO_HANDLETYPE_FIELD
1391 };
1392
1393 //----------------------------------------------------------------------------
1394 // Embedding type, method and field handles (for "ldtoken" or to pass back to helpers)
1395
1396 // Result of calling embedGenericHandle
1397 struct CORINFO_GENERICHANDLE_RESULT
1398 {
1399     CORINFO_LOOKUP          lookup;
1400
1401     // compileTimeHandle is guaranteed to be either NULL or a handle that is usable during compile time.
1402     // It must not be embedded in the code because it might not be valid at run-time.
1403     CORINFO_GENERIC_HANDLE  compileTimeHandle;
1404
1405     // Type of the result
1406     CorInfoGenericHandleType handleType;
1407 };
1408
1409 #define CORINFO_ACCESS_ALLOWED_MAX_ARGS 4
1410
1411 enum CorInfoAccessAllowedHelperArgType
1412 {
1413     CORINFO_HELPER_ARG_TYPE_Invalid = 0,
1414     CORINFO_HELPER_ARG_TYPE_Field   = 1,
1415     CORINFO_HELPER_ARG_TYPE_Method  = 2,
1416     CORINFO_HELPER_ARG_TYPE_Class   = 3,
1417     CORINFO_HELPER_ARG_TYPE_Module  = 4,
1418     CORINFO_HELPER_ARG_TYPE_Const   = 5,
1419 };
1420 struct CORINFO_HELPER_ARG
1421 {
1422     union
1423     {
1424         CORINFO_FIELD_HANDLE fieldHandle;
1425         CORINFO_METHOD_HANDLE methodHandle;
1426         CORINFO_CLASS_HANDLE classHandle;
1427         CORINFO_MODULE_HANDLE moduleHandle;
1428         size_t constant;
1429     };
1430     CorInfoAccessAllowedHelperArgType argType;
1431
1432     void Set(CORINFO_METHOD_HANDLE handle)
1433     {
1434         argType = CORINFO_HELPER_ARG_TYPE_Method;
1435         methodHandle = handle;
1436     }
1437
1438     void Set(CORINFO_FIELD_HANDLE handle)
1439     {
1440         argType = CORINFO_HELPER_ARG_TYPE_Field;
1441         fieldHandle = handle;
1442     }
1443
1444     void Set(CORINFO_CLASS_HANDLE handle)
1445     {
1446         argType = CORINFO_HELPER_ARG_TYPE_Class;
1447         classHandle = handle;
1448     }
1449
1450     void Set(size_t value)
1451     {
1452         argType = CORINFO_HELPER_ARG_TYPE_Const;
1453         constant = value;
1454     }
1455 };
1456
1457 struct CORINFO_HELPER_DESC
1458 {
1459     CorInfoHelpFunc helperNum;
1460     unsigned numArgs;
1461     CORINFO_HELPER_ARG args[CORINFO_ACCESS_ALLOWED_MAX_ARGS];
1462 };
1463
1464 //----------------------------------------------------------------------------
1465 // getCallInfo and CORINFO_CALL_INFO: The EE instructs the JIT about how to make a call
1466 //
1467 // callKind
1468 // --------
1469 //
1470 // CORINFO_CALL :
1471 //   Indicates that the JIT can use getFunctionEntryPoint to make a call,
1472 //   i.e. there is nothing abnormal about the call.  The JITs know what to do if they get this.
1473 //   Except in the case of constraint calls (see below), [targetMethodHandle] will hold
1474 //   the CORINFO_METHOD_HANDLE that a call to findMethod would
1475 //   have returned.
1476 //   This flag may be combined with nullInstanceCheck=TRUE for uses of callvirt on methods that can
1477 //   be resolved at compile-time (non-virtual, final or sealed).
1478 //
1479 // CORINFO_CALL_CODE_POINTER (shared generic code only) :
1480 //   Indicates that the JIT should do an indirect call to the entrypoint given by address, which may be specified
1481 //   as a runtime lookup by CORINFO_CALL_INFO::codePointerLookup.
1482 //   [targetMethodHandle] will not hold a valid value.
1483 //   This flag may be combined with nullInstanceCheck=TRUE for uses of callvirt on methods whose target method can
1484 //   be resolved at compile-time but whose instantiation can be resolved only through runtime lookup.
1485 //
1486 // CORINFO_VIRTUALCALL_STUB (interface calls) :
1487 //   Indicates that the EE supports "stub dispatch" and request the JIT to make a
1488 //   "stub dispatch" call (an indirect call through CORINFO_CALL_INFO::stubLookup,
1489 //   similar to CORINFO_CALL_CODE_POINTER).
1490 //   "Stub dispatch" is a specialized calling sequence (that may require use of NOPs)
1491 //   which allow the runtime to determine the call-site after the call has been dispatched.
1492 //   If the call is too complex for the JIT (e.g. because
1493 //   fetching the dispatch stub requires a runtime lookup, i.e. lookupKind.needsRuntimeLookup
1494 //   is set) then the JIT is allowed to implement the call as if it were CORINFO_VIRTUALCALL_LDVIRTFTN
1495 //   [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1496 //   have returned.
1497 //   This flag is always accompanied by nullInstanceCheck=TRUE.
1498 //
1499 // CORINFO_VIRTUALCALL_LDVIRTFTN (virtual generic methods) :
1500 //   Indicates that the EE provides no way to implement the call directly and
1501 //   that the JIT should use a LDVIRTFTN sequence (as implemented by CORINFO_HELP_VIRTUAL_FUNC_PTR)
1502 //   followed by an indirect call.
1503 //   [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1504 //   have returned.
1505 //   This flag is always accompanied by nullInstanceCheck=TRUE though typically the null check will
1506 //   be implicit in the access through the instance pointer.
1507 //
1508 //  CORINFO_VIRTUALCALL_VTABLE (regular virtual methods) :
1509 //   Indicates that the EE supports vtable dispatch and that the JIT should use getVTableOffset etc.
1510 //   to implement the call.
1511 //   [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1512 //   have returned.
1513 //   This flag is always accompanied by nullInstanceCheck=TRUE though typically the null check will
1514 //   be implicit in the access through the instance pointer.
1515 //
1516 // thisTransform and constraint calls
1517 // ----------------------------------
1518 //
1519 // For evertyhing besides "constrained." calls "thisTransform" is set to
1520 // CORINFO_NO_THIS_TRANSFORM.
1521 //
1522 // For "constrained." calls the EE attempts to resolve the call at compile
1523 // time to a more specific method, or (shared generic code only) to a runtime lookup
1524 // for a code pointer for the more specific method.
1525 //
1526 // In order to permit this, the "this" pointer supplied for a "constrained." call
1527 // is a byref to an arbitrary type (see the IL spec). The "thisTransform" field
1528 // will indicate how the JIT must transform the "this" pointer in order
1529 // to be able to call the resolved method:
1530 //
1531 //  CORINFO_NO_THIS_TRANSFORM --> Leave it as a byref to an unboxed value type
1532 //  CORINFO_BOX_THIS          --> Box it to produce an object
1533 //  CORINFO_DEREF_THIS        --> Deref the byref to get an object reference
1534 //
1535 // In addition, the "kind" field will be set as follows for constraint calls:
1536
1537 //    CORINFO_CALL              --> the call was resolved at compile time, and
1538 //                                  can be compiled like a normal call.
1539 //    CORINFO_CALL_CODE_POINTER --> the call was resolved, but the target address will be
1540 //                                  computed at runtime.  Only returned for shared generic code.
1541 //    CORINFO_VIRTUALCALL_STUB,
1542 //    CORINFO_VIRTUALCALL_LDVIRTFTN,
1543 //    CORINFO_VIRTUALCALL_VTABLE   --> usual values indicating that a virtual call must be made
1544
1545 enum CORINFO_CALL_KIND
1546 {
1547     CORINFO_CALL,
1548     CORINFO_CALL_CODE_POINTER,
1549     CORINFO_VIRTUALCALL_STUB,
1550     CORINFO_VIRTUALCALL_LDVIRTFTN,
1551     CORINFO_VIRTUALCALL_VTABLE
1552 };
1553
1554 // Indicates that the CORINFO_VIRTUALCALL_VTABLE lookup needn't do a chunk indirection
1555 #define CORINFO_VIRTUALCALL_NO_CHUNK 0xFFFFFFFF
1556
1557 enum CORINFO_THIS_TRANSFORM
1558 {
1559     CORINFO_NO_THIS_TRANSFORM,
1560     CORINFO_BOX_THIS,
1561     CORINFO_DEREF_THIS
1562 };
1563
1564 enum CORINFO_CALLINFO_FLAGS
1565 {
1566     CORINFO_CALLINFO_NONE           = 0x0000,
1567     CORINFO_CALLINFO_ALLOWINSTPARAM = 0x0001,   // Can the compiler generate code to pass an instantiation parameters? Simple compilers should not use this flag
1568     CORINFO_CALLINFO_CALLVIRT       = 0x0002,   // Is it a virtual call?
1569     CORINFO_CALLINFO_KINDONLY       = 0x0004,   // This is set to only query the kind of call to perform, without getting any other information
1570     CORINFO_CALLINFO_VERIFICATION   = 0x0008,   // Gets extra verification information.
1571     CORINFO_CALLINFO_SECURITYCHECKS = 0x0010,   // Perform security checks.
1572     CORINFO_CALLINFO_LDFTN          = 0x0020,   // Resolving target of LDFTN
1573     CORINFO_CALLINFO_ATYPICAL_CALLSITE = 0x0040, // Atypical callsite that cannot be disassembled by delay loading helper
1574 };
1575
1576 enum CorInfoIsAccessAllowedResult
1577 {
1578     CORINFO_ACCESS_ALLOWED = 0,           // Call allowed
1579     CORINFO_ACCESS_ILLEGAL = 1,           // Call not allowed
1580     CORINFO_ACCESS_RUNTIME_CHECK = 2,     // Ask at runtime whether to allow the call or not
1581 };
1582
1583
1584 // This enum is used for JIT to tell EE where this token comes from.
1585 // E.g. Depending on different opcodes, we might allow/disallow certain types of tokens or 
1586 // return different types of handles (e.g. boxed vs. regular entrypoints)
1587 enum CorInfoTokenKind
1588 {
1589     CORINFO_TOKENKIND_Class     = 0x01,
1590     CORINFO_TOKENKIND_Method    = 0x02,
1591     CORINFO_TOKENKIND_Field     = 0x04,
1592     CORINFO_TOKENKIND_Mask      = 0x07,
1593
1594     // token comes from CEE_LDTOKEN
1595     CORINFO_TOKENKIND_Ldtoken   = 0x10 | CORINFO_TOKENKIND_Class | CORINFO_TOKENKIND_Method | CORINFO_TOKENKIND_Field,
1596
1597     // token comes from CEE_CASTCLASS or CEE_ISINST
1598     CORINFO_TOKENKIND_Casting   = 0x20 | CORINFO_TOKENKIND_Class,
1599
1600     // token comes from CEE_NEWARR
1601     CORINFO_TOKENKIND_Newarr    = 0x40 | CORINFO_TOKENKIND_Class,
1602
1603     // token comes from CEE_BOX
1604     CORINFO_TOKENKIND_Box       = 0x80 | CORINFO_TOKENKIND_Class,
1605
1606     // token comes from CEE_CONSTRAINED
1607     CORINFO_TOKENKIND_Constrained = 0x100 | CORINFO_TOKENKIND_Class,
1608
1609     // token comes from CEE_NEWOBJ
1610     CORINFO_TOKENKIND_NewObj    = 0x200 | CORINFO_TOKENKIND_Method,
1611
1612     // token comes from CEE_LDVIRTFTN
1613     CORINFO_TOKENKIND_Ldvirtftn = 0x400 | CORINFO_TOKENKIND_Method,
1614 };
1615
1616 struct CORINFO_RESOLVED_TOKEN
1617 {
1618     //
1619     // [In] arguments of resolveToken
1620     //
1621     CORINFO_CONTEXT_HANDLE  tokenContext;       //Context for resolution of generic arguments
1622     CORINFO_MODULE_HANDLE   tokenScope;
1623     mdToken                 token;              //The source token
1624     CorInfoTokenKind        tokenType;
1625
1626     //
1627     // [Out] arguments of resolveToken. 
1628     // - Type handle is always non-NULL.
1629     // - At most one of method and field handles is non-NULL (according to the token type).
1630     // - Method handle is an instantiating stub only for generic methods. Type handle 
1631     //   is required to provide the full context for methods in generic types.
1632     //
1633     CORINFO_CLASS_HANDLE    hClass;
1634     CORINFO_METHOD_HANDLE   hMethod;
1635     CORINFO_FIELD_HANDLE    hField;
1636
1637     //
1638     // [Out] TypeSpec and MethodSpec signatures for generics. NULL otherwise.
1639     //
1640     PCCOR_SIGNATURE         pTypeSpec;
1641     ULONG                   cbTypeSpec;
1642     PCCOR_SIGNATURE         pMethodSpec;
1643     ULONG                   cbMethodSpec;
1644 };
1645
1646 struct CORINFO_CALL_INFO
1647 {
1648     CORINFO_METHOD_HANDLE   hMethod;            //target method handle
1649     unsigned                methodFlags;        //flags for the target method
1650
1651     unsigned                classFlags;         //flags for CORINFO_RESOLVED_TOKEN::hClass
1652
1653     CORINFO_SIG_INFO       sig;
1654
1655     //Verification information
1656     unsigned                verMethodFlags;     // flags for CORINFO_RESOLVED_TOKEN::hMethod
1657     CORINFO_SIG_INFO        verSig;
1658     //All of the regular method data is the same... hMethod might not be the same as CORINFO_RESOLVED_TOKEN::hMethod
1659
1660
1661     //If set to:
1662     //  - CORINFO_ACCESS_ALLOWED - The access is allowed.
1663     //  - CORINFO_ACCESS_ILLEGAL - This access cannot be allowed (i.e. it is public calling private).  The
1664     //      JIT may either insert the callsiteCalloutHelper into the code (as per a verification error) or
1665     //      call throwExceptionFromHelper on the callsiteCalloutHelper.  In this case callsiteCalloutHelper
1666     //      is guaranteed not to return.
1667     //  - CORINFO_ACCESS_RUNTIME_CHECK - The jit must insert the callsiteCalloutHelper at the call site.
1668     //      the helper may return
1669     CorInfoIsAccessAllowedResult accessAllowed;
1670     CORINFO_HELPER_DESC     callsiteCalloutHelper;
1671
1672     // See above section on constraintCalls to understand when these are set to unusual values.
1673     CORINFO_THIS_TRANSFORM  thisTransform;
1674
1675     CORINFO_CALL_KIND       kind;
1676     BOOL                    nullInstanceCheck;
1677
1678     // Context for inlining and hidden arg
1679     CORINFO_CONTEXT_HANDLE  contextHandle;
1680     BOOL                    exactContextNeedsRuntimeLookup; // Set if contextHandle is approx handle. Runtime lookup is required to get the exact handle.
1681
1682     // If kind.CORINFO_VIRTUALCALL_STUB then stubLookup will be set.
1683     // If kind.CORINFO_CALL_CODE_POINTER then entryPointLookup will be set.
1684     union
1685     {
1686         CORINFO_LOOKUP      stubLookup;
1687
1688         CORINFO_LOOKUP      codePointerLookup;
1689     };
1690
1691     CORINFO_CONST_LOOKUP    instParamLookup;    // Used by Ready-to-Run
1692
1693     BOOL                    secureDelegateInvoke;
1694 };
1695
1696 //----------------------------------------------------------------------------
1697 // getFieldInfo and CORINFO_FIELD_INFO: The EE instructs the JIT about how to access a field
1698
1699 enum CORINFO_FIELD_ACCESSOR
1700 {
1701     CORINFO_FIELD_INSTANCE,                 // regular instance field at given offset from this-ptr
1702     CORINFO_FIELD_INSTANCE_WITH_BASE,       // instance field with base offset (used by Ready-to-Run)
1703     CORINFO_FIELD_INSTANCE_HELPER,          // instance field accessed using helper (arguments are this, FieldDesc * and the value)
1704     CORINFO_FIELD_INSTANCE_ADDR_HELPER,     // instance field accessed using address-of helper (arguments are this and FieldDesc *)
1705
1706     CORINFO_FIELD_STATIC_ADDRESS,           // field at given address
1707     CORINFO_FIELD_STATIC_RVA_ADDRESS,       // RVA field at given address
1708     CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER, // static field accessed using the "shared static" helper (arguments are ModuleID + ClassID)
1709     CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER, // static field access using the "generic static" helper (argument is MethodTable *)
1710     CORINFO_FIELD_STATIC_ADDR_HELPER,       // static field accessed using address-of helper (argument is FieldDesc *)
1711     CORINFO_FIELD_STATIC_TLS,               // unmanaged TLS access
1712     CORINFO_FIELD_STATIC_READYTORUN_HELPER, // static field access using a runtime lookup helper
1713
1714     CORINFO_FIELD_INTRINSIC_ZERO,           // intrinsic zero (IntPtr.Zero, UIntPtr.Zero)
1715     CORINFO_FIELD_INTRINSIC_EMPTY_STRING,   // intrinsic emptry string (String.Empty)
1716     CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN, // intrinsic BitConverter.IsLittleEndian
1717 };
1718
1719 // Set of flags returned in CORINFO_FIELD_INFO::fieldFlags
1720 enum CORINFO_FIELD_FLAGS
1721 {
1722     CORINFO_FLG_FIELD_STATIC                    = 0x00000001,
1723     CORINFO_FLG_FIELD_UNMANAGED                 = 0x00000002, // RVA field
1724     CORINFO_FLG_FIELD_FINAL                     = 0x00000004,
1725     CORINFO_FLG_FIELD_STATIC_IN_HEAP            = 0x00000008, // See code:#StaticFields. This static field is in the GC heap as a boxed object
1726     CORINFO_FLG_FIELD_SAFESTATIC_BYREF_RETURN   = 0x00000010, // Field can be returned safely (has GC heap lifetime)
1727     CORINFO_FLG_FIELD_INITCLASS                 = 0x00000020, // initClass has to be called before accessing the field
1728     CORINFO_FLG_FIELD_PROTECTED                 = 0x00000040,
1729 };
1730
1731 struct CORINFO_FIELD_INFO
1732 {
1733     CORINFO_FIELD_ACCESSOR  fieldAccessor;
1734     unsigned                fieldFlags;
1735
1736     // Helper to use if the field access requires it
1737     CorInfoHelpFunc         helper;
1738
1739     // Field offset if there is one
1740     DWORD                   offset;
1741
1742     CorInfoType             fieldType;
1743     CORINFO_CLASS_HANDLE    structType; //possibly null
1744
1745     //See CORINFO_CALL_INFO.accessAllowed
1746     CorInfoIsAccessAllowedResult accessAllowed;
1747     CORINFO_HELPER_DESC     accessCalloutHelper;
1748
1749     CORINFO_CONST_LOOKUP    fieldLookup;        // Used by Ready-to-Run
1750 };
1751
1752 //----------------------------------------------------------------------------
1753 // Exception handling
1754
1755 struct CORINFO_EH_CLAUSE
1756 {
1757     CORINFO_EH_CLAUSE_FLAGS     Flags;
1758     DWORD                       TryOffset;
1759     DWORD                       TryLength;
1760     DWORD                       HandlerOffset;
1761     DWORD                       HandlerLength;
1762     union
1763     {
1764         DWORD                   ClassToken;       // use for type-based exception handlers
1765         DWORD                   FilterOffset;     // use for filter-based exception handlers (COR_ILEXCEPTION_FILTER is set)
1766     };
1767 };
1768
1769 enum CORINFO_OS
1770 {
1771     CORINFO_WINNT,
1772     CORINFO_PAL,
1773 };
1774
1775 struct CORINFO_CPU
1776 {
1777     DWORD           dwCPUType;
1778     DWORD           dwFeatures;
1779     DWORD           dwExtendedFeatures;
1780 };
1781
1782 enum CORINFO_RUNTIME_ABI
1783 {
1784     CORINFO_DESKTOP_ABI = 0x100,
1785     CORINFO_CORECLR_ABI = 0x200,
1786     CORINFO_CORERT_ABI = 0x300,
1787 };
1788
1789 // For some highly optimized paths, the JIT must generate code that directly
1790 // manipulates internal EE data structures. The getEEInfo() helper returns
1791 // this structure containing the needed offsets and values.
1792 struct CORINFO_EE_INFO
1793 {
1794     // Information about the InlinedCallFrame structure layout
1795     struct InlinedCallFrameInfo
1796     {
1797         // Size of the Frame structure
1798         unsigned    size;
1799
1800         unsigned    offsetOfGSCookie;
1801         unsigned    offsetOfFrameVptr;
1802         unsigned    offsetOfFrameLink;
1803         unsigned    offsetOfCallSiteSP;
1804         unsigned    offsetOfCalleeSavedFP;
1805         unsigned    offsetOfCallTarget;
1806         unsigned    offsetOfReturnAddress;
1807     }
1808     inlinedCallFrameInfo;
1809
1810     // Offsets into the Thread structure
1811     unsigned    offsetOfThreadFrame;            // offset of the current Frame
1812     unsigned    offsetOfGCState;                // offset of the preemptive/cooperative state of the Thread
1813
1814     // Delegate offsets
1815     unsigned    offsetOfDelegateInstance;
1816     unsigned    offsetOfDelegateFirstTarget;
1817
1818     // Secure delegate offsets
1819     unsigned    offsetOfSecureDelegateIndirectCell;
1820
1821     // Remoting offsets
1822     unsigned    offsetOfTransparentProxyRP;
1823     unsigned    offsetOfRealProxyServer;
1824
1825     // Array offsets
1826     unsigned    offsetOfObjArrayData;
1827
1828     // Reverse PInvoke offsets
1829     unsigned    sizeOfReversePInvokeFrame;
1830
1831     // OS Page size
1832     size_t      osPageSize;
1833
1834     // Null object offset
1835     size_t      maxUncheckedOffsetForNullObject;
1836
1837     // Target ABI. Combined with target architecture and OS to determine
1838     // GC, EH, and unwind styles.
1839     CORINFO_RUNTIME_ABI targetAbi;
1840
1841     CORINFO_OS  osType;
1842     unsigned    osMajor;
1843     unsigned    osMinor;
1844     unsigned    osBuild;
1845 };
1846
1847 // This is used to indicate that a finally has been called 
1848 // "locally" by the try block
1849 enum { LCL_FINALLY_MARK = 0xFC }; // FC = "Finally Call"
1850
1851 /**********************************************************************************
1852  * The following is the internal structure of an object that the compiler knows about
1853  * when it generates code
1854  **********************************************************************************/
1855
1856 #include <pshpack4.h>
1857
1858 typedef void* CORINFO_MethodPtr;            // a generic method pointer
1859
1860 struct CORINFO_Object
1861 {
1862     CORINFO_MethodPtr      *methTable;      // the vtable for the object
1863 };
1864
1865 struct CORINFO_String : public CORINFO_Object
1866 {
1867     unsigned                stringLen;
1868     wchar_t                 chars[1];       // actually of variable size
1869 };
1870
1871 struct CORINFO_Array : public CORINFO_Object
1872 {
1873     unsigned                length;
1874 #ifdef _WIN64
1875     unsigned                alignpad;
1876 #endif // _WIN64
1877
1878 #if 0
1879     /* Multi-dimensional arrays have the lengths and bounds here */
1880     unsigned                dimLength[length];
1881     unsigned                dimBound[length];
1882 #endif
1883
1884     union
1885     {
1886         __int8              i1Elems[1];    // actually of variable size
1887         unsigned __int8     u1Elems[1];
1888         __int16             i2Elems[1];
1889         unsigned __int16    u2Elems[1];
1890         __int32             i4Elems[1];
1891         unsigned __int32    u4Elems[1];
1892         float               r4Elems[1];
1893     };
1894 };
1895
1896 #include <pshpack4.h>
1897 struct CORINFO_Array8 : public CORINFO_Object
1898 {
1899     unsigned                length;
1900 #ifdef _WIN64
1901     unsigned                alignpad;
1902 #endif // _WIN64
1903
1904     union
1905     {
1906         double              r8Elems[1];
1907         __int64             i8Elems[1];
1908         unsigned __int64    u8Elems[1];
1909     };
1910 };
1911
1912 #include <poppack.h>
1913
1914 struct CORINFO_RefArray : public CORINFO_Object
1915 {
1916     unsigned                length;
1917 #ifdef _WIN64
1918     unsigned                alignpad;
1919 #endif // _WIN64
1920
1921 #if 0
1922     /* Multi-dimensional arrays have the lengths and bounds here */
1923     unsigned                dimLength[length];
1924     unsigned                dimBound[length];
1925 #endif
1926
1927     CORINFO_Object*         refElems[1];    // actually of variable size;
1928 };
1929
1930 struct CORINFO_RefAny
1931 {
1932     void                      * dataPtr;
1933     CORINFO_CLASS_HANDLE        type;
1934 };
1935
1936 // The jit assumes the CORINFO_VARARGS_HANDLE is a pointer to a subclass of this
1937 struct CORINFO_VarArgInfo
1938 {
1939     unsigned                argBytes;       // number of bytes the arguments take up.
1940                                             // (The CORINFO_VARARGS_HANDLE counts as an arg)
1941 };
1942
1943 #include <poppack.h>
1944
1945 #define SIZEOF__CORINFO_Object                            TARGET_POINTER_SIZE /* methTable */
1946
1947 #define OFFSETOF__CORINFO_Array__length                   SIZEOF__CORINFO_Object
1948 #ifdef _TARGET_64BIT_
1949 #define OFFSETOF__CORINFO_Array__data                     (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */ + sizeof(unsigned __int32) /* alignpad */)
1950 #else
1951 #define OFFSETOF__CORINFO_Array__data                     (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */)
1952 #endif
1953
1954 #define OFFSETOF__CORINFO_TypedReference__dataPtr         0
1955 #define OFFSETOF__CORINFO_TypedReference__type            (OFFSETOF__CORINFO_TypedReference__dataPtr + TARGET_POINTER_SIZE /* dataPtr */)
1956
1957 #define OFFSETOF__CORINFO_String__stringLen               SIZEOF__CORINFO_Object
1958 #define OFFSETOF__CORINFO_String__chars                   (OFFSETOF__CORINFO_String__stringLen + sizeof(unsigned __int32) /* stringLen */)
1959
1960 enum CorInfoSecurityRuntimeChecks
1961 {
1962     CORINFO_ACCESS_SECURITY_NONE                          = 0,
1963     CORINFO_ACCESS_SECURITY_TRANSPARENCY                  = 0x0001  // check that transparency rules are enforced between the caller and callee
1964 };
1965
1966
1967 /* data to optimize delegate construction */
1968 struct DelegateCtorArgs
1969 {
1970     void * pMethod;
1971     void * pArg3;
1972     void * pArg4;
1973     void * pArg5;
1974 };
1975
1976 // use offsetof to get the offset of the fields above
1977 #include <stddef.h> // offsetof
1978
1979 // Guard-stack cookie for preventing against stack buffer overruns
1980 typedef SIZE_T GSCookie;
1981
1982 #include "cordebuginfo.h"
1983
1984 /**********************************************************************************/
1985 // Some compilers cannot arbitrarily allow the handler nesting level to grow
1986 // arbitrarily during Edit'n'Continue.
1987 // This is the maximum nesting level that a compiler needs to support for EnC
1988
1989 const int MAX_EnC_HANDLER_NESTING_LEVEL = 6;
1990
1991 // Results from type comparison queries
1992 enum class TypeCompareState
1993 {
1994     MustNot = -1, // types are not equal
1995     May = 0,      // types may be equal (must test at runtime)
1996     Must = 1,     // type are equal
1997 };
1998
1999 //
2000 // This interface is logically split into sections for each class of information 
2001 // (ICorMethodInfo, ICorModuleInfo, etc.). This split used to exist physically as well
2002 // using virtual inheritance, but was eliminated to improve efficiency of the JIT-EE 
2003 // interface calls.
2004 //
2005 class ICorStaticInfo
2006 {
2007 public:
2008     /**********************************************************************************/
2009     //
2010     // ICorMethodInfo
2011     //
2012     /**********************************************************************************/
2013
2014     // return flags (defined above, CORINFO_FLG_PUBLIC ...)
2015     virtual DWORD getMethodAttribs (
2016             CORINFO_METHOD_HANDLE       ftn         /* IN */
2017             ) = 0;
2018
2019     // sets private JIT flags, which can be, retrieved using getAttrib.
2020     virtual void setMethodAttribs (
2021             CORINFO_METHOD_HANDLE       ftn,        /* IN */
2022             CorInfoMethodRuntimeFlags   attribs     /* IN */
2023             ) = 0;
2024
2025     // Given a method descriptor ftnHnd, extract signature information into sigInfo
2026     //
2027     // 'memberParent' is typically only set when verifying.  It should be the
2028     // result of calling getMemberParent.
2029     virtual void getMethodSig (
2030              CORINFO_METHOD_HANDLE      ftn,        /* IN  */
2031              CORINFO_SIG_INFO          *sig,        /* OUT */
2032              CORINFO_CLASS_HANDLE      memberParent = NULL /* IN */
2033              ) = 0;
2034
2035     /*********************************************************************
2036      * Note the following methods can only be used on functions known
2037      * to be IL.  This includes the method being compiled and any method
2038      * that 'getMethodInfo' returns true for
2039      *********************************************************************/
2040
2041     // return information about a method private to the implementation
2042     //      returns false if method is not IL, or is otherwise unavailable.
2043     //      This method is used to fetch data needed to inline functions
2044     virtual bool getMethodInfo (
2045             CORINFO_METHOD_HANDLE   ftn,            /* IN  */
2046             CORINFO_METHOD_INFO*    info            /* OUT */
2047             ) = 0;
2048
2049     // Decides if you have any limitations for inlining. If everything's OK, it will return
2050     // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this
2051     // function must respect. If caller passes pRestrictions = NULL, if there are any restrictions
2052     // INLINE_FAIL will be returned
2053     //
2054     // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
2055     //
2056     // The inlined method need not be verified
2057
2058     virtual CorInfoInline canInline (
2059             CORINFO_METHOD_HANDLE       callerHnd,                  /* IN  */
2060             CORINFO_METHOD_HANDLE       calleeHnd,                  /* IN  */
2061             DWORD*                      pRestrictions               /* OUT */
2062             ) = 0;
2063
2064     // Reports whether or not a method can be inlined, and why.  canInline is responsible for reporting all
2065     // inlining results when it returns INLINE_FAIL and INLINE_NEVER.  All other results are reported by the
2066     // JIT.
2067     virtual void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
2068                                                    CORINFO_METHOD_HANDLE inlineeHnd,
2069                                                    CorInfoInline inlineResult,
2070                                                    const char * reason) = 0;
2071
2072
2073     // Returns false if the call is across security boundaries thus we cannot tailcall
2074     //
2075     // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
2076     virtual bool canTailCall (
2077             CORINFO_METHOD_HANDLE   callerHnd,          /* IN */
2078             CORINFO_METHOD_HANDLE   declaredCalleeHnd,  /* IN */
2079             CORINFO_METHOD_HANDLE   exactCalleeHnd,     /* IN */
2080             bool fIsTailPrefix                          /* IN */
2081             ) = 0;
2082
2083     // Reports whether or not a method can be tail called, and why.
2084     // canTailCall is responsible for reporting all results when it returns
2085     // false.  All other results are reported by the JIT.
2086     virtual void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
2087                                                    CORINFO_METHOD_HANDLE calleeHnd,
2088                                                    bool fIsTailPrefix,
2089                                                    CorInfoTailCall tailCallResult,
2090                                                    const char * reason) = 0;
2091
2092     // get individual exception handler
2093     virtual void getEHinfo(
2094             CORINFO_METHOD_HANDLE ftn,              /* IN  */
2095             unsigned          EHnumber,             /* IN */
2096             CORINFO_EH_CLAUSE* clause               /* OUT */
2097             ) = 0;
2098
2099     // return class it belongs to
2100     virtual CORINFO_CLASS_HANDLE getMethodClass (
2101             CORINFO_METHOD_HANDLE       method
2102             ) = 0;
2103
2104     // return module it belongs to
2105     virtual CORINFO_MODULE_HANDLE getMethodModule (
2106             CORINFO_METHOD_HANDLE       method
2107             ) = 0;
2108
2109     // This function returns the offset of the specified method in the
2110     // vtable of it's owning class or interface.
2111     virtual void getMethodVTableOffset (
2112             CORINFO_METHOD_HANDLE       method,                 /* IN */
2113             unsigned*                   offsetOfIndirection,    /* OUT */
2114             unsigned*                   offsetAfterIndirection, /* OUT */
2115             bool*                       isRelative              /* OUT */
2116             ) = 0;
2117
2118     // Find the virtual method in implementingClass that overrides virtualMethod,
2119     // or the method in implementingClass that implements the interface method
2120     // represented by virtualMethod.
2121     //
2122     // Return null if devirtualization is not possible. Owner type is optional
2123     // and provides additional context for shared interface devirtualization.
2124     virtual CORINFO_METHOD_HANDLE resolveVirtualMethod(
2125             CORINFO_METHOD_HANDLE       virtualMethod,          /* IN */
2126             CORINFO_CLASS_HANDLE        implementingClass,      /* IN */
2127             CORINFO_CONTEXT_HANDLE      ownerType = NULL        /* IN */
2128             ) = 0;
2129
2130     // Get the unboxed entry point for a method, if possible.
2131     virtual CORINFO_METHOD_HANDLE getUnboxedEntry(
2132         CORINFO_METHOD_HANDLE ftn,
2133         bool* requiresInstMethodTableArg = NULL /* OUT */
2134         ) = 0;
2135
2136     // Given T, return the type of the default EqualityComparer<T>.
2137     // Returns null if the type can't be determined exactly.
2138     virtual CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(
2139             CORINFO_CLASS_HANDLE elemType
2140             ) = 0;
2141
2142     // Given resolved token that corresponds to an intrinsic classified as
2143     // a CORINFO_INTRINSIC_GetRawHandle intrinsic, fetch the handle associated
2144     // with the token. If this is not possible at compile-time (because the current method's 
2145     // code is shared and the token contains generic parameters) then indicate 
2146     // how the handle should be looked up at runtime.
2147     virtual void expandRawHandleIntrinsic(
2148         CORINFO_RESOLVED_TOKEN *        pResolvedToken,
2149         CORINFO_GENERICHANDLE_RESULT *  pResult) = 0;
2150
2151     // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
2152     // getIntrinsicID() returns the intrinsic ID.
2153     // *pMustExpand tells whether or not JIT must expand the intrinsic.
2154     virtual CorInfoIntrinsics getIntrinsicID(
2155             CORINFO_METHOD_HANDLE       method,
2156             bool*                       pMustExpand = NULL      /* OUT */
2157             ) = 0;
2158
2159     // Is the given module the System.Numerics.Vectors module?
2160     // This defaults to false.
2161     virtual bool isInSIMDModule(
2162             CORINFO_CLASS_HANDLE        classHnd
2163             ) { return false; }
2164
2165     // return the unmanaged calling convention for a PInvoke
2166     virtual CorInfoUnmanagedCallConv getUnmanagedCallConv(
2167             CORINFO_METHOD_HANDLE       method
2168             ) = 0;
2169
2170     // return if any marshaling is required for PInvoke methods.  Note that
2171     // method == 0 => calli.  The call site sig is only needed for the varargs or calli case
2172     virtual BOOL pInvokeMarshalingRequired(
2173             CORINFO_METHOD_HANDLE       method,
2174             CORINFO_SIG_INFO*           callSiteSig
2175             ) = 0;
2176
2177     // Check constraints on method type arguments (only).
2178     // The parent class should be checked separately using satisfiesClassConstraints(parent).
2179     virtual BOOL satisfiesMethodConstraints(
2180             CORINFO_CLASS_HANDLE        parent, // the exact parent of the method
2181             CORINFO_METHOD_HANDLE       method
2182             ) = 0;
2183
2184     // Given a delegate target class, a target method parent class,  a  target method,
2185     // a delegate class, check if the method signature is compatible with the Invoke method of the delegate
2186     // (under the typical instantiation of any free type variables in the memberref signatures).
2187     virtual BOOL isCompatibleDelegate(
2188             CORINFO_CLASS_HANDLE        objCls,           /* type of the delegate target, if any */
2189             CORINFO_CLASS_HANDLE        methodParentCls,  /* exact parent of the target method, if any */
2190             CORINFO_METHOD_HANDLE       method,           /* (representative) target method, if any */
2191             CORINFO_CLASS_HANDLE        delegateCls,      /* exact type of the delegate */
2192             BOOL                        *pfIsOpenDelegate /* is the delegate open */
2193             ) = 0;
2194
2195     // Indicates if the method is an instance of the generic
2196     // method that passes (or has passed) verification
2197     virtual CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
2198             CORINFO_METHOD_HANDLE   method /* IN  */
2199             ) = 0;
2200
2201     // Loads the constraints on a typical method definition, detecting cycles;
2202     // for use in verification.
2203     virtual void initConstraintsForVerification(
2204             CORINFO_METHOD_HANDLE   method, /* IN */
2205             BOOL *pfHasCircularClassConstraints, /* OUT */
2206             BOOL *pfHasCircularMethodConstraint /* OUT */
2207             ) = 0;
2208
2209     // Returns enum whether the method does not require verification
2210     // Also see ICorModuleInfo::canSkipVerification
2211     virtual CorInfoCanSkipVerificationResult canSkipMethodVerification (
2212             CORINFO_METHOD_HANDLE       ftnHandle
2213             ) = 0;
2214
2215     // load and restore the method
2216     virtual void methodMustBeLoadedBeforeCodeIsRun(
2217             CORINFO_METHOD_HANDLE       method
2218             ) = 0;
2219
2220     virtual CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(
2221             CORINFO_METHOD_HANDLE       method
2222             ) = 0;
2223
2224     // Returns the global cookie for the /GS unsafe buffer checks
2225     // The cookie might be a constant value (JIT), or a handle to memory location (Ngen)
2226     virtual void getGSCookie(
2227             GSCookie * pCookieVal,                     // OUT
2228             GSCookie ** ppCookieVal                    // OUT
2229             ) = 0;
2230
2231     /**********************************************************************************/
2232     //
2233     // ICorModuleInfo
2234     //
2235     /**********************************************************************************/
2236
2237     // Resolve metadata token into runtime method handles. This function may not
2238     // return normally (e.g. it may throw) if it encounters invalid metadata or other
2239     // failures during token resolution.
2240     virtual void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
2241
2242     // Attempt to resolve a metadata token into a runtime method handle. Returns true
2243     // if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata
2244     // during token reoslution). This method should be used instead of `resolveToken` in
2245     // situations that need to be resilient to invalid metadata.
2246     virtual bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
2247
2248     // Signature information about the call sig
2249     virtual void findSig (
2250             CORINFO_MODULE_HANDLE       module,     /* IN */
2251             unsigned                    sigTOK,     /* IN */
2252             CORINFO_CONTEXT_HANDLE      context,    /* IN */
2253             CORINFO_SIG_INFO           *sig         /* OUT */
2254             ) = 0;
2255
2256     // for Varargs, the signature at the call site may differ from
2257     // the signature at the definition.  Thus we need a way of
2258     // fetching the call site information
2259     virtual void findCallSiteSig (
2260             CORINFO_MODULE_HANDLE       module,     /* IN */
2261             unsigned                    methTOK,    /* IN */
2262             CORINFO_CONTEXT_HANDLE      context,    /* IN */
2263             CORINFO_SIG_INFO           *sig         /* OUT */
2264             ) = 0;
2265
2266     virtual CORINFO_CLASS_HANDLE getTokenTypeAsHandle (
2267             CORINFO_RESOLVED_TOKEN *    pResolvedToken /* IN  */) = 0;
2268
2269     // Returns true if the module does not require verification
2270     //
2271     // If fQuickCheckOnlyWithoutCommit=TRUE, the function only checks that the
2272     // module does not currently require verification in the current AppDomain.
2273     // This decision could change in the future, and so should not be cached.
2274     // If it is cached, it should only be used as a hint.
2275     // This is only used by ngen for calculating certain hints.
2276     //
2277    
2278     // Returns enum whether the module does not require verification
2279     // Also see ICorMethodInfo::canSkipMethodVerification();
2280     virtual CorInfoCanSkipVerificationResult canSkipVerification (
2281             CORINFO_MODULE_HANDLE       module     /* IN  */
2282             ) = 0;
2283
2284     // Checks if the given metadata token is valid
2285     virtual BOOL isValidToken (
2286             CORINFO_MODULE_HANDLE       module,     /* IN  */
2287             unsigned                    metaTOK     /* IN  */
2288             ) = 0;
2289
2290     // Checks if the given metadata token is valid StringRef
2291     virtual BOOL isValidStringRef (
2292             CORINFO_MODULE_HANDLE       module,     /* IN  */
2293             unsigned                    metaTOK     /* IN  */
2294             ) = 0;
2295
2296     virtual BOOL shouldEnforceCallvirtRestriction(
2297             CORINFO_MODULE_HANDLE   scope
2298             ) = 0;
2299
2300     /**********************************************************************************/
2301     //
2302     // ICorClassInfo
2303     //
2304     /**********************************************************************************/
2305
2306     // If the value class 'cls' is isomorphic to a primitive type it will
2307     // return that type, otherwise it will return CORINFO_TYPE_VALUECLASS
2308     virtual CorInfoType asCorInfoType (
2309             CORINFO_CLASS_HANDLE    cls
2310             ) = 0;
2311
2312     // for completeness
2313     virtual const char* getClassName (
2314             CORINFO_CLASS_HANDLE    cls
2315             ) = 0;
2316
2317     // Return class name as in metadata, or nullptr if there is none.
2318     // Suitable for non-debugging use.
2319     virtual const char* getClassNameFromMetadata (
2320             CORINFO_CLASS_HANDLE    cls,
2321             const char            **namespaceName   /* OUT */
2322             ) = 0;
2323
2324     // Return the type argument of the instantiated generic class,
2325     // which is specified by the index
2326     virtual CORINFO_CLASS_HANDLE getTypeInstantiationArgument(
2327             CORINFO_CLASS_HANDLE cls, 
2328             unsigned             index
2329             ) = 0;
2330     
2331
2332     // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
2333     // If fNamespace=TRUE, include the namespace/enclosing classes
2334     // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
2335     // If fAssembly=TRUE, suffix with a comma and the full assembly qualification
2336     // return size of representation
2337     virtual int appendClassName(
2338             __deref_inout_ecount(*pnBufLen) WCHAR** ppBuf, 
2339             int* pnBufLen,
2340             CORINFO_CLASS_HANDLE    cls,
2341             BOOL fNamespace,
2342             BOOL fFullInst,
2343             BOOL fAssembly
2344             ) = 0;
2345
2346     // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & CORINFO_FLG_VALUECLASS, except faster.
2347     virtual BOOL isValueClass(CORINFO_CLASS_HANDLE cls) = 0;
2348
2349     // Decides how the JIT should do the optimization to inline the check for
2350     //     GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE)
2351     //     GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN)
2352     virtual CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) = 0;
2353
2354     // If this method returns true, JIT will do optimization to inline the check for
2355     //     GetTypeFromHandle(handle) == obj.GetType()
2356     virtual BOOL canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls) = 0;
2357
2358     // return flags (defined above, CORINFO_FLG_PUBLIC ...)
2359     virtual DWORD getClassAttribs (
2360             CORINFO_CLASS_HANDLE    cls
2361             ) = 0;
2362
2363     // Returns "TRUE" iff "cls" is a struct type such that return buffers used for returning a value
2364     // of this type must be stack-allocated.  This will generally be true only if the struct 
2365     // contains GC pointers, and does not exceed some size limit.  Maintaining this as an invariant allows
2366     // an optimization: the JIT may assume that return buffer pointers for return types for which this predicate
2367     // returns TRUE are always stack allocated, and thus, that stores to the GC-pointer fields of such return
2368     // buffers do not require GC write barriers.
2369     virtual BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls) = 0;
2370
2371     virtual CORINFO_MODULE_HANDLE getClassModule (
2372             CORINFO_CLASS_HANDLE    cls
2373             ) = 0;
2374
2375     // Returns the assembly that contains the module "mod".
2376     virtual CORINFO_ASSEMBLY_HANDLE getModuleAssembly (
2377             CORINFO_MODULE_HANDLE   mod
2378             ) = 0;
2379
2380     // Returns the name of the assembly "assem".
2381     virtual const char* getAssemblyName (
2382             CORINFO_ASSEMBLY_HANDLE assem
2383             ) = 0;
2384
2385     // Allocate and delete process-lifetime objects.  Should only be
2386     // referred to from static fields, lest a leak occur.
2387     // Note that "LongLifetimeFree" does not execute destructors, if "obj"
2388     // is an array of a struct type with a destructor.
2389     virtual void* LongLifetimeMalloc(size_t sz) = 0;
2390     virtual void LongLifetimeFree(void* obj) = 0;
2391
2392     virtual size_t getClassModuleIdForStatics (
2393             CORINFO_CLASS_HANDLE    cls, 
2394             CORINFO_MODULE_HANDLE *pModule, 
2395             void **ppIndirection
2396             ) = 0;
2397
2398     // return the number of bytes needed by an instance of the class
2399     virtual unsigned getClassSize (
2400             CORINFO_CLASS_HANDLE        cls
2401             ) = 0;
2402
2403     // return the number of bytes needed by an instance of the class allocated on the heap
2404     virtual unsigned getHeapClassSize(
2405         CORINFO_CLASS_HANDLE        cls
2406     ) = 0;
2407
2408     virtual BOOL canAllocateOnStack(
2409         CORINFO_CLASS_HANDLE cls
2410     ) = 0;
2411
2412     virtual unsigned getClassAlignmentRequirement (
2413             CORINFO_CLASS_HANDLE        cls,
2414             BOOL                        fDoubleAlignHint = FALSE
2415             ) = 0;
2416
2417     // This is only called for Value classes.  It returns a boolean array
2418     // in representing of 'cls' from a GC perspective.  The class is
2419     // assumed to be an array of machine words
2420     // (of length // getClassSize(cls) / TARGET_POINTER_SIZE),
2421     // 'gcPtrs' is a pointer to an array of BYTEs of this length.
2422     // getClassGClayout fills in this array so that gcPtrs[i] is set
2423     // to one of the CorInfoGCType values which is the GC type of
2424     // the i-th machine word of an object of type 'cls'
2425     // returns the number of GC pointers in the array
2426     virtual unsigned getClassGClayout (
2427             CORINFO_CLASS_HANDLE        cls,        /* IN */
2428             BYTE                       *gcPtrs      /* OUT */
2429             ) = 0;
2430
2431     // returns the number of instance fields in a class
2432     virtual unsigned getClassNumInstanceFields (
2433             CORINFO_CLASS_HANDLE        cls        /* IN */
2434             ) = 0;
2435
2436     virtual CORINFO_FIELD_HANDLE getFieldInClass(
2437             CORINFO_CLASS_HANDLE clsHnd,
2438             INT num
2439             ) = 0;
2440
2441     virtual BOOL checkMethodModifier(
2442             CORINFO_METHOD_HANDLE hMethod,
2443             LPCSTR modifier,
2444             BOOL fOptional
2445             ) = 0;
2446
2447     // returns the "NEW" helper optimized for "newCls."
2448     virtual CorInfoHelpFunc getNewHelper(
2449             CORINFO_RESOLVED_TOKEN * pResolvedToken,
2450             CORINFO_METHOD_HANDLE    callerHandle
2451             ) = 0;
2452
2453     // returns the newArr (1-Dim array) helper optimized for "arrayCls."
2454     virtual CorInfoHelpFunc getNewArrHelper(
2455             CORINFO_CLASS_HANDLE        arrayCls
2456             ) = 0;
2457
2458     // returns the optimized "IsInstanceOf" or "ChkCast" helper
2459     virtual CorInfoHelpFunc getCastingHelper(
2460             CORINFO_RESOLVED_TOKEN * pResolvedToken,
2461             bool fThrowing
2462             ) = 0;
2463
2464     // returns helper to trigger static constructor
2465     virtual CorInfoHelpFunc getSharedCCtorHelper(
2466             CORINFO_CLASS_HANDLE clsHnd
2467             ) = 0;
2468
2469     virtual CorInfoHelpFunc getSecurityPrologHelper(
2470             CORINFO_METHOD_HANDLE   ftn
2471             ) = 0;
2472
2473     // This is not pretty.  Boxing nullable<T> actually returns
2474     // a boxed<T> not a boxed Nullable<T>.  This call allows the verifier
2475     // to call back to the EE on the 'box' instruction and get the transformed
2476     // type to use for verification.
2477     virtual CORINFO_CLASS_HANDLE  getTypeForBox(
2478             CORINFO_CLASS_HANDLE        cls
2479             ) = 0;
2480
2481     // returns the correct box helper for a particular class.  Note
2482     // that if this returns CORINFO_HELP_BOX, the JIT can assume 
2483     // 'standard' boxing (allocate object and copy), and optimize
2484     virtual CorInfoHelpFunc getBoxHelper(
2485             CORINFO_CLASS_HANDLE        cls
2486             ) = 0;
2487
2488     // returns the unbox helper.  If 'helperCopies' points to a true 
2489     // value it means the JIT is requesting a helper that unboxes the
2490     // value into a particular location and thus has the signature
2491     //     void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
2492     // Otherwise (it is null or points at a FALSE value) it is requesting 
2493     // a helper that returns a pointer to the unboxed data 
2494     //     void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
2495     // The EE has the option of NOT returning the copy style helper
2496     // (But must be able to always honor the non-copy style helper)
2497     // The EE set 'helperCopies' on return to indicate what kind of
2498     // helper has been created.  
2499
2500     virtual CorInfoHelpFunc getUnBoxHelper(
2501             CORINFO_CLASS_HANDLE        cls
2502             ) = 0;
2503
2504     virtual bool getReadyToRunHelper(
2505             CORINFO_RESOLVED_TOKEN *        pResolvedToken,
2506             CORINFO_LOOKUP_KIND *           pGenericLookupKind,
2507             CorInfoHelpFunc                 id,
2508             CORINFO_CONST_LOOKUP *          pLookup
2509             ) = 0;
2510
2511     virtual void getReadyToRunDelegateCtorHelper(
2512             CORINFO_RESOLVED_TOKEN * pTargetMethod,
2513             CORINFO_CLASS_HANDLE     delegateType,
2514             CORINFO_LOOKUP *   pLookup
2515             ) = 0;
2516
2517     virtual const char* getHelperName(
2518             CorInfoHelpFunc
2519             ) = 0;
2520
2521     // This function tries to initialize the class (run the class constructor).
2522     // this function returns whether the JIT must insert helper calls before 
2523     // accessing static field or method.
2524     //
2525     // See code:ICorClassInfo#ClassConstruction.
2526     virtual CorInfoInitClassResult initClass(
2527             CORINFO_FIELD_HANDLE    field,          // Non-NULL - inquire about cctor trigger before static field access
2528                                                     // NULL - inquire about cctor trigger in method prolog
2529             CORINFO_METHOD_HANDLE   method,         // Method referencing the field or prolog
2530             CORINFO_CONTEXT_HANDLE  context,        // Exact context of method
2531             BOOL                    speculative = FALSE     // TRUE means don't actually run it
2532             ) = 0;
2533
2534     // This used to be called "loadClass".  This records the fact
2535     // that the class must be loaded (including restored if necessary) before we execute the
2536     // code that we are currently generating.  When jitting code
2537     // the function loads the class immediately.  When zapping code
2538     // the zapper will if necessary use the call to record the fact that we have
2539     // to do a fixup/restore before running the method currently being generated.
2540     //
2541     // This is typically used to ensure value types are loaded before zapped
2542     // code that manipulates them is executed, so that the GC can access information
2543     // about those value types.
2544     virtual void classMustBeLoadedBeforeCodeIsRun(
2545             CORINFO_CLASS_HANDLE        cls
2546             ) = 0;
2547
2548     // returns the class handle for the special builtin classes
2549     virtual CORINFO_CLASS_HANDLE getBuiltinClass (
2550             CorInfoClassId              classId
2551             ) = 0;
2552
2553     // "System.Int32" ==> CORINFO_TYPE_INT..
2554     virtual CorInfoType getTypeForPrimitiveValueClass(
2555             CORINFO_CLASS_HANDLE        cls
2556             ) = 0;
2557
2558     // "System.Int32" ==> CORINFO_TYPE_INT..
2559     // "System.UInt32" ==> CORINFO_TYPE_UINT..
2560     virtual CorInfoType getTypeForPrimitiveNumericClass(
2561             CORINFO_CLASS_HANDLE        cls
2562             ) = 0;
2563
2564     // TRUE if child is a subtype of parent
2565     // if parent is an interface, then does child implement / extend parent
2566     virtual BOOL canCast(
2567             CORINFO_CLASS_HANDLE        child,  // subtype (extends parent)
2568             CORINFO_CLASS_HANDLE        parent  // base type
2569             ) = 0;
2570
2571     // TRUE if cls1 and cls2 are considered equivalent types.
2572     virtual BOOL areTypesEquivalent(
2573             CORINFO_CLASS_HANDLE        cls1,
2574             CORINFO_CLASS_HANDLE        cls2
2575             ) = 0;
2576
2577     // See if a cast from fromClass to toClass will succeed, fail, or needs
2578     // to be resolved at runtime.
2579     virtual TypeCompareState compareTypesForCast(
2580             CORINFO_CLASS_HANDLE        fromClass,
2581             CORINFO_CLASS_HANDLE        toClass
2582             ) = 0;
2583
2584     // See if types represented by cls1 and cls2 compare equal, not
2585     // equal, or the comparison needs to be resolved at runtime.
2586     virtual TypeCompareState compareTypesForEquality(
2587             CORINFO_CLASS_HANDLE        cls1,
2588             CORINFO_CLASS_HANDLE        cls2
2589             ) = 0;
2590
2591     // returns is the intersection of cls1 and cls2.
2592     virtual CORINFO_CLASS_HANDLE mergeClasses(
2593             CORINFO_CLASS_HANDLE        cls1,
2594             CORINFO_CLASS_HANDLE        cls2
2595             ) = 0;
2596
2597     // Given a class handle, returns the Parent type.
2598     // For COMObjectType, it returns Class Handle of System.Object.
2599     // Returns 0 if System.Object is passed in.
2600     virtual CORINFO_CLASS_HANDLE getParentType (
2601             CORINFO_CLASS_HANDLE        cls
2602             ) = 0;
2603
2604     // Returns the CorInfoType of the "child type". If the child type is
2605     // not a primitive type, *clsRet will be set.
2606     // Given an Array of Type Foo, returns Foo.
2607     // Given BYREF Foo, returns Foo
2608     virtual CorInfoType getChildType (
2609             CORINFO_CLASS_HANDLE       clsHnd,
2610             CORINFO_CLASS_HANDLE       *clsRet
2611             ) = 0;
2612
2613     // Check constraints on type arguments of this class and parent classes
2614     virtual BOOL satisfiesClassConstraints(
2615             CORINFO_CLASS_HANDLE cls
2616             ) = 0;
2617
2618     // Check if this is a single dimensional array type
2619     virtual BOOL isSDArray(
2620             CORINFO_CLASS_HANDLE        cls
2621             ) = 0;
2622
2623     // Get the numbmer of dimensions in an array 
2624     virtual unsigned getArrayRank(
2625             CORINFO_CLASS_HANDLE        cls
2626             ) = 0;
2627
2628     // Get static field data for an array
2629     virtual void * getArrayInitializationData(
2630             CORINFO_FIELD_HANDLE        field,
2631             DWORD                       size
2632             ) = 0;
2633
2634     // Check Visibility rules.
2635     virtual CorInfoIsAccessAllowedResult canAccessClass(
2636                         CORINFO_RESOLVED_TOKEN * pResolvedToken,
2637                         CORINFO_METHOD_HANDLE   callerHandle,
2638                         CORINFO_HELPER_DESC    *pAccessHelper /* If canAccessMethod returns something other
2639                                                                  than ALLOWED, then this is filled in. */
2640                         ) = 0;
2641
2642     /**********************************************************************************/
2643     //
2644     // ICorFieldInfo
2645     //
2646     /**********************************************************************************/
2647
2648     // this function is for debugging only.  It returns the field name
2649     // and if 'moduleName' is non-null, it sets it to something that will
2650     // says which method (a class name, or a module name)
2651     virtual const char* getFieldName (
2652                         CORINFO_FIELD_HANDLE        ftn,        /* IN */
2653                         const char                **moduleName  /* OUT */
2654                         ) = 0;
2655
2656     // return class it belongs to
2657     virtual CORINFO_CLASS_HANDLE getFieldClass (
2658                         CORINFO_FIELD_HANDLE    field
2659                         ) = 0;
2660
2661     // Return the field's type, if it is CORINFO_TYPE_VALUECLASS 'structType' is set
2662     // the field's value class (if 'structType' == 0, then don't bother
2663     // the structure info).
2664     //
2665     // 'memberParent' is typically only set when verifying.  It should be the
2666     // result of calling getMemberParent.
2667     virtual CorInfoType getFieldType(
2668                         CORINFO_FIELD_HANDLE    field,
2669                         CORINFO_CLASS_HANDLE   *structType = NULL,
2670                         CORINFO_CLASS_HANDLE    memberParent = NULL /* IN */
2671                         ) = 0;
2672
2673     // return the data member's instance offset
2674     virtual unsigned getFieldOffset(
2675                         CORINFO_FIELD_HANDLE    field
2676                         ) = 0;
2677
2678     // TODO: jit64 should be switched to the same plan as the i386 jits - use
2679     // getClassGClayout to figure out the need for writebarrier helper, and inline the copying.
2680     // The interpretted value class copy is slow. Once this happens, USE_WRITE_BARRIER_HELPERS
2681     virtual bool isWriteBarrierHelperRequired(
2682                         CORINFO_FIELD_HANDLE    field) = 0;
2683
2684     virtual void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
2685                                CORINFO_METHOD_HANDLE  callerHandle,
2686                                CORINFO_ACCESS_FLAGS   flags,
2687                                CORINFO_FIELD_INFO    *pResult
2688                               ) = 0;
2689
2690     // Returns true iff "fldHnd" represents a static field.
2691     virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0;
2692
2693     /*********************************************************************************/
2694     //
2695     // ICorDebugInfo
2696     //
2697     /*********************************************************************************/
2698
2699     // Query the EE to find out where interesting break points
2700     // in the code are.  The native compiler will ensure that these places
2701     // have a corresponding break point in native code.
2702     //
2703     // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
2704     // be used only as a hint and the native compiler should not change its
2705     // code generation.
2706     virtual void getBoundaries(
2707                 CORINFO_METHOD_HANDLE   ftn,                // [IN] method of interest
2708                 unsigned int           *cILOffsets,         // [OUT] size of pILOffsets
2709                 DWORD                 **pILOffsets,         // [OUT] IL offsets of interest
2710                                                             //       jit MUST free with freeArray!
2711                 ICorDebugInfo::BoundaryTypes *implictBoundaries // [OUT] tell jit, all boundries of this type
2712                 ) = 0;
2713
2714     // Report back the mapping from IL to native code,
2715     // this map should include all boundaries that 'getBoundaries'
2716     // reported as interesting to the debugger.
2717
2718     // Note that debugger (and profiler) is assuming that all of the
2719     // offsets form a contiguous block of memory, and that the
2720     // OffsetMapping is sorted in order of increasing native offset.
2721     virtual void setBoundaries(
2722                 CORINFO_METHOD_HANDLE   ftn,            // [IN] method of interest
2723                 ULONG32                 cMap,           // [IN] size of pMap
2724                 ICorDebugInfo::OffsetMapping *pMap      // [IN] map including all points of interest.
2725                                                         //      jit allocated with allocateArray, EE frees
2726                 ) = 0;
2727
2728     // Query the EE to find out the scope of local varables.
2729     // normally the JIT would trash variables after last use, but
2730     // under debugging, the JIT needs to keep them live over their
2731     // entire scope so that they can be inspected.
2732     //
2733     // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
2734     // be used only as a hint and the native compiler should not change its
2735     // code generation.
2736     virtual void getVars(
2737             CORINFO_METHOD_HANDLE           ftn,            // [IN]  method of interest
2738             ULONG32                        *cVars,          // [OUT] size of 'vars'
2739             ICorDebugInfo::ILVarInfo       **vars,          // [OUT] scopes of variables of interest
2740                                                             //       jit MUST free with freeArray!
2741             bool                           *extendOthers    // [OUT] it TRUE, then assume the scope
2742                                                             //       of unmentioned vars is entire method
2743             ) = 0;
2744
2745     // Report back to the EE the location of every variable.
2746     // note that the JIT might split lifetimes into different
2747     // locations etc.
2748
2749     virtual void setVars(
2750             CORINFO_METHOD_HANDLE           ftn,            // [IN] method of interest
2751             ULONG32                         cVars,          // [IN] size of 'vars'
2752             ICorDebugInfo::NativeVarInfo   *vars            // [IN] map telling where local vars are stored at what points
2753                                                             //      jit allocated with allocateArray, EE frees
2754             ) = 0;
2755
2756     /*-------------------------- Misc ---------------------------------------*/
2757
2758     // Used to allocate memory that needs to handed to the EE.
2759     // For eg, use this to allocated memory for reporting debug info,
2760     // which will be handed to the EE by setVars() and setBoundaries()
2761     virtual void * allocateArray(
2762                         ULONG              cBytes
2763                         ) = 0;
2764
2765     // JitCompiler will free arrays passed by the EE using this
2766     // For eg, The EE returns memory in getVars() and getBoundaries()
2767     // to the JitCompiler, which the JitCompiler should release using
2768     // freeArray()
2769     virtual void freeArray(
2770             void               *array
2771             ) = 0;
2772
2773     /*********************************************************************************/
2774     //
2775     // ICorArgInfo
2776     //
2777     /*********************************************************************************/
2778
2779     // advance the pointer to the argument list.
2780     // a ptr of 0, is special and always means the first argument
2781     virtual CORINFO_ARG_LIST_HANDLE getArgNext (
2782             CORINFO_ARG_LIST_HANDLE     args            /* IN */
2783             ) = 0;
2784
2785     // Get the type of a particular argument
2786     // CORINFO_TYPE_UNDEF is returned when there are no more arguments
2787     // If the type returned is a primitive type (or an enum) *vcTypeRet set to NULL
2788     // otherwise it is set to the TypeHandle associted with the type
2789     // Enumerations will always look their underlying type (probably should fix this)
2790     // Otherwise vcTypeRet is the type as would be seen by the IL,
2791     // The return value is the type that is used for calling convention purposes
2792     // (Thus if the EE wants a value class to be passed like an int, then it will
2793     // return CORINFO_TYPE_INT
2794     virtual CorInfoTypeWithMod getArgType (
2795             CORINFO_SIG_INFO*           sig,            /* IN */
2796             CORINFO_ARG_LIST_HANDLE     args,           /* IN */
2797             CORINFO_CLASS_HANDLE       *vcTypeRet       /* OUT */
2798             ) = 0;
2799
2800     // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it
2801     virtual CORINFO_CLASS_HANDLE getArgClass (
2802             CORINFO_SIG_INFO*           sig,            /* IN */
2803             CORINFO_ARG_LIST_HANDLE     args            /* IN */
2804             ) = 0;
2805
2806     // Returns type of HFA for valuetype
2807     virtual CorInfoType getHFAType (
2808             CORINFO_CLASS_HANDLE hClass
2809             ) = 0;
2810
2811  /*****************************************************************************
2812  * ICorErrorInfo contains methods to deal with SEH exceptions being thrown
2813  * from the corinfo interface.  These methods may be called when an exception
2814  * with code EXCEPTION_COMPLUS is caught.
2815  *****************************************************************************/
2816
2817     // Returns the HRESULT of the current exception
2818     virtual HRESULT GetErrorHRESULT(
2819             struct _EXCEPTION_POINTERS *pExceptionPointers
2820             ) = 0;
2821
2822     // Fetches the message of the current exception
2823     // Returns the size of the message (including terminating null). This can be
2824     // greater than bufferLength if the buffer is insufficient.
2825     virtual ULONG GetErrorMessage(
2826             __inout_ecount(bufferLength) LPWSTR buffer,
2827             ULONG bufferLength
2828             ) = 0;
2829
2830     // returns EXCEPTION_EXECUTE_HANDLER if it is OK for the compile to handle the
2831     //                        exception, abort some work (like the inlining) and continue compilation
2832     // returns EXCEPTION_CONTINUE_SEARCH if exception must always be handled by the EE
2833     //                    things like ThreadStoppedException ...
2834     // returns EXCEPTION_CONTINUE_EXECUTION if exception is fixed up by the EE
2835
2836     virtual int FilterException(
2837             struct _EXCEPTION_POINTERS *pExceptionPointers
2838             ) = 0;
2839
2840     // Cleans up internal EE tracking when an exception is caught.
2841     virtual void HandleException(
2842             struct _EXCEPTION_POINTERS *pExceptionPointers
2843             ) = 0;
2844
2845     virtual void ThrowExceptionForJitResult(
2846             HRESULT result) = 0;
2847
2848     //Throws an exception defined by the given throw helper.
2849     virtual void ThrowExceptionForHelper(
2850             const CORINFO_HELPER_DESC * throwHelper) = 0;
2851
2852     // Runs the given function under an error trap. This allows the JIT to make calls
2853     // to interface functions that may throw exceptions without needing to be aware of
2854     // the EH ABI, exception types, etc. Returns true if the given function completed
2855     // successfully and false otherwise.
2856     virtual bool runWithErrorTrap(
2857         void (*function)(void*), // The function to run
2858         void* parameter          // The context parameter that will be passed to the function and the handler
2859         ) = 0;
2860
2861 /*****************************************************************************
2862  * ICorStaticInfo contains EE interface methods which return values that are
2863  * constant from invocation to invocation.  Thus they may be embedded in
2864  * persisted information like statically generated code. (This is of course
2865  * assuming that all code versions are identical each time.)
2866  *****************************************************************************/
2867
2868     // Return details about EE internal data structures
2869     virtual void getEEInfo(
2870                 CORINFO_EE_INFO            *pEEInfoOut
2871                 ) = 0;
2872
2873     // Returns name of the JIT timer log
2874     virtual LPCWSTR getJitTimeLogFilename() = 0;
2875
2876     /*********************************************************************************/
2877     //
2878     // Diagnostic methods
2879     //
2880     /*********************************************************************************/
2881
2882     // this function is for debugging only. Returns method token.
2883     // Returns mdMethodDefNil for dynamic methods.
2884     virtual mdMethodDef getMethodDefFromMethod(
2885             CORINFO_METHOD_HANDLE hMethod
2886             ) = 0;
2887
2888     // this function is for debugging only.  It returns the method name
2889     // and if 'moduleName' is non-null, it sets it to something that will
2890     // says which method (a class name, or a module name)
2891     virtual const char* getMethodName (
2892             CORINFO_METHOD_HANDLE       ftn,        /* IN */
2893             const char                **moduleName  /* OUT */
2894             ) = 0;
2895
2896     // Return method name as in metadata, or nullptr if there is none,
2897     // and optionally return the class and namespace names as in metadata.
2898     // Suitable for non-debugging use.
2899     virtual const char* getMethodNameFromMetadata(
2900             CORINFO_METHOD_HANDLE       ftn,            /* IN */
2901             const char                **className,      /* OUT */
2902             const char                **namespaceName   /* OUT */
2903             ) = 0;
2904
2905     // this function is for debugging only.  It returns a value that
2906     // is will always be the same for a given method.  It is used
2907     // to implement the 'jitRange' functionality
2908     virtual unsigned getMethodHash (
2909             CORINFO_METHOD_HANDLE       ftn         /* IN */
2910             ) = 0;
2911
2912     // this function is for debugging only.
2913     virtual size_t findNameOfToken (
2914             CORINFO_MODULE_HANDLE       module,     /* IN  */
2915             mdToken                     metaTOK,     /* IN  */
2916             __out_ecount (FQNameCapacity) char * szFQName, /* OUT */
2917             size_t FQNameCapacity  /* IN */
2918             ) = 0;
2919
2920     // returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure.
2921     virtual bool getSystemVAmd64PassStructInRegisterDescriptor(
2922         /* IN */    CORINFO_CLASS_HANDLE        structHnd,
2923         /* OUT */   SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr
2924         ) = 0;
2925
2926 };
2927
2928 /*****************************************************************************
2929  * ICorDynamicInfo contains EE interface methods which return values that may
2930  * change from invocation to invocation.  They cannot be embedded in persisted
2931  * data; they must be requeried each time the EE is run.
2932  *****************************************************************************/
2933
2934 class ICorDynamicInfo : public ICorStaticInfo
2935 {
2936 public:
2937
2938     //
2939     // These methods return values to the JIT which are not constant
2940     // from session to session.
2941     //
2942     // These methods take an extra parameter : void **ppIndirection.
2943     // If a JIT supports generation of prejit code (install-o-jit), it
2944     // must pass a non-null value for this parameter, and check the
2945     // resulting value.  If *ppIndirection is NULL, code should be
2946     // generated normally.  If non-null, then the value of
2947     // *ppIndirection is an address in the cookie table, and the code
2948     // generator needs to generate an indirection through the table to
2949     // get the resulting value.  In this case, the return result of the
2950     // function must NOT be directly embedded in the generated code.
2951     //
2952     // Note that if a JIT does not support prejit code generation, it
2953     // may ignore the extra parameter & pass the default of NULL - the
2954     // prejit ICorDynamicInfo implementation will see this & generate
2955     // an error if the jitter is used in a prejit scenario.
2956     //
2957
2958     // Return details about EE internal data structures
2959
2960     virtual DWORD getThreadTLSIndex(
2961                     void                  **ppIndirection = NULL
2962                     ) = 0;
2963
2964     virtual const void * getInlinedCallFrameVptr(
2965                     void                  **ppIndirection = NULL
2966                     ) = 0;
2967
2968     virtual LONG * getAddrOfCaptureThreadGlobal(
2969                     void                  **ppIndirection = NULL
2970                     ) = 0;
2971
2972     // return the native entry point to an EE helper (see CorInfoHelpFunc)
2973     virtual void* getHelperFtn (
2974                     CorInfoHelpFunc         ftnNum,
2975                     void                  **ppIndirection = NULL
2976                     ) = 0;
2977
2978     // return a callable address of the function (native code). This function
2979     // may return a different value (depending on whether the method has
2980     // been JITed or not.
2981     virtual void getFunctionEntryPoint(
2982                               CORINFO_METHOD_HANDLE   ftn,                 /* IN  */
2983                               CORINFO_CONST_LOOKUP *  pResult,             /* OUT */
2984                               CORINFO_ACCESS_FLAGS    accessFlags = CORINFO_ACCESS_ANY) = 0;
2985
2986     // return a directly callable address. This can be used similarly to the
2987     // value returned by getFunctionEntryPoint() except that it is
2988     // guaranteed to be multi callable entrypoint.
2989     virtual void getFunctionFixedEntryPoint(
2990                               CORINFO_METHOD_HANDLE   ftn,
2991                               CORINFO_CONST_LOOKUP *  pResult) = 0;
2992
2993     // get the synchronization handle that is passed to monXstatic function
2994     virtual void* getMethodSync(
2995                     CORINFO_METHOD_HANDLE               ftn,
2996                     void                  **ppIndirection = NULL
2997                     ) = 0;
2998
2999     // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*). 
3000     // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
3001     virtual CorInfoHelpFunc getLazyStringLiteralHelper(
3002                     CORINFO_MODULE_HANDLE   handle
3003                     ) = 0;
3004
3005     virtual CORINFO_MODULE_HANDLE embedModuleHandle(
3006                     CORINFO_MODULE_HANDLE   handle,
3007                     void                  **ppIndirection = NULL
3008                     ) = 0;
3009
3010     virtual CORINFO_CLASS_HANDLE embedClassHandle(
3011                     CORINFO_CLASS_HANDLE    handle,
3012                     void                  **ppIndirection = NULL
3013                     ) = 0;
3014
3015     virtual CORINFO_METHOD_HANDLE embedMethodHandle(
3016                     CORINFO_METHOD_HANDLE   handle,
3017                     void                  **ppIndirection = NULL
3018                     ) = 0;
3019
3020     virtual CORINFO_FIELD_HANDLE embedFieldHandle(
3021                     CORINFO_FIELD_HANDLE    handle,
3022                     void                  **ppIndirection = NULL
3023                     ) = 0;
3024
3025     // Given a module scope (module), a method handle (context) and
3026     // a metadata token (metaTOK), fetch the handle
3027     // (type, field or method) associated with the token.
3028     // If this is not possible at compile-time (because the current method's
3029     // code is shared and the token contains generic parameters)
3030     // then indicate how the handle should be looked up at run-time.
3031     //
3032     virtual void embedGenericHandle(
3033                         CORINFO_RESOLVED_TOKEN *        pResolvedToken,
3034                         BOOL                            fEmbedParent, // TRUE - embeds parent type handle of the field/method handle
3035                         CORINFO_GENERICHANDLE_RESULT *  pResult) = 0;
3036
3037     // Return information used to locate the exact enclosing type of the current method.
3038     // Used only to invoke .cctor method from code shared across generic instantiations
3039     //   !needsRuntimeLookup       statically known (enclosing type of method itself)
3040     //   needsRuntimeLookup:
3041     //      CORINFO_LOOKUP_THISOBJ     use vtable pointer of 'this' param
3042     //      CORINFO_LOOKUP_CLASSPARAM  use vtable hidden param
3043     //      CORINFO_LOOKUP_METHODPARAM use enclosing type of method-desc hidden param
3044     virtual CORINFO_LOOKUP_KIND getLocationOfThisType(
3045                     CORINFO_METHOD_HANDLE context
3046                     ) = 0;
3047
3048     // NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are
3049     //       deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the
3050     //       functionality of these methods.
3051
3052     // return the unmanaged target *if method has already been prelinked.*
3053     virtual void* getPInvokeUnmanagedTarget(
3054                     CORINFO_METHOD_HANDLE   method,
3055                     void                  **ppIndirection = NULL
3056                     ) = 0;
3057
3058     // return address of fixup area for late-bound PInvoke calls.
3059     virtual void* getAddressOfPInvokeFixup(
3060                     CORINFO_METHOD_HANDLE   method,
3061                     void                  **ppIndirection = NULL
3062                     ) = 0;
3063
3064     // return the address of the PInvoke target. May be a fixup area in the
3065     // case of late-bound PInvoke calls.
3066     virtual void getAddressOfPInvokeTarget(
3067                     CORINFO_METHOD_HANDLE  method,
3068                     CORINFO_CONST_LOOKUP  *pLookup
3069                     ) = 0;
3070
3071     // Generate a cookie based on the signature that would needs to be passed
3072     // to CORINFO_HELP_PINVOKE_CALLI
3073     virtual LPVOID GetCookieForPInvokeCalliSig(
3074             CORINFO_SIG_INFO* szMetaSig,
3075             void           ** ppIndirection = NULL
3076             ) = 0;
3077
3078     // returns true if a VM cookie can be generated for it (might be false due to cross-module
3079     // inlining, in which case the inlining should be aborted)
3080     virtual bool canGetCookieForPInvokeCalliSig(
3081                     CORINFO_SIG_INFO* szMetaSig
3082                     ) = 0;
3083
3084     // Gets a handle that is checked to see if the current method is
3085     // included in "JustMyCode"
3086     virtual CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(
3087                     CORINFO_METHOD_HANDLE       method,
3088                     CORINFO_JUST_MY_CODE_HANDLE**ppIndirection = NULL
3089                     ) = 0;
3090
3091     // Gets a method handle that can be used to correlate profiling data.
3092     // This is the IP of a native method, or the address of the descriptor struct
3093     // for IL.  Always guaranteed to be unique per process, and not to move. */
3094     virtual void GetProfilingHandle(
3095                     BOOL                      *pbHookFunction,
3096                     void                     **pProfilerHandle,
3097                     BOOL                      *pbIndirectedHandles
3098                     ) = 0;
3099
3100     // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values.
3101     virtual void getCallInfo(
3102                         // Token info
3103                         CORINFO_RESOLVED_TOKEN * pResolvedToken,
3104
3105                         //Generics info
3106                         CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
3107
3108                         //Security info
3109                         CORINFO_METHOD_HANDLE   callerHandle,
3110
3111                         //Jit info
3112                         CORINFO_CALLINFO_FLAGS  flags,
3113
3114                         //out params
3115                         CORINFO_CALL_INFO       *pResult
3116                         ) = 0;
3117
3118     virtual BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
3119                                            CORINFO_CLASS_HANDLE hInstanceType) = 0;
3120
3121     // Returns TRUE if the Class Domain ID is the RID of the class (currently true for every class
3122     // except reflection emitted classes and generics)
3123     virtual BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls) = 0;
3124
3125     // returns the class's domain ID for accessing shared statics
3126     virtual unsigned getClassDomainID (
3127                     CORINFO_CLASS_HANDLE    cls,
3128                     void                  **ppIndirection = NULL
3129                     ) = 0;
3130
3131
3132     // return the data's address (for static fields only)
3133     virtual void* getFieldAddress(
3134                     CORINFO_FIELD_HANDLE    field,
3135                     void                  **ppIndirection = NULL
3136                     ) = 0;
3137
3138     // If pIsSpeculative is NULL, return the class handle for the value of ref-class typed
3139     // static readonly fields, if there is a unique location for the static and the class
3140     // is already initialized.
3141     // 
3142     // If pIsSpeculative is not NULL, fetch the class handle for the value of all ref-class
3143     // typed static fields, if there is a unique location for the static and the field is
3144     // not null.
3145     //
3146     // Set *pIsSpeculative true if this type may change over time (field is not readonly or
3147     // is readonly but class has not yet finished initialization). Set *pIsSpeculative false
3148     // if this type will not change.
3149     virtual CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(
3150                     CORINFO_FIELD_HANDLE    field,
3151                     bool                   *pIsSpeculative = NULL
3152                     ) = 0;
3153
3154     // registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
3155     virtual CORINFO_VARARGS_HANDLE getVarArgsHandle(
3156                     CORINFO_SIG_INFO       *pSig,
3157                     void                  **ppIndirection = NULL
3158                     ) = 0;
3159
3160     // returns true if a VM cookie can be generated for it (might be false due to cross-module
3161     // inlining, in which case the inlining should be aborted)
3162     virtual bool canGetVarArgsHandle(
3163                     CORINFO_SIG_INFO       *pSig
3164                     ) = 0;
3165
3166     // Allocate a string literal on the heap and return a handle to it
3167     virtual InfoAccessType constructStringLiteral(
3168                     CORINFO_MODULE_HANDLE   module,
3169                     mdToken                 metaTok,
3170                     void                  **ppValue
3171                     ) = 0;
3172
3173     virtual InfoAccessType emptyStringLiteral(
3174                     void                  **ppValue
3175                     ) = 0;
3176
3177     // (static fields only) given that 'field' refers to thread local store,
3178     // return the ID (TLS index), which is used to find the begining of the
3179     // TLS data area for the particular DLL 'field' is associated with.
3180     virtual DWORD getFieldThreadLocalStoreID (
3181                     CORINFO_FIELD_HANDLE    field,
3182                     void                  **ppIndirection = NULL
3183                     ) = 0;
3184
3185     // Sets another object to intercept calls to "self" and current method being compiled
3186     virtual void setOverride(
3187                 ICorDynamicInfo             *pOverride,
3188                 CORINFO_METHOD_HANDLE       currentMethod
3189                 ) = 0;
3190
3191     // Adds an active dependency from the context method's module to the given module
3192     // This is internal callback for the EE. JIT should not call it directly.
3193     virtual void addActiveDependency(
3194                CORINFO_MODULE_HANDLE       moduleFrom,
3195                CORINFO_MODULE_HANDLE       moduleTo
3196                 ) = 0;
3197
3198     virtual CORINFO_METHOD_HANDLE GetDelegateCtor(
3199             CORINFO_METHOD_HANDLE  methHnd,
3200             CORINFO_CLASS_HANDLE   clsHnd,
3201             CORINFO_METHOD_HANDLE  targetMethodHnd,
3202             DelegateCtorArgs *     pCtorData
3203             ) = 0;
3204
3205     virtual void MethodCompileComplete(
3206                 CORINFO_METHOD_HANDLE methHnd
3207                 ) = 0;
3208
3209     // return a thunk that will copy the arguments for the given signature.
3210     virtual void* getTailCallCopyArgsThunk (
3211                     CORINFO_SIG_INFO       *pSig,
3212                     CorInfoHelperTailCallSpecialHandling flags
3213                     ) = 0;
3214
3215     // Optionally, convert calli to regular method call. This is for PInvoke argument marshalling.
3216     virtual bool convertPInvokeCalliToCall(
3217                     CORINFO_RESOLVED_TOKEN * pResolvedToken,
3218                     bool fMustConvert
3219                     ) = 0;
3220 };
3221
3222 /**********************************************************************************/
3223
3224 // It would be nicer to use existing IMAGE_REL_XXX constants instead of defining our own here...
3225 #define IMAGE_REL_BASED_REL32           0x10
3226 #define IMAGE_REL_BASED_THUMB_BRANCH24  0x13
3227
3228 // The identifier for ARM32-specific PC-relative address
3229 // computation corresponds to the following instruction
3230 // sequence:
3231 //  l0: movw rX, #imm_lo  // 4 byte
3232 //  l4: movt rX, #imm_hi  // 4 byte
3233 //  l8: add  rX, pc <- after this instruction rX = relocTarget
3234 //
3235 // Program counter at l8 is address of l8 + 4
3236 // Address of relocated movw/movt is l0
3237 // So, imm should be calculated as the following:
3238 //  imm = relocTarget - (l8 + 4) = relocTarget - (l0 + 8 + 4) = relocTarget - (l_0 + 12)
3239 // So, the value of offset correction is 12
3240 //
3241 #define IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL   0x14
3242
3243 #endif // _COR_INFO_H_