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