Casting Instruction.Value

I'm getting runtime errors (Specified cast is not valid) when attempting to cast Instruction.Value (for Stloc and Ldloc OpCode families) to an integer e.g.:



int variableIndex;
if(instruction.OpCode == OpCode.Stloc_S)
{
    variableIndex = (int)instruction.Value;
}

 

An example line raising an error is

SqlDataReader dr = cmd.ExecuteReader();

which compiles to the IL:

IL_00b8:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlDataReader [System.Data]System.Data.SqlClient.SqlCommand::ExecuteReader()
IL_00bd:  stloc.s    dr

According to the MSDN documentation, stloc.c has argument index of type int (unsigned int8, to be precise) whereas this appears to be using a string rather than a local variable index. dr is referenced in the locals section at the top of the dissembly as

[4] class [System.Data]System.Data.SqlClient.SqlDataReader dr

So I'm wondering whether a) I'm casting incorrectly or b) instruction.Value has the string indentifier, and not the declared index

Cheers,
James.




Answer this question

Casting Instruction.Value

  • Andie Kurniawan

    Rather than requiring users to retrieve an integer value and index into the Locals available in the method, we simply place the Local in the op code value. This also prevents boxing. As you can see, ildasm does something similar, it maps the argument for the opcode to the actual local (dr, in the example you cited) for clarity when looking at the disassembly.

    So, just cast the Value to a Local instance. In the future, if you have questions about the type of an item which is stored in Value, you can either dump its type name (via GetType()) or set a breakpoint in the debugger. On retrieving and expanding the OpCode instance, the debugger will tell you the type that's stored in the Value member.

    Michael

  • Casting Instruction.Value