Files
Torch/Torch/Managers/PatchManager/PatchUtilities.cs
Westin Miller f7d45ca338 Add more advanced debugging to patcher
Support multiple try-catch operations on a single instruction
Replace long branch with short branch instructions where possible
Dump generated IL at three stages to a file.
2018-10-07 00:44:36 -07:00

77 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using NLog;
using Torch.Managers.PatchManager.MSIL;
using Torch.Managers.PatchManager.Transpile;
using Torch.Utils;
namespace Torch.Managers.PatchManager
{
/// <summary>
/// Functions that let you read and write MSIL to methods directly.
/// </summary>
public class PatchUtilities
{
/// <summary>
/// Gets the content of a method as an instruction stream
/// </summary>
/// <param name="method">Method to examine</param>
/// <returns>instruction stream</returns>
public static IEnumerable<MsilInstruction> ReadInstructions(MethodBase method)
{
var context = new MethodContext(method);
context.Read();
return context.Instructions;
}
/// <summary>
/// Writes the given instruction stream to the given IL generator, fixing short branch instructions.
/// </summary>
/// <param name="insn">Instruction stream</param>
/// <param name="generator">Output</param>
public static void EmitInstructions(IEnumerable<MsilInstruction> insn, LoggingIlGenerator generator)
{
MethodTranspiler.EmitMethod(insn.ToList(), generator);
}
public delegate void DelPrintIntegrityInfo(bool error, string msg);
/// <summary>
/// Analyzes the integrity of a set of instructions.
/// </summary>
/// <param name="handler">Logger</param>
/// <param name="instructions">instructions</param>
public static void IntegrityAnalysis(DelPrintIntegrityInfo handler, IReadOnlyList<MsilInstruction> instructions)
{
MethodTranspiler.IntegrityAnalysis(handler, instructions);
}
#pragma warning disable 649
[ReflectedStaticMethod(Type = typeof(RuntimeHelpers), Name = "_CompileMethod", OverrideTypeNames = new[] {"System.IRuntimeMethodInfo"})]
private static Action<object> _compileDynamicMethod;
[ReflectedMethod(Name = "GetMethodInfo")]
private static Func<RuntimeMethodHandle, object> _getMethodInfo;
[ReflectedMethod(Name = "GetMethodDescriptor")]
private static Func<DynamicMethod, RuntimeMethodHandle> _getMethodHandle;
#pragma warning restore 649
/// <summary>
/// Forces the given dynamic method to be compiled
/// </summary>
/// <param name="method"></param>
public static void Compile(DynamicMethod method)
{
// Force it to compile
RuntimeMethodHandle handle = _getMethodHandle.Invoke(method);
object runtimeMethodInfo = _getMethodInfo.Invoke(handle);
_compileDynamicMethod.Invoke(runtimeMethodInfo);
}
}
}