Introduction
These instructions work on the members and types the metadata describes. Each carries a token as its operand: a field token (a Field row in this assembly, or a
MemberRef for a field of another), or a type token (TypeDef, TypeRef or TypeSpec for a generic or array type). Boxing is how a
value type (an int, a struct) becomes an object: box copies it into a new heap object, and unbox or unbox.any gets the value out again.
Exceptions and verifiability, for the whole page. Using a field or type the loader cannot find throws MissingFieldException, MissingMethodException or
TypeLoadException, and touching a field the code may not access throws FieldAccessException. Reading or writing a field of a null object throws
NullReferenceException. The first use of a static field, or a call, can run the type’s static constructor, which may throw TypeInitializationException.
Fields
| Opcode | Instruction | Stack | What it does | Exceptions · verifiability |
|---|---|---|---|---|
7B token | ldfld field | …, object → …, value | Pops an object reference (or a managed pointer to a value type, or a value type itself) and pushes the value of the field. | NullReferenceException if the object is null. Verifiable. |
7C token | ldflda field | …, object → …, address | Pops an object or pointer and pushes the address of the field as a managed pointer (or, from an unmanaged pointer, an unmanaged one). | NullReferenceException if the object is null. Verifiable through managed pointers. |
7D token | stfld field | …, object, value → … | Pops a value and an object (or pointer) and stores the value in the field, narrowing it to the field’s type. | NullReferenceException if the object is null. Storing into an initonly field outside the constructor is not verifiable. |
7E token | ldsfld field | … → …, value | Pushes the value of a static field. It may first run the class’s static constructor. | As the page introduction. |
7F token | ldsflda field | … → …, address | Pushes the address of a static field as a managed pointer. | As the page introduction. |
80 token | stsfld field | …, value → … | Pops a value into a static field. | As the page introduction. |
Casts, boxing and tests
| Opcode | Instruction | Stack | What it does | Exceptions · verifiability |
|---|---|---|---|---|
74 token | castclass type | …, object → …, object | Checks that the object is an instance of the type (or null, which always passes) and pushes the same reference, now typed as the type. The type may be a class, an interface or a generic instantiation. | InvalidCastException if it is not. Verifiable. |
75 token | isinst type | …, object → …, object | Pushes the object if it is an instance of the type, otherwise null. C# is and as compile to it. | None. Verifiable. |
8C token | box type | …, value → …, object | For a value type, allocates a heap object and copies the value into it; the result is a reference. For a reference type it leaves the reference as it is. Boxing a Nullable<T> that has no value gives null. | OutOfMemoryException. Verifiable. |
79 token | unbox type | …, object → …, address | Pops a boxed value and pushes a managed pointer to the value inside the box (so it can be read, or changed in place). | NullReferenceException for null; InvalidCastException if the box holds another type. Verifiable. |
A5 token | unbox.any type | …, object → …, value | For a value type, unboxes and pushes the value itself; for a reference type it is the same as castclass. It is what generic code uses when it does not know which kind T is. | NullReferenceException for null (except for Nullable<T>, which gives its empty value); InvalidCastException. |
Runtime handles, sizes and typed references
| Opcode | Instruction | Stack | What it does | Exceptions · verifiability |
|---|---|---|---|---|
D0 token | ldtoken token | … → …, handle | Pushes a runtime handle for the type, field or method the token names: a RuntimeTypeHandle, RuntimeFieldHandle or RuntimeMethodHandle (value types wrapping a native pointer). C# typeof(T) is ldtoken then a call to Type.GetTypeFromHandle. | None. Verifiable. |
FE 1C token | sizeof type | … → …, int32 | Pushes the size in bytes of a value of the type, as the runtime lays it out. For a reference type it is the size of a reference. | None. Verifiable. |
C6 token | mkrefany type | …, address → …, typedref | Pops a pointer and pushes a typed reference: a pointer together with the type token, as C# __makeref builds it. | None. Verifiable. |
C2 token | refanyval type | …, typedref → …, address | Pops a typed reference and pushes the pointer it holds, if its type is the one named. | InvalidCastException if the type differs. Verifiable. |
FE 1D | refanytype | …, typedref → …, handle | Pops a typed reference and pushes the RuntimeTypeHandle of the type it holds. | None. Verifiable. |
Not described
Known, not yet covered
- Static constructor timing: exactly when the type initializer runs (at first access, or earlier for types marked
beforefieldinit) is not described.
Unknown
- How a runtime lays out a value type for
sizeof(padding, alignment), which the specification leaves to the implementation.
Links
Reference
- ECMA-335 – partition III: ldfld, ldflda, stfld, ldsfld, ldsflda, stsfld, castclass, isinst, box, unbox, unbox.any, ldtoken, sizeof, mkrefany, refanyval, refanytype
- .NET tables – the Field, TypeDef, TypeRef, TypeSpec and MemberRef tables the tokens point into