An Instruction is placed in a
Method,
as part of the definition of the runtime behavior of the
method. Instructions have various types of
Operands, which modify the behavior of
the instruction.
Each MSIL instruction has an enumerated name, formed by adding
i_ at the front and replacing dots with underscores.
For example:
add becomes i_add
ldc.i4.4 becomes i_ldc_i4_4
there are three special instructions
i_label, // puts a label at this point in the
instruction stream
i_comment, // puts a comment at this point in the instruction
stream
i_seh, // puts an SEH region boundary at his point
in the module code.
The instruction may be constructed either directly or through an
Allocator object.
The first form of the constructor creates a generic instruction,
including a label. The second form embeds a comment
into the .IL source file. The third form embeds an
SEH boundary.
Note that the complete list of instructions as listed in ECMA-335
is available for use.
Instruction(iop
Op, Operand *Operand);
Instruction(iop Op, std::string Text);
Instruction(iseh type, bool begin, Type *catchType);
Access the opcode
iop OpCode() const
{ return op_; }
void
OpCode(iop Op) { op_ = Op; }
Add a lable to a 'switch' instruction. Labels must be
added in order.
void
AddCaseLabel(std::string label);
Get the list of switch labels
std::list<std::string> * GetSwitches() { return
switches_; }
Get an operand for instructions that don't require an
operand.
void
NullOperand(Allocator &allocator);
Retrieve the operand.
Operand
*GetOperand() const { return operand_; }
Retrieve the comment text.
std::string
Text() const { return text_; }
Retrieve any label associated with the
instruction. Note that labels are strings in this
implementation (they are converted to offsets when generating
CIL code).
std::string
Label() const;
Retrieve the size of the instruction.
int
InstructionSize();
Retrieve the stack usage of the instruction. 0 =
no effect, >0 = stack grows, <0 = stack shrinks
int StackUsage();