aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/EmitterContext.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Translation/EmitterContext.cs')
-rw-r--r--ARMeilleure/Translation/EmitterContext.cs74
1 files changed, 44 insertions, 30 deletions
diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs
index f14c920e..656f1704 100644
--- a/ARMeilleure/Translation/EmitterContext.cs
+++ b/ARMeilleure/Translation/EmitterContext.cs
@@ -3,12 +3,14 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State;
using System;
using System.Collections.Generic;
-using System.Runtime.InteropServices;
+using System.Reflection;
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
namespace ARMeilleure.Translation
{
+ using PTC;
+
class EmitterContext
{
private Dictionary<Operand, BasicBlock> _irLabels;
@@ -79,42 +81,52 @@ namespace ARMeilleure.Translation
return Add(Instruction.ByteSwap, Local(op1.Type), op1);
}
- public Operand Call(Delegate func, params Operand[] callArgs)
+ public Operand Call(MethodInfo info, params Operand[] callArgs)
{
- // Add the delegate to the cache to ensure it will not be garbage collected.
- func = DelegateCache.GetOrAdd(func);
+ if (Ptc.State == PtcState.Disabled)
+ {
+ IntPtr funcPtr = Delegates.GetDelegateFuncPtr(info);
- IntPtr ptr = Marshal.GetFunctionPointerForDelegate<Delegate>(func);
+ OperandType returnType = GetOperandType(info.ReturnType);
- Symbols.Add((ulong)ptr.ToInt64(), func.Method.Name);
+ Symbols.Add((ulong)funcPtr.ToInt64(), info.Name);
- OperandType returnType = GetOperandType(func.Method.ReturnType);
+ return Call(Const(funcPtr.ToInt64()), returnType, callArgs);
+ }
+ else
+ {
+ int index = Delegates.GetDelegateIndex(info);
- return Call(Const(ptr.ToInt64()), returnType, callArgs);
- }
+ IntPtr funcPtr = Delegates.GetDelegateFuncPtrByIndex(index);
- private static Dictionary<TypeCode, OperandType> _typeCodeToOperandTypeMap =
- new Dictionary<TypeCode, OperandType>()
- {
- { TypeCode.Boolean, OperandType.I32 },
- { TypeCode.Byte, OperandType.I32 },
- { TypeCode.Char, OperandType.I32 },
- { TypeCode.Double, OperandType.FP64 },
- { TypeCode.Int16, OperandType.I32 },
- { TypeCode.Int32, OperandType.I32 },
- { TypeCode.Int64, OperandType.I64 },
- { TypeCode.SByte, OperandType.I32 },
- { TypeCode.Single, OperandType.FP32 },
- { TypeCode.UInt16, OperandType.I32 },
- { TypeCode.UInt32, OperandType.I32 },
- { TypeCode.UInt64, OperandType.I64 }
- };
+ OperandType returnType = GetOperandType(info.ReturnType);
+
+ Symbols.Add((ulong)funcPtr.ToInt64(), info.Name);
+
+ return Call(Const(funcPtr.ToInt64(), true, index), returnType, callArgs);
+ }
+ }
private static OperandType GetOperandType(Type type)
{
- if (_typeCodeToOperandTypeMap.TryGetValue(Type.GetTypeCode(type), out OperandType ot))
+ if (type == typeof(bool) || type == typeof(byte) ||
+ type == typeof(char) || type == typeof(short) ||
+ type == typeof(int) || type == typeof(sbyte) ||
+ type == typeof(ushort) || type == typeof(uint))
{
- return ot;
+ return OperandType.I32;
+ }
+ else if (type == typeof(long) || type == typeof(ulong))
+ {
+ return OperandType.I64;
+ }
+ else if (type == typeof(double))
+ {
+ return OperandType.FP64;
+ }
+ else if (type == typeof(float))
+ {
+ return OperandType.FP32;
}
else if (type == typeof(V128))
{
@@ -124,8 +136,10 @@ namespace ARMeilleure.Translation
{
return OperandType.None;
}
-
- throw new ArgumentException($"Invalid type \"{type.Name}\".");
+ else
+ {
+ throw new ArgumentException($"Invalid type \"{type.Name}\".");
+ }
}
public Operand Call(Operand address, OperandType returnType, params Operand[] callArgs)
@@ -615,4 +629,4 @@ namespace ARMeilleure.Translation
return new ControlFlowGraph(_irBlocks.First, _irBlocks);
}
}
-} \ No newline at end of file
+}