This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!
Intermediate Language (IL)
The Intermediate Language is intended to be easily targeted by compilers for a wide range of common programming languages and to be implemented by a range of IL-to-native code compilers, including Just-In-Time (JIT) compilers. It is the job of the JITter to convert from this Intermediate Language and execution model into the native instructions, calling convention, and execution model of a physical computer (see Conversion of IL into Native Code).
The virtual execution model consists of an evaluation stack used for pushing arguments to methods and built-in operations. At a method call the arguments are transferred from the control of the calling method to the control of the called method. Returned values of any instantiable type are pushed on the stack before method return. Instance and virtual methods are called by passing the this pointer as a “hidden” first parameter to the called method.
The IL instruction set can be divided into the following categories of instructions. See the IL Instruction Set specification for details
- Arithmetic and Logical Operations. These take their operands off the evaluation stack and store the result back there. Arithmetic includes computation, comparison, and coercion. Computations can be performed with or without overflow detection. These operations implement the fundamental operations on the built-in VOS data types.
- Control Flow.
- conditional and unconditional branches within a method
- jump table to known destinations within method (case dispatch)
- calls and returns between methods (with fixed destination, computed destination, or instance-based destination, all with or without tail-call optimization)
- throwing and catching an exception
- breakpoint and no-op
- Direct memory access. These include the ability to clear, copy, and load onto the stack arbitrary portions of memory. It is also possible to compute the address of static data, and load or store a built-in data type or Reference Type indirectly through a pointer.
- Stack manipulation. The contents of the top of the stack can be duplicated or removed (popped), and constants (numbers, the null reference value, and strings) can be pushed onto the stack.
- Argument and local variables. The values of arguments and local variables can be loaded onto the stack, the top of the stack can be stored into them, and their address can be loaded onto the stack. There is also support for typesafe reference to a variable number of input arguments.
- Stack allocation. Memory can be allocated in the currently executing stack frame (alloca).
- Object model. The IL directly supports the box and unbox operations for converting Value Types to and from their corresponding Reference Type. It also supports assignment compatibility testing.
- Values of Instantiable Types. There are specific IL instructions to create and copy values of instantiable types (both Value Types and Reference Types) as well as to load them on the stack and initialize their bit sequences to a known initial state. There are instructions to access and modify member fields (static or instance) of values, as well as to compute the addresses of member fields.
- Critical region. Every object (the value of a self-describing Reference Type) can be used as a synchronization point for methods and critical regions. Methods on objects can be marked synchronized to guarantee mutually exclusive access to their implementations. Static methods on a class or interface can also be marked synchronized and they use the class or interface itself as the synchronization point.
- Arrays. There are IL instructions to deal with one-dimensional, zero-indexed arrays (vectors). These are used to create such arrays, extract their length, load or store individual elements, and calculate the address of an individual element. All arrays (not just vectors) maintain the information about their rank, bounds for each dimension, and underlying data type as part of their runtime description. Any attempt to store into the array or compute the address of an element of an array checks the bounds and the type at runtime (co-variant arrays).
- Typed locations. The IL has instructions to create typed locations (used to implement the typed reference parameter passing convention of the VOS), load them on the stack, access their address part in a typesafe manner, and access their type part.