HarmonyX icon indicating copy to clipboard operation
HarmonyX copied to clipboard

Label Jump

Open littlecattle opened this issue 8 months ago • 1 comments

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

littlecattle avatar Oct 22 '23 03:10 littlecattle

Likely related to #77

ManlyMarco avatar Oct 22 '23 12:10 ManlyMarco

Fixed in latest releases.

ManlyMarco avatar May 16 '24 23:05 ManlyMarco