aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/DirectCallStubs.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Translation/DirectCallStubs.cs')
-rw-r--r--ARMeilleure/Translation/DirectCallStubs.cs44
1 files changed, 23 insertions, 21 deletions
diff --git a/ARMeilleure/Translation/DirectCallStubs.cs b/ARMeilleure/Translation/DirectCallStubs.cs
index 42a78c71..7c11fdb2 100644
--- a/ARMeilleure/Translation/DirectCallStubs.cs
+++ b/ARMeilleure/Translation/DirectCallStubs.cs
@@ -2,6 +2,7 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State;
using System;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
@@ -12,10 +13,10 @@ namespace ARMeilleure.Translation
{
private delegate long GuestFunction(IntPtr nativeContextPtr);
- private static GuestFunction _directCallStub;
- private static GuestFunction _directTailCallStub;
- private static GuestFunction _indirectCallStub;
- private static GuestFunction _indirectTailCallStub;
+ private static IntPtr _directCallStubPtr;
+ private static IntPtr _directTailCallStubPtr;
+ private static IntPtr _indirectCallStubPtr;
+ private static IntPtr _indirectTailCallStubPtr;
private static readonly object _lock = new object();
private static bool _initialized;
@@ -23,25 +24,32 @@ namespace ARMeilleure.Translation
public static void InitializeStubs()
{
if (_initialized) return;
+
lock (_lock)
{
if (_initialized) return;
- _directCallStub = GenerateDirectCallStub(false);
- _directTailCallStub = GenerateDirectCallStub(true);
- _indirectCallStub = GenerateIndirectCallStub(false);
- _indirectTailCallStub = GenerateIndirectCallStub(true);
+
+ _directCallStubPtr = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateDirectCallStub(false));
+ _directTailCallStubPtr = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateDirectCallStub(true));
+ _indirectCallStubPtr = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateIndirectCallStub(false));
+ _indirectTailCallStubPtr = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateIndirectCallStub(true));
+
_initialized = true;
}
}
public static IntPtr DirectCallStub(bool tailCall)
{
- return Marshal.GetFunctionPointerForDelegate(tailCall ? _directTailCallStub : _directCallStub);
+ Debug.Assert(_initialized);
+
+ return tailCall ? _directTailCallStubPtr : _directCallStubPtr;
}
public static IntPtr IndirectCallStub(bool tailCall)
{
- return Marshal.GetFunctionPointerForDelegate(tailCall ? _indirectTailCallStub : _indirectCallStub);
+ Debug.Assert(_initialized);
+
+ return tailCall ? _indirectTailCallStubPtr : _indirectCallStubPtr;
}
private static void EmitCall(EmitterContext context, Operand address, bool tailCall)
@@ -70,21 +78,18 @@ namespace ARMeilleure.Translation
Operand address = context.Load(OperandType.I64, context.Add(nativeContextPtr, Const((long)NativeContext.GetCallAddressOffset())));
address = context.BitwiseOr(address, Const(address.Type, 1)); // Set call flag.
- Operand functionAddr = context.Call(new _U64_U64(NativeInterface.GetFunctionAddress), address);
+ Operand functionAddr = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), address);
EmitCall(context, functionAddr, tailCall);
ControlFlowGraph cfg = context.GetControlFlowGraph();
- OperandType[] argTypes = new OperandType[]
- {
- OperandType.I64
- };
+ OperandType[] argTypes = new OperandType[] { OperandType.I64 };
return Compiler.Compile<GuestFunction>(cfg, argTypes, OperandType.I64, CompilerOptions.HighCq);
}
/// <summary>
- /// Generates a stub that is used to find function addresses and add them to an indirect table.
+ /// Generates a stub that is used to find function addresses and add them to an indirect table.
/// Used for indirect calls entries (already claimed) when their jump table does not have the host address yet.
/// Takes a NativeContext like a translated guest function, and extracts the target indirect table entry from the NativeContext.
/// If the function we find is highCq, the entry in the table is updated to point to that function rather than this stub.
@@ -100,17 +105,14 @@ namespace ARMeilleure.Translation
// We need to find the missing function. If the function is HighCq, then it replaces this stub in the indirect table.
// Either way, we call it afterwards.
- Operand functionAddr = context.Call(new _U64_U64_U64(NativeInterface.GetIndirectFunctionAddress), address, entryAddress);
+ Operand functionAddr = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetIndirectFunctionAddress)), address, entryAddress);
// Call and save the function.
EmitCall(context, functionAddr, tailCall);
ControlFlowGraph cfg = context.GetControlFlowGraph();
- OperandType[] argTypes = new OperandType[]
- {
- OperandType.I64
- };
+ OperandType[] argTypes = new OperandType[] { OperandType.I64 };
return Compiler.Compile<GuestFunction>(cfg, argTypes, OperandType.I64, CompilerOptions.HighCq);
}