aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Decoder/ADecoder.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-02-22 16:26:11 -0300
committergdkchan <gab.dark.100@gmail.com>2018-02-22 16:26:11 -0300
commit2cba1d49f6fcf3d22969579eb2d0d7f02b4c9efa (patch)
tree19e17b1a63d3a1be4fb701f19722c97c3c4515f7 /ChocolArm64/Decoder/ADecoder.cs
parent224211367f52cf514f0608d69056e84a3ef37ff5 (diff)
Add FRINTP instruction, fix opcode ctor call method creation with multithreading
Diffstat (limited to 'ChocolArm64/Decoder/ADecoder.cs')
-rw-r--r--ChocolArm64/Decoder/ADecoder.cs46
1 files changed, 26 insertions, 20 deletions
diff --git a/ChocolArm64/Decoder/ADecoder.cs b/ChocolArm64/Decoder/ADecoder.cs
index 06a535c1..a3f44e47 100644
--- a/ChocolArm64/Decoder/ADecoder.cs
+++ b/ChocolArm64/Decoder/ADecoder.cs
@@ -1,6 +1,7 @@
using ChocolArm64.Instruction;
using ChocolArm64.Memory;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection.Emit;
@@ -8,6 +9,15 @@ namespace ChocolArm64.Decoder
{
static class ADecoder
{
+ private delegate object OpActivator(AInst Inst, long Position, int OpCode);
+
+ private static ConcurrentDictionary<Type, OpActivator> OpActivators;
+
+ static ADecoder()
+ {
+ OpActivators = new ConcurrentDictionary<Type, OpActivator>();
+ }
+
public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(ATranslator Translator, long Start)
{
Dictionary<long, ABlock> Visited = new Dictionary<long, ABlock>();
@@ -165,43 +175,39 @@ namespace ChocolArm64.Decoder
if (Inst.Type != null)
{
- DecodedOpCode = CreateOpCode(Inst.Type, Inst, Position, OpCode);
+ DecodedOpCode = MakeOpCode(Inst.Type, Inst, Position, OpCode);
}
return DecodedOpCode;
}
- private delegate object OpActivator(AInst Inst, long Position, int OpCode);
-
- private static Dictionary<Type, OpActivator> Activators = new Dictionary<Type, OpActivator>();
-
- private static AOpCode CreateOpCode(Type Type, AInst Inst, long Position, int OpCode)
+ private static AOpCode MakeOpCode(Type Type, AInst Inst, long Position, int OpCode)
{
if (Type == null)
{
throw new ArgumentNullException(nameof(Type));
}
- if (!Activators.TryGetValue(Type, out OpActivator CreateInstance))
- {
- Type[] ArgTypes = new Type[] { typeof(AInst), typeof(long), typeof(int) };
+ OpActivator CreateInstance = OpActivators.GetOrAdd(Type, CacheOpActivator);
- DynamicMethod Mthd = new DynamicMethod($"{Type.Name}_Create", Type, ArgTypes);
+ return (AOpCode)CreateInstance(Inst, Position, OpCode);
+ }
- ILGenerator Generator = Mthd.GetILGenerator();
+ private static OpActivator CacheOpActivator(Type Type)
+ {
+ Type[] ArgTypes = new Type[] { typeof(AInst), typeof(long), typeof(int) };
- Generator.Emit(OpCodes.Ldarg_0);
- Generator.Emit(OpCodes.Ldarg_1);
- Generator.Emit(OpCodes.Ldarg_2);
- Generator.Emit(OpCodes.Newobj, Type.GetConstructor(ArgTypes));
- Generator.Emit(OpCodes.Ret);
+ DynamicMethod Mthd = new DynamicMethod($"Make{Type.Name}", Type, ArgTypes);
- CreateInstance = (OpActivator)Mthd.CreateDelegate(typeof(OpActivator));
+ ILGenerator Generator = Mthd.GetILGenerator();
- Activators.Add(Type, CreateInstance);
- }
+ Generator.Emit(OpCodes.Ldarg_0);
+ Generator.Emit(OpCodes.Ldarg_1);
+ Generator.Emit(OpCodes.Ldarg_2);
+ Generator.Emit(OpCodes.Newobj, Type.GetConstructor(ArgTypes));
+ Generator.Emit(OpCodes.Ret);
- return (AOpCode)CreateInstance(Inst, Position, OpCode);
+ return (OpActivator)Mthd.CreateDelegate(typeof(OpActivator));
}
}
} \ No newline at end of file