CodeContainers hold the body of
Method
objects, e.g. a list of
Instruction
objects (including labels), along with any
Operand object required by each
instructions.
Code containers are usually constructed as part of the
destruction of the derived class Method, and the constructor
will not be accessed by user code. It does however
allow setting of standard CIL flags.
CodeContainer(Qualifiers Flags) :flags_(Flags);
An instruction may be added to the end of the container.
void
AddInstruction(Instruction *instruction);
Sometimes it is interesting to examine or remove the last
instruction generated.
Instruction
*RemoveLastInstruction();
Instruction
*LastInstruction() const;
When the instructions have been generated, one
can validate them directly, or one can wait to call
Method::Optimize(), which will validate them.
Validation may throw a
PELibError
exception, with information about what is wrong.
Presently the CodeContainer will throw exceptions for misuse
of labels, and
Param and
Local object indexes out of range for
the instruction in use. Method::Optimize will also
check that the stack remains balanced though.
void
ValidateInstructions();
void
ValidateSEH();
The CIL qualifiers may be examined or modified.
Qualifiers
&Flags() { return flags_; }
const
Qualifiers &Flags() const { return flags_; }
The parent container may be examined or set.
Normally, the set would take place automatically when the Method
is added to an
AssemblyDef,
Class or
Namespace.
This is done in the
DataContainer
interface.
void
SetContainer(DataContainer *parent) { parent_ = parent; }
DataContainer
*GetContainer() const { return parent_; }