-
-
Notifications
You must be signed in to change notification settings - Fork 142
Open
Labels
Description
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_0000Additional 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.
Reactions are currently unavailable