Skip to content

Commit 6746d17

Browse files
kohanisManlyMarco
authored andcommitted
CecilEmitter.Dump: Adding test for ILLabel dumping
1 parent c4392ee commit 6746d17

File tree

2 files changed

+58
-15
lines changed

2 files changed

+58
-15
lines changed

Harmony/Internal/Util/CecilEmitter.cs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,33 @@ internal static class CecilEmitter
2828
typeof(UnverifiableCodeAttribute).GetConstructor(Type.EmptyTypes);
2929

3030
public static void Dump(MethodDefinition md, IEnumerable<string> dumpPaths, MethodBase original = null)
31+
{
32+
using var module = DumpImpl(md, original);
33+
34+
foreach (var settingsDumpPath in dumpPaths)
35+
{
36+
var fullPath = Path.GetFullPath(settingsDumpPath);
37+
try
38+
{
39+
Directory.CreateDirectory(fullPath);
40+
using var stream = File.OpenWrite(Path.Combine(fullPath, $"{module.Name}.dll"));
41+
module.Write(stream);
42+
}
43+
catch (Exception e)
44+
{
45+
Logger.Log(Logger.LogChannel.Error, () => $"Failed to dump {md.GetID(simple: true)} to {fullPath}: {e}");
46+
}
47+
}
48+
}
49+
50+
internal static ModuleDefinition DumpImpl(MethodDefinition md, MethodBase original = null)
3151
{
3252
if(md.Body is null)
3353
throw new ArgumentException($"Body of MethodDefinition '{md.Name}' to dump is null");
3454

3555
var name = $"HarmonyDump.{SanitizeTypeName(md.GetID(withType: false, simple: true))}.{Guid.NewGuid().GetHashCode():X8}";
3656
var originalName = (original?.Name ?? md.Name).Replace('.', '_');
37-
using var module = ModuleDefinition.CreateModule(name,
57+
var module = ModuleDefinition.CreateModule(name,
3858
new ModuleParameters
3959
{
4060
Kind = ModuleKind.Dll, ReflectionImporterProvider = MMReflectionImporter.ProviderNoDefault
@@ -114,20 +134,7 @@ public static void Dump(MethodDefinition md, IEnumerable<string> dumpPaths, Meth
114134
new ParameterDefinition("<>_this", ParameterAttributes.None, type.Relink(relinker, clone)));
115135
}
116136

117-
foreach (var settingsDumpPath in dumpPaths)
118-
{
119-
var fullPath = Path.GetFullPath(settingsDumpPath);
120-
try
121-
{
122-
Directory.CreateDirectory(fullPath);
123-
using var stream = File.OpenWrite(Path.Combine(fullPath, $"{module.Name}.dll"));
124-
module.Write(stream);
125-
}
126-
catch (Exception e)
127-
{
128-
Logger.Log(Logger.LogChannel.Error, () => $"Failed to dump {md.GetID(simple: true)} to {fullPath}: {e}");
129-
}
130-
}
137+
return module;
131138
}
132139

133140
private static string SanitizeTypeName(string typeName)

HarmonyTests/Extras/Dump.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using HarmonyLib.Internal.Util;
2+
using HarmonyLibTests;
3+
using MonoMod.Cil;
4+
using MonoMod.Utils;
5+
using NUnit.Framework;
6+
using System;
7+
using System.Linq;
8+
9+
10+
namespace HarmonyTests.Extras;
11+
12+
[TestFixture]
13+
public class Dump : TestLogger
14+
{
15+
[Test]
16+
public void Test_DumpIlLabel()
17+
{
18+
using var dmd = new DynamicMethodDefinition("DumpIlLabelTestMethod", typeof(void), Type.EmptyTypes);
19+
var il = new ILContext(dmd.Definition);
20+
var cur = new ILCursor(il);
21+
22+
var label = cur.DefineLabel();
23+
cur.EmitBr(label);
24+
cur.EmitRet();
25+
label.Target = cur.Prev;
26+
27+
var method = cur.Method;
28+
29+
using var dumpedModule = CecilEmitter.DumpImpl(method);
30+
var dumpedMethod = dumpedModule.Types.SelectMany(i => i.Methods).FirstOrDefault();
31+
Assert.NotNull(dumpedMethod);
32+
33+
var instructions = dumpedMethod!.Body.Instructions;
34+
Assert.True(instructions[0].Operand == instructions[1]);
35+
}
36+
}

0 commit comments

Comments
 (0)