Skip to content

Commit

Permalink
CodeMatch: use CodeInstruction ToString for simple matches
Browse files Browse the repository at this point in the history
Allows to use Code.* as CodeInstruction replacement
  • Loading branch information
ghorsington committed Mar 24, 2022
1 parent 0b0f190 commit 17f3474
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 23 deletions.
21 changes: 11 additions & 10 deletions Harmony/Tools/CodeMatcher/CodeMatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;

namespace HarmonyLib
{
Expand Down Expand Up @@ -103,24 +104,24 @@ internal bool Matches(List<CodeInstruction> codes, CodeInstruction instruction)
///
public override string ToString()
{
var result = "[";
var sb = new StringBuilder();
if (name != null)
result += $"{name}: ";
sb.Append($"{name}: ");
if (opcodes.Count > 0)
result += $"opcodes={opcodes.Union(new []{ opcode }).Where(o => o.Name != null).Join()} ";
sb.Append($"opcodes={opcodes.Union(new[] {opcode}).Where(o => o.Size != 0).Join()} ");
if (operands.Count > 0)
result += $"operands={operands.Union(new []{ operand }).Where(o => o != null).Join()} ";
sb.Append($"operands={operands.Union(new[] {operand}).Where(o => o != null).Join()} ");
if (labels.Count > 0)
result += $"labels={labels.Join()} ";
sb.Append($"labels={labels.Join()} ");
if (blocks.Count > 0)
result += $"blocks={blocks.Join()} ";
sb.Append($"blocks={blocks.Join()} ");
if (jumpsFrom.Count > 0)
result += $"jumpsFrom={jumpsFrom.Join()} ";
sb.Append($"jumpsFrom={jumpsFrom.Join()} ");
if (jumpsTo.Count > 0)
result += $"jumpsTo={jumpsTo.Join()} ";
sb.Append($"jumpsTo={jumpsTo.Join()} ");
if (predicate != null)
result += "predicate=yes ";
return $"{result.TrimEnd()}]";
sb.Append("predicate=yes ");
return sb.Length != 0 ? $"[{sb.ToString().Trim()}]" : base.ToString();
}

/// <summary>Creates a new code match for an opcode</summary>
Expand Down
36 changes: 23 additions & 13 deletions HarmonyTests/Tools/TestCodeMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using static HarmonyLib.Code;

namespace HarmonyLibTests.Tools;

Expand All @@ -29,23 +30,32 @@ public void TestRepeatReplaceMultiple()
err => throw new Exception($"Nothing replaced .{err}"))
.Instructions();

var writeLine = AccessTools.Method(typeof(Console), nameof(Console.WriteLine), new[] {typeof(string)});
AssertSameCode(result,
new[]
new CodeInstruction[]
{
"ldarg.0 NULL", "call void HarmonyLibTests.Assets.CodeMatcherClass1::Foo()",
"call void HarmonyLibTests.Assets.CodeMatcherClass1::Bar()", "ldstr \"Foo!\"",
"call static void Console::WriteLine(string value)", "ldarg.0 NULL",
"call void HarmonyLibTests.Assets.CodeMatcherClass1::Foo()",
"call void HarmonyLibTests.Assets.CodeMatcherClass1::Bar()", "ldstr \"Foo!\"",
"call static void Console::WriteLine(string value)", "ldarg.0 NULL",
"call void HarmonyLibTests.Assets.CodeMatcherClass1::Foo()",
"call void HarmonyLibTests.Assets.CodeMatcherClass1::Bar()", "ldstr \"Foo!\"",
"call static void Console::WriteLine(string value)", "ret NULL"
});
Ldarg_0, //
Call[matchTarget], //
Call[matchReplacement], //
Ldstr["Foo!"], //
Call[writeLine], //
Ldarg_0, //
Call[matchTarget], //
Call[matchReplacement], //
Ldstr["Foo!"], //
Call[writeLine], //
Ldarg_0, //
Call[matchTarget], //
Call[matchReplacement], //
Ldstr["Foo!"], //
Call[writeLine], //
Ret //
}
);
}

private void AssertSameCode(List<CodeInstruction> ins, string[] expected)
private void AssertSameCode(List<CodeInstruction> ins, CodeInstruction[] expected)
{
Assert.AreEqual(expected, ins.Select(i => i.ToString()).ToArray());
Assert.AreEqual(expected.Select(i => i.ToString()), ins.Select(i => i.ToString()).ToArray());
}
}

0 comments on commit 17f3474

Please sign in to comment.