The instructions described in the base instruction set are independent of the object model being executed. Those instructions correspond closely to what would be found on a real CPU. The object model instructions are less built-in than the base instructions in the sense that they could be built out of the base instructions and calls to the underlying operating system. RATIONALE The object model instructions provide a common, efficient implementation of a set of services used by many (but by no means all) higher-level languages. They embed in their operation a set of conventions defined by the Common Type System. This includes (among other things): Field layout within an object Layout for late-bound method calls (vtables) Memory allocation and reclamation Exception handling Boxing and unboxing to convert between reference-based Objects and Value Types For more details, see Partition I [section 8 and its subsections]. 4.1 box Convert Value Type to Object Reference
Stack Transition: …, valueType …, obj Description: A value type has two separate representations (see Partition I [section 8.2 and its subsections]) within the CLI:
The box instruction converts the "raw" valueType (an unboxed value type) into an instance of type Object (of type O). This is accomplished by creating a new object and copying the data from valueType into the newly allocated object. valTypeTok is a metadata token (a typeref or typedef) indicating the type of valueType (see Partition II). Exceptions: OutOfMemoryException is thrown if there is insufficient memory to satisfy the request. TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that valueType is of the correct value type, and that valTypeTok is a typeref or typedef metadata token for that value type. 4.2 callvirt Call a Method Associated, at Runtime, with an Object
Stack Transition: …, obj, arg1, … argN …, returnVal (not always returned) Description: The callvirt instruction calls a late-bound method on an object. That is, the method is chosen based on the runtime type of obj rather than the compile-time class visible in the method metadata token. callvirt can be used to call both virtual and instance methods. See Partition I [section 12.4 and its subsections] for a detailed description of the CIL calling sequence. The callvirt instruction may be immediately preceded by a tail. prefix to specify that the current stack frame should be released before transferring control. If the call would transfer control to a method of higher trust than the original method, the stack frame would not be released. (A callee of "higher trust" is defined as one whose permission grant-set is a strict superset of the grant-set of the caller.) method is a metadata token (a methoddef or methodref; see Partition II) that provides the name, class, and signature of the method to call. In more detail, callvirt can be thought of as follows. Associated with obj is the class of which it is an instance. If obj's class defines a non-static method that matches the indicated method name and signature, this method is called. Otherwise all classes in the superclass chain of obj's class are checked in order. It is an error if no method is found. callvirt pops the object and the arguments off the evaluation stack before calling the method. If the method has a return value, it is pushed onto the stack upon method completion. On the callee side, the obj parameter is accessed as argument 0, arg1 as argument 1, etc. The arguments are placed on the stack in left-to-right order. That is, the first argument is computed and placed on the stack, then the second argument, etc. The this pointer (always required for callvirt) must be pushed before any of the user-visible arguments. The signature carried in the metadata does not contain an entry in the parameter list for the this pointer, but uses a bit (called HASTHIS) to indicate whether the method requires passing the this pointer (see Partition II [sections 22.2.1 and 22.2.2]). Note that a virtual method may also be called using the call instruction. Exceptions: MissingMethodException is thrown if a non-static method with the indicated name and signature could not be found in obj's class or any of its superclasses. This is typically detected when CIL is converted to native code, rather than at runtime. NullReferenceException is thrown if obj is null. SecurityException is thrown if system security does not grant the caller access to the called method. The security check may occur when the CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that the destination method exists and the values on the stack correspond to the types of the parameters of the method being called. In its typical use, callvirt is verifiable if (a) the above restrictions are met, (b) the verification type of obj is consistent with the method being called, (c) the verification types of the arguments on the stack are consistent with the types expected by the method call, and (d) the method is accessible from the call site. A callvirt annotated by tail. has additional considerations see Partition III, section 2.1. 4.3 castclass Cast an Object to a Class
Stack Transition: …, obj …, obj2 Description: The castclass instruction attempts to cast obj (an O) to the class. class is a metadata token (a typeref or typedef) indicating the desired class. If the class of the object on the top of the stack does not implement class (if class is an interface), and is not a subclass of class (if class is a regular class), then an InvalidCastException is thrown. Note that:
If obj is null, castclass succeeds and returns null. This behavior differs from isInst. Exceptions: InvalidCastException is thrown if obj cannot be cast to class. TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that class is a valid typeref or typedef token, and that obj is always either null or an object reference. 4.4 cpobj Copy a Value Type
Stack Transition: …, destValObj, srcValObj …, Description: The cpobj instruction copies the value type located at the address specified by srcValObj (an unmanaged pointer, native int, or a managed pointer, &) to the address specified by destValObj (also a pointer). Behavior is unspecified if srcValObj and dstValObj are not pointers to instances of the class represented by classTok (a typeref or typedef), or if classTok does not represent a value type. Exceptions: NullReferenceException may be thrown if an invalid address is detected. Verifiability: Correct CIL ensures that classTok is a valid typeref or typedef token for a value type, as well as that srcValObj and destValObj are both pointers to locations of that type. Verification requires, in addition, that srcValObj and destValObj are both managed pointers (not unmanaged pointers). 4.5 initobj Initialize a Value Type
Stack Transition: …, addrOfValObj …, Description: The initobj instruction initializes all the fields of the object represented by the address addrOfValObj (of type native int, or &) to null or a 0 of the appropriate built-in type. After this method is called, the instance is ready for the constructor method to be called. Behavior is unspecified if either addrOfValObj is not a pointer to an instance of the class represented by classTok (a typeref or typedef; see Partition II), or classTok does not represent a value type. Notice that, unlike newobj, the constructor method is not called by initobj. initobj is intended for initializing value types, while newobj is used to allocate and initialize objects. Exceptions: None. Verifiability: Correct CIL ensures that classTok is a valid typeref or typedef token specifying a value type, and that valObj is a managed pointer to an instance of that value type. 4.6 isinst Test If an Object Is an Instance of a Class or Interface
Stack Transition: …, obj …, result Description: The isinst instruction tests whether obj (type O) is an instance of class. class is a metadata token (a typeref or typedef; see Partition II) indicating the desired class. If the class of the object on the top of the stack implements class (if class is an interface) or is a subclass of class (if class is a regular class), then it is cast to the type class and the result is pushed onto the stack, exactly as though castclass had been called. Otherwise null is pushed onto the stack. If obj is null, isinst returns null. Note that:
Exceptions: TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that class is a valid typeref or typedef token indicating a class, and that obj is always either null or an object reference. 4.7 ldelem.<type> Load an Element of an Array
Stack Transition: …, array, index …, value Description: The ldelem instruction loads the value of the element with index index (of type int32 or native int) in the zero-based, one-dimensional array array and places it on the top of the stack. Arrays are objects and hence represented by a value of type O. The return value is indicated by the instruction. For one-dimensional arrays that aren't zero-based, and for multi-dimensional arrays, the array class provides a Get method. Note that integer values of less than 4 bytes are extended to int32 (not native int) when they are loaded onto the evaluation stack. Floating point values are converted to F type when loaded onto the evaluation stack. Exceptions: NullReferenceException is thrown if array is null. IndexOutOfRangeException is thrown if index is negative, or larger than the bound of array. ArrayTypeMismatchException is thrown if array doesn't hold elements of the required type. Verifiability: Correct CIL code requires that array is either null or a zero-based, one-dimensional array whose declared element type matches exactly the type for this particular instruction suffix (e.g., ldelem.r4 can only be applied to a zero-based, one-dimensional array of float32s). 4.8 ldelema Load Address of an Element of an Array
Stack Transition: …, array, index …, address Description: The ldelema instruction loads the address of the element with index index (of type int32 or native int) in the zero-based, one-dimensional array array (of element type class) and places it on the top of the stack. Arrays are objects and hence represented by a value of type O. The return address is a managed pointer (type &). For one-dimensional arrays that aren't zero-based, and for multi-dimensional arrays, the array class provides a Address method. Exceptions: NullReferenceException is thrown if array is null. IndexOutOfRangeException is thrown if index is negative, or larger than the bound of array. ArrayTypeMismatchException is thrown if array doesn't hold elements of the required type. Verifiability: Correct CIL ensures that class is a typeref or typedef token to a class, and that array is indeed always either null or a zero-based, one-dimensional array whose declared element type matches class exactly. 4.9 ldfld Load Field of an Object
Stack Transition: …, obj …, value Description: The ldfld instruction pushes onto the stack the value of a field of obj. obj must be an object (type O), a managed pointer (type &), an unmanaged pointer (type native int), or an instance of a value type. The use of an unmanaged pointer is not permitted in verifiable code. field is a metadata token (a fieldref or fielddef; see Partition II) that must refer to a field member. The return type is that associated with field. ldfld pops the object reference off the stack and pushes the value for the field in its place. The field may be either an instance field (in which case obj must not be null) or a static field. The ldfld instruction may be preceded by either or both of the unaligned. and volatile. prefixes. Exceptions: NullReferenceException is thrown if obj is null and the field is not static. MissingFieldException is thrown if field is not found in the metadata. This is typically checked when CIL is converted to native code, not at runtime. Verifiability: Correct CIL ensures that field is a valid token referring to a field, and that obj will always have a type compatible with that required for the lookup being performed. For verifiable code, obj may not be an unmanaged pointer. 4.10 ldflda Load Field Address
Stack Transition: …, obj …, address Description: The ldflda instruction pushes the address of a field of obj. obj is either an object, type O; a managed pointer, type &; or an unmanaged pointer, type native int. The use of an unmanaged pointer is not allowed in verifiable code. The value returned by ldflda is a managed pointer (type &) unless obj is an unmanaged pointer, in which case it is an unmanaged pointer (type native int). field is a metadata token (a fieldref or fielddef; see Partition II) that must refer to a field member. The field may be either an instance field (in which case obj must not be null) or a static field. Exceptions: InvalidOperationException is thrown if the obj is not within the application domain from which it is being accessed. The address of a field that is not inside the accessing application domain cannot be loaded. MissingFieldException is thrown if field is not found in the metadata. This is typically checked when CIL is converted to native code, not at runtime. NullReferenceException is thrown if obj is null and the field isn't static. Verifiability: Correct CIL ensures that field is a valid fieldref token and that obj will always have a type compatible with that required for the lookup being performed. NOTE Using ldflda to compute the address of a static, init-only field and then using the resulting pointer to modify that value outside the body of the class initializer may lead to unpredictable behavior. It cannot, however, compromise memory integrity or type safety, so it is not tested by verification. 4.11 ldlen Load the Length of an Array
Stack Transition: …, array …, length Description: The ldlen instruction pushes the number of elements of array (a zero-based, one-dimensional array) onto the stack. Arrays are objects and hence represented by a value of type O. The return value is a native unsigned int. Exceptions: NullReferenceException is thrown if array is null. Verifiability: Correct CIL ensures that array is indeed always either null or a zero-based, one-dimensional array. 4.12 ldobj Copy Value Type to the Stack
Stack Transition: …, addrOfValObj …, valObj Description: The ldobj instruction copies the value pointed to by addrOfValObj (of type managed pointer, &, or unmanaged pointer, native unsigned int) to the top of the stack. The number of bytes copied depends on the size of the class represented by classTok. classTok is a metadata token (a typeref or typedef; see Partition II) representing a value type. RATIONALE The ldobj instruction is used to pass a value type as a parameter. See Partition I [section 12.1.6.2.2]. It is unspecified what happens if addrOfValObj is not an instance of the class represented by classTok or if classTok does not represent a value type. The operation of the ldobj instruction may be altered by an immediately preceding volatile. or unaligned. prefix instruction. Exceptions: TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that classTok is a metadata token representing a value type and that addrOfValObj is a pointer to a location containing a value of the type specified by classTok. Verifiable code additionally requires that addrOfValObj is a managed pointer of a matching type. 4.13 ldsfld Load Static Field of a Class
Stack Transition: …, …, value Description: The ldsfld instruction pushes the value of a static (shared among all instances of a class) field onto the stack. field is a metadata token (a fieldref or fielddef; see Partition II) referring to a static field member. The return type is that associated with field. The ldsfld instruction may have a volatile. prefix. Exceptions: None. Verifiability: Correct CIL ensures that field is a valid metadata token referring to a static field member. 4.14 ldsflda Load Static Field Address
Stack Transition: …, …, address Description: The ldsflda instruction pushes the address (a managed pointer, type &, if field refers to a type whose memory is managed; otherwise an unmanaged pointer, type native int) of a static field onto the stack. field is a metadata token (a fieldref or fielddef; see Partition II) referring to a static field member. (Note that field may be a static global with assigned RVA, in which case its memory is unmanaged where RVA stands for Relative Virtual Address, the offset of the field from the base address at which its containing PE file is loaded into memory.) Exceptions: MissingFieldException is thrown if field is not found in the metadata. This is typically checked when CIL is converted to native code, not at runtime. Verifiability: Correct CIL ensures that field is a valid metadata token referring to a static field member if field refers to a type whose memory is managed. NOTE Using ldsflda to compute the address of a static, init-only field and then using the resulting pointer to modify that value outside the body of the class initializer may lead to unpredictable behavior. It cannot, however, compromise memory integrity or type safety, so it is not tested by verification. 4.15 ldstr Load a Literal String
Stack Transition: …, …, string Description: The ldstr instruction pushes a new string object representing the literal stored in the metadata as string (that must be a string literal). The ldstr instruction allocates memory and performs any format conversion required to convert from the form used in the file to the string format required at runtime. The CLI guarantees that the result of two ldstr instructions referring to two metadata tokens that have the same sequence of characters return precisely the same string object (a process known as "string interning"). Exceptions: None. Verifiability: Correct CIL requires that string is a valid string literal metadata token. 4.16 ldtoken Load the Runtime Representation of a Metadata Token
Stack Transition: … …, RuntimeHandle Description: The ldtoken instruction pushes a RuntimeHandle for the specified metadata token. The token must be one of:
The value pushed onto the stack can be used in calls to Reflection methods in the system class library. Exceptions: None. Verifiability: Correct CIL requires that token describes a valid metadata token. 4.17 ldvirtftn Load a Virtual Method Pointer
Stack Transition: … object …, ftn Description: The ldvirtftn instruction pushes an unmanaged pointer (type native int) to the native code implementing the virtual method associated with object and described by the method reference mthd (a metadata token, either a methoddef or methodref; see Partition II) onto the stack. The value pushed can be called using the calli instruction if it references a managed method (or a stub that transitions from managed to unmanaged code). The value returned points to native code using the calling convention specified by mthd. Thus a method pointer can be passed to unmanaged native code (e.g., as a callback routine) if that routine expects the corresponding calling convention. Note that the address computed by this instruction may be to a thunk produced specially for this purpose (for example, to re-enter the CLI when a native version of the method isn't available). Exceptions: None. Verifiability: Correct CIL ensures that mthd is a valid methoddef or methodref token, and also that mthd references a non-static method that is defined for object. Verification tracks the type of the value pushed in more detail than the native int type, remembering that it is a method pointer. Such a method pointer can then be used in verified code with calli or to construct a delegate.
4.18 mkrefany Push a Typed Reference onto the Stack
Stack Transition: …, ptr …, typedRef Description: The mkrefany instruction supports the passing of dynamically typed references. ptr must be a pointer (type &, or native int) that holds the address of a piece of data. class is the class token (a typeref or typedef; see Partition II) describing the type of ptr. mkrefany pushes a typed reference onto the stack that is an opaque descriptor of ptr and class. The only legal operation on a typed reference on the stack is to pass it to a method that requires a typed reference as a parameter. The callee can then use the refanytype and refanyval instructions to retrieve the type (class) and address (ptr), respectively. Exceptions: TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that class is a valid typeref or typedef token describing some type, and that ptr is a pointer to exactly that type. Verification additionally requires that ptr be a managed pointer. Verification will fail if it cannot deduce that ptr is a pointer to an instance of class. 4.19 newarr Create a Zero-Based, One-Dimensional Array
Stack Transition: …, numElems …, array Description: The newarr instruction pushes a reference to a new zero-based, one-dimensional array whose elements are of type elemtype, a metadata token (a typeref or typedef; see Partition II). numElems (of type native int) specifies the number of elements in the array. Valid array indexes are 0 index < Zero-based, one-dimensional arrays of numbers are created using a metadata token referencing the appropriate value type (System.Int32, etc.). Elements of the array are initialized to 0 of the appropriate type. One-dimensional arrays that aren't zero-based, and multi-dimensional arrays, are created using newobj rather than newarr. More commonly, they are created using the methods of System.Array class in the Base Framework. Exceptions: OutOfMemoryException is thrown if there is insufficient memory to satisfy the request. OverflowException is thrown if numElems is < 0. Verifiability: Correct CIL ensures that etype is a valid typeref or typedef token. 4.20 newobj Create a New Object
Stack Transition: …, arg1, … argN …, obj Description: The newobj instruction creates a new object or a new instance of a value type. ctor is a metadata token (a methodref or methodef that must be marked as a constructor; see Partition II) that indicates the name, class, and signature of the constructor to call. If a constructor exactly matching the indicated name, class, and signature cannot be found, MissingMethodException is thrown. The newobj instruction allocates a new instance of the class associated with constructor and initializes all the fields in the new instance to 0 (of the proper type) or null as appropriate. It then calls the constructor with the given arguments along with the newly created instance. After the constructor has been called, the now initialized object reference is pushed onto the stack. From the constructor's point of view, the uninitialized object is argument 0 and the other arguments passed to newobj follow in order. All zero-based, one-dimensional arrays are created using newarr, not newobj. On the other hand, all other arrays (more than one dimension, or one-dimensional but not zero-based) are created using newobj. Value types are not usually created using newobj. They are usually allocated either as arguments or local variables, using newarr (for zero-based, one-dimensional arrays), or as fields of objects. Once allocated, they are initialized using initobj. However, the newobj instruction can be used to create a new instance of a value type on the stack, that can then be passed as an argument, stored in a local, etc. Exceptions: OutOfMemoryException is thrown if there is insufficient memory to satisfy the request. MissingMethodException is thrown if a constructor method with the indicated name, class, and signature could not be found. This is typically detected when CIL is converted to native code, rather than at runtime. Verifiability: Correct CIL ensures that constructor is a valid methodref or methoddef token, and that the arguments on the stack are compatible with those expected by the constructor. Verification considers a delegate constructor as a special case, checking that the method pointer passed in as the second argument, of type native int, does indeed refer to a method of the correct type. 4.21 refanytype Load the Type Out of a Typed Reference
Stack Transition: …, TypedRef …, type Description: Retrieves the type token embedded in TypedRef. See the mkrefany instruction [Partition III, section 4.18]. Exceptions: None. Verifiability: Correct CIL ensures that TypedRef is a valid typed reference (created by a previous call to mkrefany). The refanytype instruction is always verifiable. 4.22 refanyval Load the Address Out of a Typed Reference
Stack Transition: …, TypedRef …, address Description: Retrieves the address (of type &) embedded in TypedRef. The type of reference in TypedRef must match the type specified by type (a metadata token, either a typedef or a typeref; see Partition II). See the mkrefany instruction [Partition III, section 4.18]. Exceptions: InvalidCastException is thrown if type is not identical to the type stored in the TypedRef (i.e., the class supplied to the mkrefany instruction that constructed that TypedRef). TypeLoadException is thrown if type cannot be found. Verifiability: Correct CIL ensures that TypedRef is a valid typed reference (created by a previous call to mkrefany). The refanyval instruction is always verifiable. 4.23 rethrow Rethrow the Current Exception
Stack Transition: …, …, Description: The rethrow instruction is only permitted within the body of a catch handler (see Partition I [sections 12.4.2.5 through 12.4.2.8]). It throws the same exception that was caught by this handler.
Exceptions: The original exception is thrown. Verifiability: Correct CIL uses this instruction only within the body of a catch handler (not of any exception handlers embedded within that catch handler). If a rethrow occurs elsewhere, then an exception will be thrown, but precisely which exception is undefined. 4.24 sizeof Load the Size in Bytes of a Value Type
Stack Transition: …, …, size (4 bytes, unsigned) Description: Returns the size, in bytes, of a value type. valueType must be a metadata token (a typeref or typedef; see Partition II) that specifies a value type. RATIONALE The definition of a value type can change between the time the CIL is generated and the time that it is loaded for execution. Thus, the size of the type is not always known when the CIL is generated. The sizeof instruction allows CIL code to determine the size at runtime without the need to call into the Framework class library. The computation can occur entirely at runtime or at CIL-to-native-code compilation time. sizeof returns the total size that would be occupied by each element in an array of this value type including any padding the implementation chooses to add. Specifically, array elements lie sizeof bytes apart.
Exceptions: None. Verifiability: Correct CIL ensures that valueType is a typeref or typedef referring to a value type. It is always verifiable. 4.25 stelem.<type> Store an Element of an Array
Stack Transition: …, array, index, value …, Description: The stelem instruction replaces the value of the element with zero-based index index (of type int32 or native int) in the one-dimensional array array with value. Arrays are objects and hence represented by a value of type O. Note that stelem.ref implicitly casts value to the element type of array before assigning the value to the array element. This cast can fail, even for verified code. Thus the stelem.ref instruction may throw the ArrayTypeMismatchException. For one-dimensional arrays that aren't zero-based, and for multi-dimensional arrays, the array class provides a StoreElement method. Exceptions: NullReferenceException is thrown if array is null. IndexOutOfRangeException is thrown if index is negative, or larger than the bound of array. ArrayTypeMismatchException is thrown if array doesn't hold elements of the required type. Verifiability: Correct CIL requires that array be a zero-based, one-dimensional array whose declared element type matches exactly the type for this particular instruction suffix (e.g., stelem.r4 can only be applied to a zero-based, one-dimensional array of float32s), and also that index lies within the bounds of array. 4.26 stfld Store into a Field of an Object
Stack Transition: …, obj, value …, Description: The stfld instruction replaces the value of a field of an obj (an O) or via a pointer (type native int, or &) with value. field is a metadata token (a fieldref or fielddef; see Partition II) that refers to a field member reference. stfld pops the value and the object reference off the stack and updates the object. The stfld instruction may have a prefix of either or both of unaligned. and volatile.. Exceptions: NullReferenceException is thrown if obj is null and the field isn't static. MissingFieldException is thrown if field is not found in the metadata. This is typically checked when CIL is converted to native code, not at runtime. Verifiability: Correct CIL ensures that field is a valid token referring to a field, and that obj and value will always have types appropriate for the assignment being performed. For verifiable code, obj may not be an unmanaged pointer. NOTE Using stfld to change the value of a static, init-only field outside the body of the class initializer may lead to unpredictable behavior. It cannot, however, compromise memory integrity or type safety, so it is not tested by verification. 4.27 stobj Store a Value Type from the Stack into Memory
Stack Transition: …, addr, valObj …, Description: The stobj instruction copies the value type valObj into the address specified by addr (a pointer of type native int, or &). The number of bytes copied depends on the size of the class represented by classTok. classTok is a metadata token (a typeref or typedef; see Partition II) representing a value type. It is unspecified what happens if valObj is not an instance of the class represented by classTok or if classTok does not represent a value type. The operation of the stobj instruction may be altered by an immediately preceding volatile. or unaligned. prefix instruction. Exceptions: TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that classTok is a metadata token representing a value type and that valObj is a pointer to a location containing an initialized value of the type specified by classTok. In addition, verifiable code requires that addr be a managed pointer to the type specified by classTok. 4.28 stsfld Store a Static Field of a Class
Stack Transition: …, val …, Description: The stsfld instruction replaces the value of a static field with a value from the stack. field is a metadata token (a fieldref or fielddef; see Partition II) that must refer to a static field member. stsfld pops the value off the stack and updates the static field with that value. The stsfld instruction may be prefixed by volatile.. Exceptions: MissingFieldException is thrown if field is not found in the metadata. This is typically checked when CIL is converted to native code, not at runtime. Verifiability: Correct CIL ensures that field is a valid token referring to a static field, and that value will always have a type appropriate for the assignment being performed. NOTE Using stsfld to change the value of a static, init-only field outside the body of the class initializer may lead to unpredictable behavior. It cannot, however, compromise memory integrity or type safety, so it is not tested by verification. 4.29 throw Throw an Exception
Stack Transition: …, object …, Description: The throw instruction throws the exception object (type O) on the stack. For details of the exception mechanism, see Partition I [sections 12.4.2.5 through 12.4.2.8]. NOTE While the CLI permits any object to be thrown, the Common Language Specification (CLS) describes a specific exception class that must be used for language interoperability. Exceptions: NullReferenceException is thrown if obj is null. Verifiability: Correct CIL ensures that class is a valid typeref token indicating a class, and that obj is always either null or an object reference i.e., of type O. 4.30 unbox Convert Boxed Value Type to Its Raw Form
Stack Transition: …, obj …, valueTypePtr Description: A value type has two separate representations (see Partition I [section 8.2 and its subsections]) within the CLI:
The unbox instruction converts obj (of type O), the boxed representation of a value type, to valueTypePtr (a managed pointer, type &), its unboxed form. valuetype is a metadata token (a typeref or typedef) indicating the type of value type contained within obj. If obj is not a boxed instance of valuetype, or if obj is a boxed enum and valuetype is not its underlying type, then this instruction will throw an InvalidCastException. Unlike box, which is required to make a copy of a value type for use in the object, unbox is not required to copy the value type from the object. Typically it simply computes the address of the value type that is already present inside of the boxed object. Exceptions: InvalidCastException is thrown if obj is not a boxed valuetype (or if obj is a boxed enum and valuetype is not its underlying type). NullReferenceException is thrown if obj is null. TypeLoadException is thrown if class cannot be found. This is typically detected when CIL is converted to native code rather than at runtime. Verifiability: Correct CIL ensures that valueType is a typeref or typedef metadata token for some value type, and that obj is always an object reference i.e., of type O and represents a boxed instance of a valuetype value type. |