diff options
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 |
