HarmonyX
HarmonyX copied to clipboard
Label Jump
Transpiler has label issue for specific CIL.
Applying an empty Transpiler Patch to the following function will change the jump label position.
leave IL_002f
was modified to leave IL_0024
, causing unexpected execution.
using HarmonyLib;
using HarmonyLib.Tools;
using System.Reflection.Emit;
namespace Test
{
[HarmonyDebug]
public class Program
{
static void Test()
{
int i = 0;
try
{
if (i == 0)
{
try
{
Console.WriteLine("jump");
goto Label;
}
finally {}
}
Console.WriteLine("test");
Label:;
}
finally {}
}
[HarmonyPatch(typeof(Program), "Test")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> TestTranspiler(IEnumerable<CodeInstruction> instructions)
{
return instructions;
// temp solve
var codeMatcher = new CodeMatcher(instructions);
codeMatcher.MatchForward(false, new [] {new CodeMatch(OpCodes.Leave)});
codeMatcher.Insert(codeMatcher.Instruction);
return codeMatcher.InstructionEnumeration();
}
static void Main(string[] args)
{
HarmonyFileLog.Enabled = true;
Harmony.CreateAndPatchAll(typeof(Program));
Test();
}
}
}
log
[IL] Generated patch (System.Void DMD<Test.Program::Test>?66572856::Test.Program::Test()):
.locals init (
System.Int32 V_0
System.Boolean V_1
)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
.try
{
IL_0003: nop
IL_0004: ldloc.0
IL_0005: ldc.i4.0
IL_0006: ceq
IL_0008: stloc.1
IL_0009: ldloc.1
IL_000a: brfalse IL_0024
IL_000f: nop
.try
{
IL_0010: nop
IL_0011: ldstr "jump"
IL_0016: call System.Void System.Console::WriteLine(System.String)
IL_001b: nop
IL_001c: leave IL_0024
} // end .try
finally
{
IL_0021: nop
IL_0022: nop
IL_0023: endfinally
} // end handler (finally)
IL_0024: ldstr "test"
IL_0029: call System.Void System.Console::WriteLine(System.String)
IL_002e: nop
IL_002f: nop
IL_0030: nop
IL_0031: nop
IL_0032: leave IL_003a
} // end .try
finally
{
IL_0037: nop
IL_0038: nop
IL_0039: endfinally
} // end handler (finally)
IL_003a: ret
Likely related to #77
Fixed in latest releases.