Search code examples
c#ilinstructions

IL Instructions not exposed by C#


What IL instructions are not exposed by C#?

I'm referring to instructions like sizeof and cpblk - there's no class or command that executes these instructions (sizeof in C# is computed at compile time, not at runtime AFAIK).

Others?

EDIT: The reason I'm asking this (and hopefully this will make my question a little more valid) is because I'm working on a small library which will provide the functionality of these instructions. sizeof and cpblk are already implemented - I wanted to know what others I may have missed before moving on.

EDIT2: Using Eric's answer, I've compiled a list of instructions:

  • Break
  • Jmp
  • Calli
  • Cpobj
  • Ckfinite
  • Prefix[1-7]
  • Prefixref
  • Endfilter
  • Unaligned
  • Tailcall
  • Cpblk
  • Initblk

There were a number of other instructions which were not included in the list, which I'm separating because they're basically shortcuts for other instructions (compressed to save time and space):

  • Ldarg[0-3]
  • Ldloc[0-3]
  • Stloc[0-3]
  • Ldc_[I4_[M1/S/0-8]/I8/R4/R8]
  • Ldind_[I1/U1/I2/U2/I4/U4/I8/R4/R8]
  • Stind_[I1/I2/I4/I8/R4/R8]
  • Conv_[I1/I2/I4/I8/R4/R8/U4/U8/U2/U1]
  • Conv_Ovf_[I1/I2/I4/I8/U1/U2/U4/U8]
  • Conv_Ovf_[I1/I2/I4/I8/U1/U2/U4/U8]_Un
  • Ldelem_[I1/I2/I4/I8/U1/U2/U4/R4/R8]
  • Stelem_[I1/I2/I4/I8/R4/R8]

Solution

  • I'm referring to instructions like sizeof and cpblk - there's no class or command that executes these instructions (sizeof in C# is computed at compile time, not at runtime AFAIK).

    This is incorrect. sizeof(int) will be treated as the compile-time constant 4, of course, but there are plenty of situations (all in unsafe code) where the compiler relies upon the runtime to determine what the memory size of a structure is. Consider, for example, a structure that contains two pointers. It would be of size 8 on a 32 bit machine but 16 on a 64 bit machine. In those circumstances the compiler will generate the sizeof opcode.

    Others?

    I don't have a list of all the opcodes we don't produce -- I have never had a need to build such a list. However, off the top of my head I can tell you that there is no way to generate an "call indirect" (calli) instruction in C#; we are occasionally asked for that feature as it would improve performance of certain interop scenarios.

    UPDATE: I just grepped the source code to produce a list of opcodes we definitely do produce. They are:

    add
    add_ovf
    add_ovf_un
    and
    arglist
    beq
    beq_s
    bge
    bge_s
    bge_un
    bge_un_s
    bgt
    bgt_s
    bgt_un
    bgt_un_s
    ble
    ble_s
    ble_un
    ble_un_s
    blt
    blt_s
    blt_un
    blt_un_s
    bne_un
    bne_un_s
    box
    br
    br_s
    brfalse
    brfalse_s
    brtrue
    brtrue_s
    call
    callvirt
    castclass
    ceq
    cgt
    cgt_un
    clt
    clt_un
    constrained
    conv_i
    conv_ovf_i
    conv_ovf_i_un
    conv_ovf_u
    conv_ovf_u_un
    conv_r
    conv_r_un
    conv_u
    div
    div_un
    dup
    endfinally
    initobj
    isinst
    ldarg
    ldarg_
    ldarg_s
    ldarga
    ldarga_s
    ldc_i
    ldc_r
    ldelem
    ldelem_i
    ldelem_r
    ldelem_ref
    ldelem_u
    ldelema
    ldfld
    ldflda
    ldftn
    ldind_i
    ldind_r
    ldind_ref
    ldind_u
    ldlen
    ldloc
    ldloc_
    ldloc_s
    ldloca
    ldloca_s
    ldnull
    ldobj
    ldsfld
    ldsflda
    ldstr
    ldtoken
    ldvirtftn
    leave
    leave_s
    localloc
    mkrefany
    mul
    mul_ovf
    mul_ovf_un
    neg
    newarr
    newobj
    nop
    not
    or
    pop
    readonly
    refanytype
    refanyval
    rem
    rem_un
    ret
    rethrow
    shl
    shr
    shr_un
    sizeof
    starg
    starg_s
    stelem
    stelem_i
    stelem_r
    stelem_ref
    stfld
    stind_i
    stind_r
    stind_ref
    stloc
    stloc_s
    stobj
    stsfld
    sub
    sub_ovf
    sub_ovf_un
    switch
    throw
    unbox_any
    volatile
    xor

    I'm not going to guarantee that that's all of them, but that is certainly most of them. You can then compare that against a list of all the opcodes and see what is missing.