Use reflected manager for patch internals
This commit is contained in:
@@ -3,11 +3,17 @@ using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Torch.Utils;
|
||||
|
||||
namespace Torch.Managers.PatchManager
|
||||
{
|
||||
internal class AssemblyMemory
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[ReflectedMethod(Name = "GetMethodDescriptor")]
|
||||
private static Func<DynamicMethod, RuntimeMethodHandle> _getMethodHandle;
|
||||
#pragma warning restore 649
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address, in RAM, where the body of a method starts.
|
||||
/// </summary>
|
||||
@@ -16,9 +22,8 @@ namespace Torch.Managers.PatchManager
|
||||
public static long GetMethodBodyStart(MethodBase method)
|
||||
{
|
||||
RuntimeMethodHandle handle;
|
||||
if (method is DynamicMethod)
|
||||
handle = (RuntimeMethodHandle)typeof(DynamicMethod).GetMethod("GetMethodDescriptor", BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.Invoke(method, new object[0]);
|
||||
if (method is DynamicMethod dyn)
|
||||
handle = _getMethodHandle.Invoke(dyn);
|
||||
else
|
||||
handle = method.MethodHandle;
|
||||
RuntimeHelpers.PrepareMethod(handle);
|
||||
|
@@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using NLog;
|
||||
using Torch.Managers.PatchManager.Transpile;
|
||||
using Torch.Utils;
|
||||
|
||||
namespace Torch.Managers.PatchManager
|
||||
{
|
||||
@@ -76,21 +77,25 @@ namespace Torch.Managers.PatchManager
|
||||
private const string INSTANCE_PARAMETER = "__instance";
|
||||
private const string RESULT_PARAMETER = "__result";
|
||||
|
||||
#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
|
||||
|
||||
public DynamicMethod ComposePatchedMethod()
|
||||
{
|
||||
var method = AllocatePatchMethod();
|
||||
DynamicMethod method = AllocatePatchMethod();
|
||||
var generator = new LoggingIlGenerator(method.GetILGenerator());
|
||||
EmitPatched(generator);
|
||||
|
||||
// Force it to compile
|
||||
const BindingFlags nonPublicInstance = BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
const BindingFlags nonPublicStatic = BindingFlags.NonPublic | BindingFlags.Static;
|
||||
var compileMethod = typeof(RuntimeHelpers).GetMethod("_CompileMethod", nonPublicStatic);
|
||||
var getMethodDescriptor = typeof(DynamicMethod).GetMethod("GetMethodDescriptor", nonPublicInstance);
|
||||
var handle = (RuntimeMethodHandle)getMethodDescriptor.Invoke(method, new object[0]);
|
||||
var getMethodInfo = typeof(RuntimeMethodHandle).GetMethod("GetMethodInfo", nonPublicInstance);
|
||||
var runtimeMethodInfo = getMethodInfo.Invoke(handle, new object[0]);
|
||||
compileMethod.Invoke(null, new[] { runtimeMethodInfo });
|
||||
RuntimeMethodHandle handle = _getMethodHandle.Invoke(method);
|
||||
object runtimeMethodInfo = _getMethodInfo.Invoke(handle);
|
||||
_compileDynamicMethod.Invoke(runtimeMethodInfo);
|
||||
return method;
|
||||
}
|
||||
#endregion
|
||||
|
Reference in New Issue
Block a user