Allow reflection for NativeInterface + statically reference GetFunctionAddress so it gets compiled
This commit is contained in:
parent
ccfcdd4219
commit
c3083076ee
@ -7,15 +7,17 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
private const string SupervisorCallName = nameof(NativeInterface.SupervisorCall);
|
||||
private const string BreakName = nameof(NativeInterface.Break);
|
||||
private const string UndefinedName = nameof(NativeInterface.Undefined);
|
||||
|
||||
public static void Brk(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeException op = (OpCodeException)context.CurrOp;
|
||||
|
||||
string name = nameof(NativeInterface.Break);
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id));
|
||||
context.Call(NativeInterface.Type.GetMethod(BreakName), Const(op.Address), Const(op.Id));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
@ -25,12 +27,10 @@ namespace ARMeilleure.Instructions
|
||||
public static void Svc(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeException op = (OpCodeException)context.CurrOp;
|
||||
|
||||
string name = nameof(NativeInterface.SupervisorCall);
|
||||
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id));
|
||||
context.Call(NativeInterface.Type.GetMethod(SupervisorCallName), Const(op.Address), Const(op.Id));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
@ -41,11 +41,9 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
OpCode op = context.CurrOp;
|
||||
|
||||
string name = nameof(NativeInterface.Undefined);
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.RawOpCode));
|
||||
context.Call(NativeInterface.Type.GetMethod(UndefinedName), Const(op.Address), Const(op.RawOpCode));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id));
|
||||
context.Call(NativeInterface.Type.GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
@ -29,7 +29,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id));
|
||||
context.Call(NativeInterface.Type.GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
|
@ -478,7 +478,7 @@ namespace ARMeilleure.Instructions
|
||||
context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual, BasicBlockFrequency.Cold);
|
||||
|
||||
// Signal memory tracking. Size here doesn't matter as address is assumed to be size aligned here.
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)), address, Const(1UL), Const(write ? 1 : 0));
|
||||
context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.SignalMemoryTracking)), address, Const(1UL), Const(write ? 1 : 0));
|
||||
context.MarkLabel(lblNotWatched);
|
||||
|
||||
pte = context.BitwiseAnd(pte, Const(0xffffffffffffUL)); // Ignore any software protection bits. (they are still used by C# memory access)
|
||||
@ -489,7 +489,7 @@ namespace ARMeilleure.Instructions
|
||||
context.BranchIfTrue(lblNonNull, pte, BasicBlockFrequency.Cold);
|
||||
|
||||
// The call is not expected to return (it should throw).
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)), address);
|
||||
context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)), address);
|
||||
context.MarkLabel(lblNonNull);
|
||||
}
|
||||
|
||||
@ -535,16 +535,16 @@ namespace ARMeilleure.Instructions
|
||||
switch (size)
|
||||
{
|
||||
case 0:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadByte));
|
||||
break;
|
||||
case 1:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt16));
|
||||
break;
|
||||
case 2:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt32));
|
||||
break;
|
||||
case 3:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt64));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -564,19 +564,19 @@ namespace ARMeilleure.Instructions
|
||||
switch (size)
|
||||
{
|
||||
case 0:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadByte));
|
||||
break;
|
||||
case 1:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt16));
|
||||
break;
|
||||
case 2:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt32));
|
||||
break;
|
||||
case 3:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt64));
|
||||
break;
|
||||
case 4:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadVector128));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -608,16 +608,16 @@ namespace ARMeilleure.Instructions
|
||||
switch (size)
|
||||
{
|
||||
case 0:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteByte));
|
||||
break;
|
||||
case 1:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt16));
|
||||
break;
|
||||
case 2:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt32));
|
||||
break;
|
||||
case 3:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt64));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -643,19 +643,19 @@ namespace ARMeilleure.Instructions
|
||||
switch (size)
|
||||
{
|
||||
case 0:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteByte));
|
||||
break;
|
||||
case 1:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt16));
|
||||
break;
|
||||
case 2:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt32));
|
||||
break;
|
||||
case 3:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt64));
|
||||
break;
|
||||
case 4:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteVector128));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,10 @@ namespace ARMeilleure.Instructions
|
||||
switch (GetPackedId(op))
|
||||
{
|
||||
case 0b11_011_0000_0000_001:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCtrEl0));
|
||||
break;
|
||||
case 0b11_011_0000_0000_111:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetDczidEl0));
|
||||
break;
|
||||
case 0b11_011_0100_0010_000:
|
||||
EmitGetNzcv(context);
|
||||
@ -53,13 +53,13 @@ namespace ARMeilleure.Instructions
|
||||
EmitGetTpidr2El0(context);
|
||||
return;
|
||||
case 0b11_011_1110_0000_000:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntfrqEl0));
|
||||
break;
|
||||
case 0b11_011_1110_0000_001:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntpctEl0));
|
||||
break;
|
||||
case 0b11_011_1110_0000_010:
|
||||
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0));
|
||||
info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntvctEl0));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -131,7 +131,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
case 0b11_011_0111_0101_001: // IC IVAU
|
||||
Operand target = Register(op.Rt, RegisterType.Integer, OperandType.I64);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)), target);
|
||||
context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.InvalidateCacheLine)), target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ namespace ARMeilleure.Instructions
|
||||
// Timer.
|
||||
14 => opc switch
|
||||
{
|
||||
0 => typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)),
|
||||
0 => NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntpctEl0)),
|
||||
_ => throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."),
|
||||
},
|
||||
_ => throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X} at 0x{op.Address:X}."),
|
||||
|
@ -2,12 +2,32 @@ using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
static class NativeInterface
|
||||
{
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
public static readonly Type Type = typeof(NativeInterface);
|
||||
|
||||
static NativeInterface()
|
||||
{
|
||||
try
|
||||
{
|
||||
//TODO:
|
||||
// dude. this is so bad. figure out AOT's bs.
|
||||
// this needs to be compiled into the AOT build but it doesn't get compiled
|
||||
// under any circumstances unless directly referenced like below, not dynamically which is how it's always used.
|
||||
_ = GetFunctionAddress(0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class ThreadContext
|
||||
{
|
||||
public ExecutionContext Context { get; }
|
||||
@ -178,8 +198,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
throw new InvalidAccessException(address);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
|
||||
public static ulong GetFunctionAddress(ulong address)
|
||||
{
|
||||
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
|
||||
|
@ -1,6 +1,7 @@
|
||||
using ARMeilleure.Instructions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
@ -62,7 +63,7 @@ namespace ARMeilleure.Translation
|
||||
}
|
||||
|
||||
private static readonly SortedList<string, DelegateInfo> _delegates;
|
||||
|
||||
|
||||
static Delegates()
|
||||
{
|
||||
_delegates = new SortedList<string, DelegateInfo>();
|
||||
@ -79,30 +80,30 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Round)));
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Truncate)));
|
||||
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.Break)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.EnqueueForRejit)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntpctEl0)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntvctEl0)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCtrEl0)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetDczidEl0)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetFunctionAddress)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadByte)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt16)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt32)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt64)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadVector128)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.SupervisorCall)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.Undefined)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteByte)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt16)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt32)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt64)));
|
||||
SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteVector128)));
|
||||
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
||||
|
@ -457,7 +457,7 @@ namespace ARMeilleure.Translation
|
||||
context.Store(address, count);
|
||||
context.BranchIf(lblEnd, curCount, Const(MinsCallForRejit), Comparison.NotEqual, BasicBlockFrequency.Cold);
|
||||
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)), Const(context.EntryAddress));
|
||||
context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.EnqueueForRejit)), Const(context.EntryAddress));
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
@ -473,7 +473,7 @@ namespace ARMeilleure.Translation
|
||||
Operand count = context.Load(OperandType.I32, countAddr);
|
||||
context.BranchIfTrue(lblNonZero, count, BasicBlockFrequency.Cold);
|
||||
|
||||
Operand running = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
||||
Operand running = context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
||||
context.BranchIfTrue(lblExit, running, BasicBlockFrequency.Cold);
|
||||
|
||||
context.Return(Const(0L));
|
||||
|
@ -4,6 +4,7 @@ using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation.Cache;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
|
||||
@ -181,7 +182,7 @@ namespace ARMeilleure.Translation
|
||||
context.Tailcall(hostAddress, nativeContext);
|
||||
|
||||
context.MarkLabel(lblFallback);
|
||||
hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
||||
hostAddress = context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
||||
context.Tailcall(hostAddress, nativeContext);
|
||||
|
||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
||||
@ -206,7 +207,7 @@ namespace ARMeilleure.Translation
|
||||
Operand guestAddress = context.Load(OperandType.I64,
|
||||
context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset())));
|
||||
|
||||
Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
||||
Operand hostAddress = context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
|
||||
context.Tailcall(hostAddress, nativeContext);
|
||||
|
||||
ControlFlowGraph cfg = context.GetControlFlowGraph();
|
||||
|
Loading…
x
Reference in New Issue
Block a user