cil

CIL instruction "isinst <valuetype>"


The ECMA Common Language Infrastructure documentation says this about the CIL "isinst class" instruction:

Correct CIL ensures that class is a valid typeref or typedef or typespec token indicating a class, and that obj is always either null or an object reference.

This implies that a valuetype is not allowed, right? But mscorlib.dll contains a method System.RuntimeTypeHandle::Equals(object obj) with the following instruction:

IL_0001: isinst System.RuntimeTypeHandle

And System.RuntimeTypeHandle is a valuetype. Can anybody put me right here?


Solution

  • Have a look at the declaration of RuntimeTypeHandle:

    .class public sequential ansi serializable sealed beforefieldinit RuntimeTypeHandle
        extends     System.ValueType
        implements  System.Runtime.Serialization.ISerializable
    

    Although RuntimeTypeHandle is declared as a struct its representation in CIL is some kind of special class. In other words, you can imagine structs as special classes that inherit from System.ValueType and whose attributes follow a strict order.

    With that in mind isinst would be callable with RuntimeTypeHandle. For what I interpret isinst is not limited to reference types at all as long as there is a class representing the type.

    Let's say we write in C#:

    var i = 4;
    var b = i is Int32;
    

    We get a compiler warning

    Warning: The given expression is always of the provided ('int') type.

    What happens? We assign 4 to i. ibecoms an int. On the next line iis being auto-boxed to its corresponding ReferenceType (class), so that the warning is obvious. We could even write

    var b = i is int;
    

    I hope this can contribute to some kind of clearification on this topic.