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