diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-02-22 16:26:11 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-02-22 16:26:11 -0300 |
| commit | 2cba1d49f6fcf3d22969579eb2d0d7f02b4c9efa (patch) | |
| tree | 19e17b1a63d3a1be4fb701f19722c97c3c4515f7 /ChocolArm64/Decoder/ADecoder.cs | |
| parent | 224211367f52cf514f0608d69056e84a3ef37ff5 (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.cs | 46 |
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 |
