Description
ILCursor.EmitBr and such methods which take Instruction as an argument will emit branch instructions that branch to themselves when the instruction passed as an argument equals ILCursor.Next
This happens because these methods use MarkLabel:
public global::MonoMod.Cil.ILCursor EmitBr(Instruction operand) =>
_Insert(IL.Create(OpCodes.Br, MarkLabel(operand)));
And this overload of MarkLabel has an undocumented dangerous feature (as seen by the existence of this bug report):
/// <summary>
/// Create a new label targetting a specific instruction.
/// </summary>
/// <param name="inst">The instruction to target</param>
/// <returns>The created label</returns>
public ILLabel MarkLabel(Instruction inst)
{
var label = Context.DefineLabel();
if (inst == Next) // <---- !!!!!!!!!!!!!
{
// !!! Description of method:
// Set the target of a label to the current position (<c>label.Target = Next</c>) and moves after it.
MarkLabel(label);
return label;
}
label.Target = inst;
return label;
}
Example
static void MyILHook(ILContext il)
{
ILCursor c = new(il);
c.EmitBr(c.Next!);
}
The emitted instruction looks like the following:
┌ Incoming branches: IL_0000;
IL_0000: br IL_0000
Additional thoughts:
Should this feature in the MarkLabel method even exist? Having the method do completely different things depending on some condition seems like a potential disaster. At least it needs to be documented.
Description
ILCursor.EmitBr and such methods which take Instruction as an argument will emit branch instructions that branch to themselves when the instruction passed as an argument equals ILCursor.Next
This happens because these methods use MarkLabel:
And this overload of MarkLabel has an undocumented dangerous feature (as seen by the existence of this bug report):
Example
The emitted instruction looks like the following:
Additional thoughts:
Should this feature in the MarkLabel method even exist? Having the method do completely different things depending on some condition seems like a potential disaster. At least it needs to be documented.