aboutsummaryrefslogtreecommitdiff
path: root/runtime/VMProtect.Runtime/Tests/UnitTestProject/UnitTestCombine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/VMProtect.Runtime/Tests/UnitTestProject/UnitTestCombine.cs')
-rw-r--r--runtime/VMProtect.Runtime/Tests/UnitTestProject/UnitTestCombine.cs1715
1 files changed, 1715 insertions, 0 deletions
diff --git a/runtime/VMProtect.Runtime/Tests/UnitTestProject/UnitTestCombine.cs b/runtime/VMProtect.Runtime/Tests/UnitTestProject/UnitTestCombine.cs
new file mode 100644
index 0000000..fb1a6db
--- /dev/null
+++ b/runtime/VMProtect.Runtime/Tests/UnitTestProject/UnitTestCombine.cs
@@ -0,0 +1,1715 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+using UnitTestProject.RefVm;
+using VMProtect;
+using OpCodes = System.Reflection.Emit.OpCodes;
+
+namespace UnitTestProject
+{
+ [TestClass]
+ public class UnitTestCombine
+ {
+ // шаблон для окружающего кода для некой инструкции
+ public enum CodeTemplate
+ {
+ BranchTwoOpBool, // 2 операнда на стеке, 2 ветки исполнения (одна возвращает true, другая false)
+ SingleOpAny, // 1 операнд на стеке, инструкция, возвращающая разные типы
+ TwoOpBool, // 2 операнда на стеке, инструкция, возвращающая bool
+ TwoOpAny, // 2 операнда на стеке, инструкция, возвращающая разные типы
+ }
+
+ [TestMethod]
+ public void TestMethodRefVm()
+ {
+ InitStrings();
+ TestMethod(new MsilToVmTestCompilerRefVm());
+ }
+
+ [TestMethod]
+ public void TestMethodVmp()
+ {
+ TestMethod(new MsilToVmTestCompilerVmp());
+ }
+
+ [SuppressMessage("ReSharper", "RedundantCast")]
+ public void TestMethod(MsilToVmTestCompiler c)
+ {
+ // типовые и крайние значения следующих типов:
+ // SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64,
+ // float, double,
+ // LongEnum, ULongEnum, Char, SByteEnum, ByteEnum, ShortEnum, UShortEnum, IntEnum, UIntEnum
+ // bool, object, IntPtr, UIntPtr
+ //TODO: decimal
+ #region valsVector
+ // ReSharper disable once RedundantExplicitArrayCreation
+ var valsVector = new object []
+ {
+ (SByte)0, (SByte)1, (SByte)(-1), SByte.MaxValue, SByte.MinValue, (SByte)0x55, // SByte
+ (Byte)0, (Byte)1, Byte.MaxValue, (Byte)0xAA, // Byte
+ (Int16)0, (Int16)1, (Int16)(-1), Int16.MaxValue, Int16.MinValue, (Int16)0x55AA, // Int16
+ (UInt16)0, (UInt16)1, UInt16.MaxValue, (UInt16)0xAA55, // UInt16
+ 0, 1, -1, Int32.MaxValue, Int32.MinValue, 0x55AA55AA, // Int32
+ (UInt32)0, (UInt32)1, UInt32.MaxValue, 0xAA5555AA, // UInt32
+ (Int64)0, (Int64)1, (Int64)(-1), Int64.MaxValue, Int64.MinValue, 0x55AA55AA55AA55AA, // Int64
+ (UInt64)0, (UInt64)1, UInt64.MaxValue, 0xAA5555AAAA5555AA, // UInt64
+ (float)0, (float)1, (float)(-1), float.MaxValue, float.MinValue, float.Epsilon, float.NaN,
+ float.NegativeInfinity, float.PositiveInfinity, (float)(5678.1234),(float)(1234.5678), (float)(-5678.1234), (float)(-1234.5678),
+ (float)(2147483647.0 * 3.0), (float)(-2147483647.0 * 3.0), (float)(9223372336854775807.0 * 3.0), -(float)(9223372336854775807.0 * 3.0), // float
+ (double)0, (double)1, (double)(-1), double.MaxValue, double.MinValue, double.Epsilon, double.NaN,
+ double.NegativeInfinity, double.PositiveInfinity, 5678.1234, 1234.5678, -5678.1234, -1234.5678,
+ (double)(2147483647.0 * 3.0), (double)(-2147483647.0 * 3.0), (double)9223372336854775807.0 * 3.0, -(double)9223372336854775807.0 * 3.0, // double
+ (MsilToVmTestCompiler.LongEnum)0, (MsilToVmTestCompiler.LongEnum)1, (MsilToVmTestCompiler.LongEnum)(-1), (MsilToVmTestCompiler.LongEnum)Int64.MaxValue, (MsilToVmTestCompiler.LongEnum)Int64.MinValue, (MsilToVmTestCompiler.LongEnum)0x55AA55AA55AA55AA, // LongEnum
+ (MsilToVmTestCompiler.ULongEnum)0, (MsilToVmTestCompiler.ULongEnum)1, (MsilToVmTestCompiler.ULongEnum)UInt64.MaxValue, (MsilToVmTestCompiler.ULongEnum)0xAA5555AAAA5555AA, // ULongEnum
+ (Char)0, (Char)1, 'Ю', Char.MaxValue, (Char)0xAA55, // Char
+ (MsilToVmTestCompiler.SByteEnum)0, (MsilToVmTestCompiler.SByteEnum)1, (MsilToVmTestCompiler.SByteEnum)(-1), (MsilToVmTestCompiler.SByteEnum)sbyte.MaxValue, (MsilToVmTestCompiler.SByteEnum)sbyte.MinValue, (MsilToVmTestCompiler.SByteEnum)0x55, // SByteEnum
+ (MsilToVmTestCompiler.ByteEnum)0, (MsilToVmTestCompiler.ByteEnum)1, (MsilToVmTestCompiler.ByteEnum)Byte.MaxValue, (MsilToVmTestCompiler.ByteEnum)0xAA, // ByteEnum
+ (MsilToVmTestCompiler.ShortEnum)0, (MsilToVmTestCompiler.ShortEnum)1, (MsilToVmTestCompiler.ShortEnum)(-1), (MsilToVmTestCompiler.ShortEnum)short.MaxValue, (MsilToVmTestCompiler.ShortEnum)short.MinValue, (MsilToVmTestCompiler.ShortEnum)0x55AA, // ShortEnum
+ (MsilToVmTestCompiler.UShortEnum)0, (MsilToVmTestCompiler.UShortEnum)1, (MsilToVmTestCompiler.UShortEnum)ushort.MaxValue, (MsilToVmTestCompiler.UShortEnum)0xAA55, // UShortEnum
+ (MsilToVmTestCompiler.IntEnum)0, (MsilToVmTestCompiler.IntEnum)1, (MsilToVmTestCompiler.IntEnum)(-1), (MsilToVmTestCompiler.IntEnum)int.MaxValue, (MsilToVmTestCompiler.IntEnum)int.MinValue, (MsilToVmTestCompiler.IntEnum)0x55AA55AA, // IntEnum
+ (MsilToVmTestCompiler.UIntEnum)0, (MsilToVmTestCompiler.UIntEnum)1, (MsilToVmTestCompiler.UIntEnum)uint.MaxValue, (MsilToVmTestCompiler.UIntEnum)0xAA5555AA, // UIntEnum
+ true, false, // bool
+ new object(), //object
+ new IntPtr(0), new UIntPtr(0), // IntPtr, UIntPtr
+ };
+#endregion
+ var errCounters = new int[(int)MsilToVmTestCompiler.InvokeTestCombineError.Cnt];
+ var operations = new List<KeyValuePair<OpCode, CodeTemplate>>
+ {
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Add, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Add_Ovf, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Add_Ovf_Un, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.And, CodeTemplate.TwoOpAny),
+ //Arglist не годится для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Beq_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Bge_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Bge_Un_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Bgt_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Bgt_Un_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Ble_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Ble_Un_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Blt_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Blt_Un_S, CodeTemplate.BranchTwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Bne_Un_S, CodeTemplate.BranchTwoOpBool),
+ //TODO Box
+ //Br_S тестируется неявно в этом тесте
+ //Break не годится для этого теста
+ //TODO Brfalse_S
+ //TODO Brtrue_S
+ //Call тестируется в TestNewobj
+ //Calli Callvirt Castclass не годятся для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Ceq, CodeTemplate.TwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Cgt, CodeTemplate.TwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Cgt_Un, CodeTemplate.TwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Ckfinite, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Clt, CodeTemplate.TwoOpBool),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Clt_Un, CodeTemplate.TwoOpBool),
+ //Constrained не годится для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_I, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_I1, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_I2, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_I4, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_I8, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I1, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I1_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I2, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I2_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I4, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I4_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I8, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I8_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_I_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U1, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U1_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U2, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U2_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U4, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U4_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U8, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U8_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_Ovf_U_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_R4, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_R8, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_R_Un, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_U, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_U1, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_U2, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_U4, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_U8, CodeTemplate.SingleOpAny),
+ //Cpblk Cpobj не годятся для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Div, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Div_Un, CodeTemplate.TwoOpAny),
+ //TODO: Dup
+ //Endfilter Endfinally Initblk Initobj Isinst Jmp Ldarg не годятся для этого теста
+ //Ldarg_0 тестируется неявно в этом тесте
+ //Ldarg_1 тестируется неявно в этом тесте
+ //Ldarg_2 Ldarg_3 Ldarg_S Ldarga не годятся для этого теста
+ //Ldarga_S тестируется в TestNewobj
+ //Ldc_I4 не годится для этого теста
+ //Ldc_I4_0 тестируется неявно в этом тесте
+ //Ldc_I4_1 тестируется неявно в этом тесте
+ //Ldc_I4_2 Ldc_I4_3 Ldc_I4_4 Ldc_I4_5 Ldc_I4_6 Ldc_I4_7 Ldc_I4_8 Ldc_I4_M1 Ldc_I4_S Ldc_I8 Ldc_R4 Ldc_R8 не годятся для этого теста
+ //Ldelem* Ldfld Ldflda Ldftn Ldind_* Ldlen Ldloc* Ldnull Ldobj Ldsfld Ldsflda Ldstr Ldtoken Ldvirtftn Leave Leave_S Localloc Mkrefany не годятся для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Mul, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Mul_Ovf, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Mul_Ovf_Un, CodeTemplate.TwoOpAny),
+ //TODO new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Neg, CodeTemplate.SingleOp),
+ //Newarr не годится для этого теста
+ //Newobj тестируется в TestNewobj
+ //Nop не годится для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Not, CodeTemplate.SingleOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Or, CodeTemplate.TwoOpAny),
+ //Pop Prefix* Readonly Refanytype Refanyval не годятся для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Rem, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Rem_Un, CodeTemplate.TwoOpAny),
+ //Ret тестируется неявно в этом тесте
+ //Rethrow не годится для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Shl, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Shr, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Shr_Un, CodeTemplate.TwoOpAny),
+ //Sizeof
+ //St* не годятся для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Sub, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Sub_Ovf, CodeTemplate.TwoOpAny),
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Sub_Ovf_Un, CodeTemplate.TwoOpAny),
+ //Switch Tailcall Throw Unaligned
+ //TODO Unbox
+ //TODO Unbox_Any
+ //Volatile не годится для этого теста
+ new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Xor, CodeTemplate.TwoOpAny),
+ };
+ foreach (var op in operations)
+ {
+ switch (op.Value)
+ {
+ case CodeTemplate.BranchTwoOpBool:
+ case CodeTemplate.TwoOpBool:
+ case CodeTemplate.TwoOpAny:
+ TestOperationTwoOp(c, op, valsVector, errCounters);
+ break;
+ case CodeTemplate.SingleOpAny:
+ TestOperationSingleOp(c, op, valsVector, errCounters);
+ break;
+ default:
+ Assert.Fail("Unsupported op.Value: {0}", op.Value);
+ break;
+ }
+ }
+ Console.Error.WriteLine("--- {0} results ---", IntPtr.Size == 4 ? "x86" : "x64");
+ var sum = 0;
+ for (var i = 0; i < errCounters.Length; i++)
+ {
+ Console.Error.WriteLine("{0}: {1}", (MsilToVmTestCompiler.InvokeTestCombineError)i, errCounters[i]);
+ sum += errCounters[i];
+ }
+ Console.Error.WriteLine("--- TOTAL: {0} ---", sum);
+ Assert.AreEqual(sum, errCounters[(int)MsilToVmTestCompiler.InvokeTestCombineError.NoError] +
+ errCounters[(int)MsilToVmTestCompiler.InvokeTestCombineError.NoErrorByStdEx]);
+ Console.Error.WriteLine(sum == errCounters[(int) MsilToVmTestCompiler.InvokeTestCombineError.NoError] +
+ errCounters[(int) MsilToVmTestCompiler.InvokeTestCombineError.NoErrorByStdEx]
+ ? "TEST PASSED"
+ : "TEST FAILED");
+ }
+
+ private void TestOperationTwoOp(MsilToVmTestCompiler c, KeyValuePair<OpCode, CodeTemplate> op, object[] valsVector, int[] errCounters)
+ {
+ foreach (var i in valsVector)
+ {
+ foreach (var j in valsVector)
+ {
+ object[] parameters = {i, j};
+ string err, istr = i.ToString(), jstr = j.ToString();
+ if (i is Char)
+ istr = $@"'\{Convert.ToInt32(i)}'";
+ if (j is Char)
+ jstr = $@"'\{Convert.ToInt32(j)}'";
+
+ var res = TestOperation(c, op, parameters, errCounters, out err);
+ if(res > MsilToVmTestCompiler.InvokeTestCombineError.NoErrorByStdEx)
+ Console.Error.WriteLine("{0}.{1}(({4}){2}, ({5}){3}) = {6}", op.Key, op.Value,
+ istr, jstr, i.GetType().FullName, j.GetType().FullName, err);
+ }
+ }
+ }
+
+ private void TestOperationSingleOp(MsilToVmTestCompiler c, KeyValuePair<OpCode, CodeTemplate> op, object[] valsVector, int[] errCounters)
+ {
+ foreach (object i in valsVector)
+ {
+ object[] parameters = { i };
+ string err, istr = i.ToString();
+ if (i is Char)
+ istr = $@"'\{Convert.ToInt32(i)}'";
+ var res = TestOperation(c, op, parameters, errCounters, out err);
+ if (res > MsilToVmTestCompiler.InvokeTestCombineError.NoErrorByStdEx)
+ Console.Error.WriteLine("{0}.{1}(({3}){2}) = {4}", op.Key, op.Value, istr, i.GetType().FullName, err);
+ }
+ }
+
+ [TestMethod]
+ public void TempRefVm()
+ {
+ InitStrings();
+ var errCounters = new int[(int)MsilToVmTestCompiler.InvokeTestCombineError.Cnt];
+ string err;
+ TestOperation(new MsilToVmTestCompilerRefVm(), new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Add_Ovf_Un, CodeTemplate.TwoOpAny),
+ // ReSharper disable once RedundantExplicitArrayCreation
+ new object[] { new object(), (System.SByte)0 }, errCounters, out err);
+ Assert.AreEqual(1, errCounters[0] + errCounters[1]);
+ }
+
+ [TestMethod]
+ public void TempVmp()
+ {
+ var errCounters = new int[(int)MsilToVmTestCompiler.InvokeTestCombineError.Cnt];
+ string err;
+ TestOperation(new MsilToVmTestCompilerVmp(), new KeyValuePair<OpCode, CodeTemplate>(OpCodes.Conv_U4, CodeTemplate.SingleOpAny),
+ // ReSharper disable once RedundantCast
+ new object[] { (Int32)0 }, errCounters, out err);
+ Console.WriteLine(err);
+ Assert.AreEqual(1, errCounters[0] + errCounters[1]);
+ }
+
+ private static void InitStrings()
+ {
+ StringDecryptor.SetString(-1550347095, "The value is not finite real number.");
+ }
+
+ private MsilToVmTestCompiler.InvokeTestCombineError TestOperation(
+ MsilToVmTestCompiler c, KeyValuePair<OpCode, CodeTemplate> op, object[] parameters, int [] errCounters, out string err)
+ {
+ DynamicMethod dyn;
+ err = "";
+ var types = parameters.Select(o => o.GetType()).ToArray();
+ switch (op.Value)
+ {
+ case CodeTemplate.BranchTwoOpBool:
+ dyn = DynBranch2Op(op, types);
+ break;
+ case CodeTemplate.SingleOpAny:
+ dyn = DynSingleOpAny(op, types);
+ break;
+ case CodeTemplate.TwoOpBool:
+ dyn = Dyn2OpBool(op, types);
+ break;
+ case CodeTemplate.TwoOpAny:
+ dyn = Dyn2OpAny(op, types);
+ break;
+ default:
+ Assert.Fail("Unsupported op.Value: {0}", op.Value);
+ // ReSharper disable once HeuristicUnreachableCode
+ return MsilToVmTestCompiler.InvokeTestCombineError.Cnt;
+ }
+ object dynRet, vmRet;
+ var ret = c.InvokeTestCombine(dyn, parameters, out dynRet, out vmRet, out err);
+ // TODO: для регрессии надо как-то научиться закладывать сюда все правильные результаты
+ if (errCounters != null)
+ {
+ if (ret > MsilToVmTestCompiler.InvokeTestCombineError.NoErrorByStdEx &&
+ ExtendedEcma335.Check(op, parameters, vmRet))
+ {
+ ret = MsilToVmTestCompiler.InvokeTestCombineError.NoErrorByStdEx;
+ }
+
+ errCounters[(int)ret]++;
+ }
+ return ret;
+ }
+
+ private DynamicMethod DynSingleOpAny(KeyValuePair<OpCode, CodeTemplate> op, Type[] types)
+ {
+ Type pushedT;
+ switch (op.Key.StackBehaviourPush)
+ {
+ default:
+ Assert.Fail("DynSingleOp unsupported StackBehaviourPush={0}", op.Key.StackBehaviourPush);
+ // ReSharper disable once HeuristicUnreachableCode
+ return null;
+ case StackBehaviour.Pushi:
+ pushedT = typeof(Int32);
+ break;
+ case StackBehaviour.Pushi8:
+ pushedT = typeof(Int64);
+ break;
+ case StackBehaviour.Pushr4:
+ pushedT = typeof(float);
+ break;
+ case StackBehaviour.Pushr8:
+ pushedT = typeof(double);
+ break;
+ case StackBehaviour.Push1:
+ pushedT = CompatibleType(types[0], types[0], false);
+ if (pushedT == typeof(object)) pushedT = typeof(IntPtr);
+ break;
+ }
+ if ((IntPtr.Size == 8) && (op.Key.Equals(OpCodes.Conv_I) || op.Key.Equals(OpCodes.Conv_Ovf_I) || op.Key.Equals(OpCodes.Conv_Ovf_I_Un)))
+ pushedT = typeof(Int64);
+ if (op.Key.Equals(OpCodes.Conv_U) ||op.Key.Equals(OpCodes.Conv_Ovf_U) || op.Key.Equals(OpCodes.Conv_Ovf_U_Un))
+ pushedT = (IntPtr.Size == 8) ? typeof(UInt64) : typeof(UInt32);
+ var dyn = new DynamicMethod(op.Key.Name, pushedT, types, typeof(void), true);
+ var gen = dyn.GetILGenerator();
+
+ gen.Emit(OpCodes.Ldarg_0);
+ gen.Emit(op.Key);
+ gen.Emit(OpCodes.Ret);
+
+ return dyn;
+ }
+
+ internal class ClassNewobj
+ {
+ public const long Check = 0xF00D;
+ public long Ptr;
+ public unsafe ClassNewobj(byte *ptr)
+ {
+ Ptr = (long) ptr;
+ }
+ }
+ public static unsafe object StatNewobj(IntPtr ptr)
+ {
+ return new ClassNewobj((byte *)ptr.ToPointer());
+ }
+
+ [TestMethod]
+ [SuppressMessage("ReSharper", "PossibleNullReferenceException")]
+ public void TestNewobj() //https://ursoft.asuscomm.com:8080/browse/VMP-134?focusedCommentId=15312&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-15312
+ {
+ InitStrings();
+ MsilToVmTestCompiler c = new MsilToVmTestCompilerVmp();
+ var mi = typeof (UnitTestCombine).GetMethod("StatNewobj");
+ var no = (ClassNewobj)c.Invoke(new object[] {new IntPtr(ClassNewobj.Check)},
+ c.CreateVmStream(mi.ReturnType, mi.GetParameters(),
+ mi.GetMethodBody().LocalVariables.Select(o => o.LocalType).ToArray(), mi.GetMethodBody().GetILAsByteArray()));
+ Assert.AreEqual(ClassNewobj.Check, no.Ptr);
+ }
+
+ private static DynamicMethod DynBranch2Op(KeyValuePair<OpCode, CodeTemplate> op, Type[] types)
+ {
+ var dyn = new DynamicMethod(op.Key.Name, typeof(bool), types, typeof(void), true);
+ var gen = dyn.GetILGenerator();
+ var retTrue = gen.DefineLabel();
+ var endOfMthd = gen.DefineLabel();
+
+ gen.Emit(OpCodes.Ldarg_1);
+ gen.Emit(OpCodes.Ldarg_0);
+ gen.Emit(op.Key, retTrue);
+
+ gen.Emit(OpCodes.Ldc_I4_0);
+ gen.Emit(OpCodes.Br_S, endOfMthd);
+
+ gen.MarkLabel(retTrue);
+ gen.Emit(OpCodes.Ldc_I4_1);
+
+ gen.MarkLabel(endOfMthd);
+ gen.Emit(OpCodes.Ret);
+ return dyn;
+ }
+
+ private static DynamicMethod Dyn2OpAny(KeyValuePair<OpCode, CodeTemplate> op, Type[] types)
+ {
+ Type pushedT;
+ switch (op.Key.StackBehaviourPush)
+ {
+ default:
+ Assert.Fail("Dyn2OpAny unsupported StackBehaviourPush={0}", op.Key.StackBehaviourPush);
+ // ReSharper disable once HeuristicUnreachableCode
+ return null;
+ case StackBehaviour.Pushi:
+ pushedT = typeof(Int32);
+ break;
+ case StackBehaviour.Pushi8:
+ pushedT = typeof(Int64);
+ break;
+ case StackBehaviour.Pushr4:
+ pushedT = typeof(float);
+ break;
+ case StackBehaviour.Pushr8:
+ pushedT = typeof(double);
+ break;
+ case StackBehaviour.Push1:
+ pushedT = (op.Key.Value == OpCodes.Shl.Value || op.Key.Value == OpCodes.Shr.Value || op.Key.Value == OpCodes.Shr_Un.Value) ? types[1]: types[0];
+ pushedT = CompatibleType(pushedT, types[1], !op.Key.Name.EndsWith("_Un"));
+ if (pushedT == typeof (object)) pushedT = typeof(IntPtr);
+ break;
+ }
+ return Dyn2Op(op, types, pushedT);
+ }
+
+ public static Type CompatibleType(Type type0, Type type1, bool signed)
+ {
+ if (type0.IsEnum) type0 = type0.GetEnumUnderlyingType();
+ if (type1.IsEnum) type1 = type1.GetEnumUnderlyingType();
+ if (type0 == typeof (bool) && type1 == typeof (bool)) return typeof (sbyte); // true + true = 2
+ if (type0 == typeof (IntPtr)) type0 = IntPtr.Size == 4 ? typeof (Int32) : typeof (Int64);
+ if (type0 == typeof (UIntPtr)) type0 = IntPtr.Size == 4 ? typeof (UInt32) : typeof (UInt64);
+ if (type1 == typeof (IntPtr)) type1 = IntPtr.Size == 4 ? typeof (Int32) : typeof (Int64);
+ if (type1 == typeof (UIntPtr)) type1 = IntPtr.Size == 4 ? typeof (UInt32) : typeof (UInt64);
+ if (type0 == type1) return type0;
+ // возвращаем наиболее широкий из типов
+ return TypeWidth(type0) >= TypeWidth(type1) ? EnsureSign(type0, signed) : EnsureSign(type1, signed);
+ }
+
+ private static Type EnsureSign(Type t, bool signed)
+ {
+ if (t == typeof (Int32)) return signed ? t : typeof (UInt32);
+ if (t == typeof (UInt32)) return signed ? typeof (Int32) : t;
+ if (t == typeof (Int64)) return signed ? t : typeof (UInt64);
+ if (t == typeof (UInt64)) return signed ? typeof (Int64) : t;
+ return t;
+ }
+
+ private static int TypeWidth(Type t)
+ {
+ if (t.IsEnum) t = t.GetEnumUnderlyingType();
+ if (t == typeof (bool)) return 1;
+ if (t == typeof (byte) || t == typeof (sbyte)) return 2;
+ if (t == typeof (short) || t == typeof (ushort) || t == typeof(Char)) return 3;
+ if (t == typeof (int) || t == typeof (uint)) return 4;
+ if (t == typeof (long) || t == typeof (ulong)) return 5;
+ if (t == typeof(float)) return 6;
+ if (t == typeof(double)) return 7;
+ return 8; // object etc
+ }
+
+ private static DynamicMethod Dyn2OpBool(KeyValuePair<OpCode, CodeTemplate> op, Type[] types)
+ {
+ Type pushedT = typeof(bool);
+ return Dyn2Op(op, types, pushedT);
+ }
+
+ private static DynamicMethod Dyn2Op(KeyValuePair<OpCode, CodeTemplate> op, Type[] types, Type ret)
+ {
+ var dyn = new DynamicMethod(op.Key.Name, ret, types, typeof(void), true);
+ var gen = dyn.GetILGenerator();
+
+ gen.Emit(OpCodes.Ldarg_1);
+ gen.Emit(OpCodes.Ldarg_0);
+ gen.Emit(op.Key);
+
+ gen.Emit(OpCodes.Ret);
+ return dyn;
+ }
+ }
+
+ internal class MsilToVmTestCompilerVmp : MsilToVmTestCompiler
+ {
+ #region opcodes
+ internal static readonly Dictionary<short, KeyValuePair<OpCode, VMProtect.OpCodes>> IlToVmInstrInfo = new Dictionary<short, KeyValuePair<OpCode, VMProtect.OpCodes>>()
+ {
+ { OpCodes.Add.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Add, VMProtect.OpCodes.icAdd) },
+ { OpCodes.Add_Ovf.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Add_Ovf, VMProtect.OpCodes.icAdd_ovf) },
+ { OpCodes.Add_Ovf_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Add_Ovf_Un, VMProtect.OpCodes.icAdd_ovf_un) },
+ { OpCodes.And.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.And, VMProtect.OpCodes.icAnd) },
+ //{ OpCodes.Arglist.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Arglist, VMProtect.OpCodes.icArglist) },
+ { OpCodes.Beq_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Beq_S, VMProtect.OpCodes.icBeq) },
+ { OpCodes.Bge_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Bge_S, VMProtect.OpCodes.icBge) },
+ { OpCodes.Bge_Un_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Bge_Un_S, VMProtect.OpCodes.icBge_un) },
+ { OpCodes.Bgt_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Bgt_S, VMProtect.OpCodes.icBgt) },
+ { OpCodes.Bgt_Un_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Bgt_Un_S, VMProtect.OpCodes.icBgt_un) },
+ { OpCodes.Ble_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ble_S, VMProtect.OpCodes.icBle) },
+ { OpCodes.Ble_Un_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ble_Un_S, VMProtect.OpCodes.icBle_un) },
+ { OpCodes.Blt_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Blt_S, VMProtect.OpCodes.icBlt) },
+ { OpCodes.Blt_Un_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Blt_Un_S, VMProtect.OpCodes.icBlt_un) },
+ { OpCodes.Bne_Un_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Bne_Un_S, VMProtect.OpCodes.icBne_un) },
+ //{ OpCodes.Box.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Box, VMProtect.OpCodes.icBox) },
+ { OpCodes.Br_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Br_S, VMProtect.OpCodes.icBr) },
+ //{ OpCodes.Break.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Break, VMProtect.OpCodes.icBreak) },
+ //{ OpCodes.Brfalse_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Brfalse_S, VMProtect.OpCodes.icBrfalse_S) },
+ //{ OpCodes.Brtrue_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Brtrue_S, VMProtect.OpCodes.icBrtrue_S) },
+ { OpCodes.Call.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Call, VMProtect.OpCodes.icCall) },
+ //{ OpCodes.Calli.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Calli, VMProtect.OpCodes.icCalli) },
+ //{ OpCodes.Callvirt.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Callvirt, VMProtect.OpCodes.icCallvirt) },
+ //{ OpCodes.Castclass.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Castclass, VMProtect.OpCodes.icCastclass) },
+ { OpCodes.Ceq.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ceq, VMProtect.OpCodes.icCeq) },
+ { OpCodes.Cgt.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Cgt, VMProtect.OpCodes.icCgt) },
+ { OpCodes.Cgt_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Cgt_Un, VMProtect.OpCodes.icCgt_un) },
+ { OpCodes.Ckfinite.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ckfinite, VMProtect.OpCodes.icCkfinite) },
+ { OpCodes.Clt.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Clt, VMProtect.OpCodes.icClt) },
+ { OpCodes.Clt_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Clt_Un, VMProtect.OpCodes.icClt_un) },
+ //{ OpCodes.Constrained.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Constrained, VMProtect.OpCodes.icConstrained) },
+ { OpCodes.Conv_I.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_I, VMProtect.OpCodes.icConv_i) },
+ { OpCodes.Conv_I1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_I1, VMProtect.OpCodes.icConv_i1) },
+ { OpCodes.Conv_I2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_I2, VMProtect.OpCodes.icConv_i2) },
+ { OpCodes.Conv_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_I4, VMProtect.OpCodes.icConv_i4) },
+ { OpCodes.Conv_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_I8, VMProtect.OpCodes.icConv_i8) },
+ { OpCodes.Conv_Ovf_I.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I, VMProtect.OpCodes.icConv_ovf_i) },
+ { OpCodes.Conv_Ovf_I_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I_Un, VMProtect.OpCodes.icConv_ovf_i_un) },
+ { OpCodes.Conv_Ovf_I1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I1, VMProtect.OpCodes.icConv_ovf_i1) },
+ { OpCodes.Conv_Ovf_I1_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I1_Un, VMProtect.OpCodes.icConv_ovf_i1_un) },
+ { OpCodes.Conv_Ovf_I2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I2, VMProtect.OpCodes.icConv_ovf_i2) },
+ { OpCodes.Conv_Ovf_I2_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I2_Un, VMProtect.OpCodes.icConv_ovf_i2_un) },
+ { OpCodes.Conv_Ovf_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I4, VMProtect.OpCodes.icConv_ovf_i4) },
+ { OpCodes.Conv_Ovf_I4_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I4_Un, VMProtect.OpCodes.icConv_ovf_i4_un) },
+ { OpCodes.Conv_Ovf_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I8, VMProtect.OpCodes.icConv_ovf_i8) },
+ { OpCodes.Conv_Ovf_I8_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_I8_Un, VMProtect.OpCodes.icConv_ovf_i8_un) },
+ { OpCodes.Conv_Ovf_U.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U, VMProtect.OpCodes.icConv_ovf_u) },
+ { OpCodes.Conv_Ovf_U_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U_Un, VMProtect.OpCodes.icConv_ovf_u_un) },
+ { OpCodes.Conv_Ovf_U1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U1, VMProtect.OpCodes.icConv_ovf_u1) },
+ { OpCodes.Conv_Ovf_U1_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U1_Un, VMProtect.OpCodes.icConv_ovf_u1_un) },
+ { OpCodes.Conv_Ovf_U2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U2, VMProtect.OpCodes.icConv_ovf_u2) },
+ { OpCodes.Conv_Ovf_U2_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U2_Un, VMProtect.OpCodes.icConv_ovf_u2_un) },
+ { OpCodes.Conv_Ovf_U4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U4, VMProtect.OpCodes.icConv_ovf_u4) },
+ { OpCodes.Conv_Ovf_U4_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U4_Un, VMProtect.OpCodes.icConv_ovf_u4_un) },
+ { OpCodes.Conv_Ovf_U8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U8, VMProtect.OpCodes.icConv_ovf_u8) },
+ { OpCodes.Conv_Ovf_U8_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_Ovf_U8_Un, VMProtect.OpCodes.icConv_ovf_u8_un) },
+ { OpCodes.Conv_R_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_R_Un, VMProtect.OpCodes.icConv_r_un) },
+ { OpCodes.Conv_R4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_R4, VMProtect.OpCodes.icConv_r4) },
+ { OpCodes.Conv_R8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_R8, VMProtect.OpCodes.icConv_r8) },
+ { OpCodes.Conv_U.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_U, VMProtect.OpCodes.icConv_u) },
+ { OpCodes.Conv_U1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_U1, VMProtect.OpCodes.icConv_u1) },
+ { OpCodes.Conv_U2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_U2, VMProtect.OpCodes.icConv_u2) },
+ { OpCodes.Conv_U4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_U4, VMProtect.OpCodes.icConv_u4) },
+ { OpCodes.Conv_U8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Conv_U8, VMProtect.OpCodes.icConv_u8) },
+ //{ OpCodes.Cpblk.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Cpblk, VMProtect.OpCodes.icCpblk) },
+ //{ OpCodes.Cpobj.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Cpobj, VMProtect.OpCodes.icCpobj) },
+ { OpCodes.Div.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Div, VMProtect.OpCodes.icDiv) },
+ { OpCodes.Div_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Div_Un, VMProtect.OpCodes.icDiv_un) },
+ //{ OpCodes.Dup.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Dup, VMProtect.OpCodes.icDup) },
+ //{ OpCodes.Endfilter.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Endfilter, VMProtect.OpCodes.icEndfilter) },
+ //{ OpCodes.Endfinally.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Endfinally, VMProtect.OpCodes.icEndfinally) },
+ //{ OpCodes.Initblk.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Initblk, VMProtect.OpCodes.icInitblk) },
+ //{ OpCodes.Initobj.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Initobj, VMProtect.OpCodes.icInitobj) },
+ //{ OpCodes.Isinst.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Isinst, VMProtect.OpCodes.icIsinst) },
+ //{ OpCodes.Jmp.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Jmp, VMProtect.OpCodes.icJmp) },
+ //{ OpCodes.Ldarg.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarg, VMProtect.OpCodes.icLdarg) },
+ { OpCodes.Ldarg_0.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarg_0, VMProtect.OpCodes.icLdarg_0) },
+ { OpCodes.Ldarg_1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarg_1, VMProtect.OpCodes.icLdarg_1) },
+ //{ OpCodes.Ldarg_2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarg_2, VMProtect.OpCodes.icLdarg_2) },
+ //{ OpCodes.Ldarg_3.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarg_3, VMProtect.OpCodes.icLdarg_3) },
+ //{ OpCodes.Ldarg_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarg_S, VMProtect.OpCodes.icLdarg_S) },
+ //{ OpCodes.Ldarga.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarga, VMProtect.OpCodes.icLdarga) },
+ { OpCodes.Ldarga_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldarga_S, VMProtect.OpCodes.icLdarga_s) },
+ { OpCodes.Ldc_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4, VMProtect.OpCodes.icLdc_i4) },
+ { OpCodes.Ldc_I4_0.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_0, VMProtect.OpCodes.icLdc_i4_0) },
+ { OpCodes.Ldc_I4_1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_1, VMProtect.OpCodes.icLdc_i4_1) },
+ { OpCodes.Ldc_I4_2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_2, VMProtect.OpCodes.icLdc_i4_2) },
+ //{ OpCodes.Ldc_I4_3.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_3, VMProtect.OpCodes.icLdc_I4_3) },
+ //{ OpCodes.Ldc_I4_4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_4, VMProtect.OpCodes.icLdc_I4_4) },
+ //{ OpCodes.Ldc_I4_5.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_5, VMProtect.OpCodes.icLdc_I4_5) },
+ //{ OpCodes.Ldc_I4_6.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_6, VMProtect.OpCodes.icLdc_I4_6) },
+ //{ OpCodes.Ldc_I4_7.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_7, VMProtect.OpCodes.icLdc_I4_7) },
+ //{ OpCodes.Ldc_I4_8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_8, VMProtect.OpCodes.icLdc_I4_8) },
+ //{ OpCodes.Ldc_I4_M1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_M1, VMProtect.OpCodes.icLdc_I4_M1) },
+ //{ OpCodes.Ldc_I4_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I4_S, VMProtect.OpCodes.icLdc_I4_S) },
+ //{ OpCodes.Ldc_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_I8, VMProtect.OpCodes.icLdc_I8) },
+ //{ OpCodes.Ldc_R4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_R4, VMProtect.OpCodes.icLdc_R4) },
+ //{ OpCodes.Ldc_R8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldc_R8, VMProtect.OpCodes.icLdc_R8) },
+ //{ OpCodes.Ldelem.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem, VMProtect.OpCodes.icLdelem) },
+ //{ OpCodes.Ldelem_I.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_I, VMProtect.OpCodes.icLdelem_I) },
+ //{ OpCodes.Ldelem_I1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_I1, VMProtect.OpCodes.icLdelem_I1) },
+ //{ OpCodes.Ldelem_I2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_I2, VMProtect.OpCodes.icLdelem_I2) },
+ //{ OpCodes.Ldelem_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_I4, VMProtect.OpCodes.icLdelem_I4) },
+ //{ OpCodes.Ldelem_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_I8, VMProtect.OpCodes.icLdelem_I8) },
+ //{ OpCodes.Ldelem_R4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_R4, VMProtect.OpCodes.icLdelem_R4) },
+ //{ OpCodes.Ldelem_R8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_R8, VMProtect.OpCodes.icLdelem_R8) },
+ //{ OpCodes.Ldelem_Ref.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_Ref, VMProtect.OpCodes.icLdelem_Ref) },
+ //{ OpCodes.Ldelem_U1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_U1, VMProtect.OpCodes.icLdelem_U1) },
+ //{ OpCodes.Ldelem_U2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_U2, VMProtect.OpCodes.icLdelem_U2) },
+ //{ OpCodes.Ldelem_U4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelem_U4, VMProtect.OpCodes.icLdelem_U4) },
+ //{ OpCodes.Ldelema.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldelema, VMProtect.OpCodes.icLdelema) },
+ //{ OpCodes.Ldfld.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldfld, VMProtect.OpCodes.icLdfld) },
+ //{ OpCodes.Ldflda.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldflda, VMProtect.OpCodes.icLdflda) },
+ //{ OpCodes.Ldftn.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldftn, VMProtect.OpCodes.icLdftn) },
+ //{ OpCodes.Ldind_I.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_I, VMProtect.OpCodes.icLdind_I) },
+ //{ OpCodes.Ldind_I1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_I1, VMProtect.OpCodes.icLdind_I1) },
+ //{ OpCodes.Ldind_I2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_I2, VMProtect.OpCodes.icLdind_I2) },
+ //{ OpCodes.Ldind_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_I4, VMProtect.OpCodes.icLdind_I4) },
+ //{ OpCodes.Ldind_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_I8, VMProtect.OpCodes.icLdind_I8) },
+ //{ OpCodes.Ldind_R4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_R4, VMProtect.OpCodes.icLdind_R4) },
+ //{ OpCodes.Ldind_R8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_R8, VMProtect.OpCodes.icLdind_R8) },
+ //{ OpCodes.Ldind_Ref.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_Ref, VMProtect.OpCodes.icLdind_Ref) },
+ //{ OpCodes.Ldind_U1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_U1, VMProtect.OpCodes.icLdind_U1) },
+ //{ OpCodes.Ldind_U2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_U2, VMProtect.OpCodes.icLdind_U2) },
+ //{ OpCodes.Ldind_U4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldind_U4, VMProtect.OpCodes.icLdind_U4) },
+ //{ OpCodes.Ldlen.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldlen, VMProtect.OpCodes.icLdlen) },
+ //{ OpCodes.Ldloc.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloc, VMProtect.OpCodes.icLdloc) },
+ { OpCodes.Ldloc_0.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloc_0, VMProtect.OpCodes.icLdloc_0) },
+ //{ OpCodes.Ldloc_1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloc_1, VMProtect.OpCodes.icLdloc_1) },
+ //{ OpCodes.Ldloc_2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloc_2, VMProtect.OpCodes.icLdloc_2) },
+ //{ OpCodes.Ldloc_3.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloc_3, VMProtect.OpCodes.icLdloc_3) },
+ //{ OpCodes.Ldloc_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloc_S, VMProtect.OpCodes.icLdloc_S) },
+ //{ OpCodes.Ldloca.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloca, VMProtect.OpCodes.icLdloca) },
+ //{ OpCodes.Ldloca_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldloca_S, VMProtect.OpCodes.icLdloca_S) },
+ { OpCodes.Ldnull.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldnull, VMProtect.OpCodes.icLdnull) },
+ //{ OpCodes.Ldobj.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldobj, VMProtect.OpCodes.icLdobj) },
+ //{ OpCodes.Ldsfld.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldsfld, VMProtect.OpCodes.icLdsfld) },
+ //{ OpCodes.Ldsflda.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldsflda, VMProtect.OpCodes.icLdsflda) },
+ //{ OpCodes.Ldstr.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldstr, VMProtect.OpCodes.icLdstr) },
+ //{ OpCodes.Ldtoken.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldtoken, VMProtect.OpCodes.icLdtoken) },
+ //{ OpCodes.Ldvirtftn.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ldvirtftn, VMProtect.OpCodes.icLdvirtftn) },
+ //{ OpCodes.Leave.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Leave, VMProtect.OpCodes.icLeave) },
+ //{ OpCodes.Leave_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Leave_S, VMProtect.OpCodes.icLeave_S) },
+ //{ OpCodes.Localloc.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Localloc, VMProtect.OpCodes.icLocalloc) },
+ //{ OpCodes.Mkrefany.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Mkrefany, VMProtect.OpCodes.icMkrefany) },
+ { OpCodes.Mul.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Mul, VMProtect.OpCodes.icMul) },
+ { OpCodes.Mul_Ovf.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Mul_Ovf, VMProtect.OpCodes.icMul_ovf) },
+ { OpCodes.Mul_Ovf_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Mul_Ovf_Un, VMProtect.OpCodes.icMul_ovf_un) },
+ //{ OpCodes.Neg.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Neg, VMProtect.OpCodes.icNeg) },
+ //{ OpCodes.Newarr.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Newarr, VMProtect.OpCodes.icNewarr) },
+ { OpCodes.Newobj.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Newobj, VMProtect.OpCodes.icNewobj) },
+ { OpCodes.Nop.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Nop, VMProtect.OpCodes.icNop) },
+ { OpCodes.Not.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Not, VMProtect.OpCodes.icNot) },
+ { OpCodes.Or.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Or, VMProtect.OpCodes.icOr) },
+ //{ OpCodes.Pop.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Pop, VMProtect.OpCodes.icPop) },
+ //{ OpCodes.Prefix1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix1, VMProtect.OpCodes.icPrefix1) },
+ //{ OpCodes.Prefix2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix2, VMProtect.OpCodes.icPrefix2) },
+ //{ OpCodes.Prefix3.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix3, VMProtect.OpCodes.icPrefix3) },
+ //{ OpCodes.Prefix4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix4, VMProtect.OpCodes.icPrefix4) },
+ //{ OpCodes.Prefix5.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix5, VMProtect.OpCodes.icPrefix5) },
+ //{ OpCodes.Prefix6.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix6, VMProtect.OpCodes.icPrefix6) },
+ //{ OpCodes.Prefix7.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefix7, VMProtect.OpCodes.icPrefix7) },
+ //{ OpCodes.Prefixref.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Prefixref, VMProtect.OpCodes.icPrefixref) },
+ //{ OpCodes.Readonly.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Readonly, VMProtect.OpCodes.icReadonly) },
+ //{ OpCodes.Refanytype.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Refanytype, VMProtect.OpCodes.icRefanytype) },
+ //{ OpCodes.Refanyval.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Refanyval, VMProtect.OpCodes.icRefanyval) },
+ { OpCodes.Rem.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Rem, VMProtect.OpCodes.icRem) },
+ { OpCodes.Rem_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Rem_Un, VMProtect.OpCodes.icRem_un) },
+ { OpCodes.Ret.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Ret, VMProtect.OpCodes.icRet) },
+ //{ OpCodes.Rethrow.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Rethrow, VMProtect.OpCodes.icRethrow) },
+ { OpCodes.Shl.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Shl, VMProtect.OpCodes.icShl) },
+ { OpCodes.Shr.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Shr, VMProtect.OpCodes.icShr) },
+ { OpCodes.Shr_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Shr_Un, VMProtect.OpCodes.icShr_un) },
+ //{ OpCodes.Sizeof.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Sizeof, VMProtect.OpCodes.icSizeof) },
+ //{ OpCodes.Starg.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Starg, VMProtect.OpCodes.icStarg) },
+ //{ OpCodes.Starg_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Starg_S, VMProtect.OpCodes.icStarg_S) },
+ //{ OpCodes.Stelem.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem, VMProtect.OpCodes.icStelem) },
+ //{ OpCodes.Stelem_I.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_I, VMProtect.OpCodes.icStelem_I) },
+ //{ OpCodes.Stelem_I1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_I1, VMProtect.OpCodes.icStelem_I1) },
+ { OpCodes.Stelem_I2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_I2, VMProtect.OpCodes.icStelem_i2) },
+ //{ OpCodes.Stelem_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_I4, VMProtect.OpCodes.icStelem_I4) },
+ //{ OpCodes.Stelem_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_I8, VMProtect.OpCodes.icStelem_I8) },
+ //{ OpCodes.Stelem_R4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_R4, VMProtect.OpCodes.icStelem_R4) },
+ //{ OpCodes.Stelem_R8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_R8, VMProtect.OpCodes.icStelem_R8) },
+ //{ OpCodes.Stelem_Ref.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stelem_Ref, VMProtect.OpCodes.icStelem_Ref) },
+ //{ OpCodes.Stfld.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stfld, VMProtect.OpCodes.icStfld) },
+ //{ OpCodes.Stind_I.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_I, VMProtect.OpCodes.icStind_I) },
+ //{ OpCodes.Stind_I1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_I1, VMProtect.OpCodes.icStind_I1) },
+ //{ OpCodes.Stind_I2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_I2, VMProtect.OpCodes.icStind_I2) },
+ //{ OpCodes.Stind_I4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_I4, VMProtect.OpCodes.icStind_I4) },
+ //{ OpCodes.Stind_I8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_I8, VMProtect.OpCodes.icStind_I8) },
+ //{ OpCodes.Stind_R4.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_R4, VMProtect.OpCodes.icStind_R4) },
+ //{ OpCodes.Stind_R8.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_R8, VMProtect.OpCodes.icStind_R8) },
+ //{ OpCodes.Stind_Ref.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stind_Ref, VMProtect.OpCodes.icStind_Ref) },
+ //{ OpCodes.Stloc.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stloc, VMProtect.OpCodes.icStloc) },
+ { OpCodes.Stloc_0.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stloc_0, VMProtect.OpCodes.icStloc_0) },
+ //{ OpCodes.Stloc_1.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stloc_1, VMProtect.OpCodes.icStloc_1) },
+ //{ OpCodes.Stloc_2.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stloc_2, VMProtect.OpCodes.icStloc_2) },
+ //{ OpCodes.Stloc_3.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stloc_3, VMProtect.OpCodes.icStloc_3) },
+ //{ OpCodes.Stloc_S.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stloc_S, VMProtect.OpCodes.icStloc_S) },
+ //{ OpCodes.Stobj.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stobj, VMProtect.OpCodes.icStobj) },
+ //{ OpCodes.Stsfld.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Stsfld, VMProtect.OpCodes.icStsfld) },
+ { OpCodes.Sub.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Sub, VMProtect.OpCodes.icSub) },
+ { OpCodes.Sub_Ovf.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Sub_Ovf, VMProtect.OpCodes.icSub_ovf) },
+ { OpCodes.Sub_Ovf_Un.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Sub_Ovf_Un, VMProtect.OpCodes.icSub_ovf_un) },
+ //{ OpCodes.Switch.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Switch, VMProtect.OpCodes.icSwitch) },
+ //{ OpCodes.Tailcall.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Tailcall, VMProtect.OpCodes.icTailcall) },
+ //{ OpCodes.Throw.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Throw, VMProtect.OpCodes.icThrow) },
+ //{ OpCodes.Unaligned.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Unaligned, VMProtect.OpCodes.icUnaligned) },
+ //{ OpCodes.Unbox.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Unbox, VMProtect.OpCodes.icUnbox) },
+ //{ OpCodes.Unbox_Any.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Unbox_Any, VMProtect.OpCodes.icUnbox_Any) },
+ //{ OpCodes.Volatile.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Volatile, VMProtect.OpCodes.icVolatile) },
+ { OpCodes.Xor.Value, new KeyValuePair<OpCode, VMProtect.OpCodes>(OpCodes.Xor, VMProtect.OpCodes.icXor) },
+ };
+ #endregion
+ private static readonly Dictionary<Type, int> TypeTokenInModule = new Dictionary<Type, int>(); //TypeDefs and TypeRefs
+ private static int GetTypeTokenInModule(Type t)
+ {
+ var tryToken = 0x01000001; //first TypeRef
+ var m = typeof (MsilToVmTestCompilerVmp).Module;
+ while (true)
+ {
+ try
+ {
+ Type t1 = m.ResolveType(tryToken);
+ TypeTokenInModule.Add(t1, tryToken++);
+ }
+ catch (Exception)
+ {
+ break; //until last TypeRef
+ }
+
+ }
+ if (TypeTokenInModule.ContainsKey(t))
+ return TypeTokenInModule[t];
+ if (t.Module == m)
+ {
+ TypeTokenInModule.Add(t, t.MetadataToken);
+ return t.MetadataToken;
+ }
+ Assert.Fail("Bad type {0}: not accessible from this module", t);
+ return 0;
+ }
+ public override Stream CreateVmStream(Type rt, ParameterInfo[] pi, Type[] locals, byte[] ilBytes)
+ {
+ var ret = new MemoryStream();
+ var wr = new BinaryWriter(ret);
+ var fwdTypeDefs = new Dictionary<Type, int>();
+ var fwdTypeRefs = new Dictionary<int, Type>();
+ var deferredBrTargets = new Dictionary<long, UInt32>();
+ var srcToDstInstrPositions = new Dictionary<long, UInt32>();
+ const int dummy = 0x55555555;
+ fwdTypeDefs.Add(rt, dummy);
+ var pars = pi;
+ foreach (var parameterInfo in pars)
+ {
+ if (!fwdTypeDefs.ContainsKey(parameterInfo.ParameterType))
+ fwdTypeDefs.Add(parameterInfo.ParameterType, dummy);
+ wr.Write((byte)VMProtect.OpCodes.icInitarg);
+ fwdTypeRefs.Add((int)ret.Position, parameterInfo.ParameterType);
+ wr.Write(dummy); // parTypeId fwd ref
+ }
+ foreach (var lt in locals)
+ {
+ if (!fwdTypeDefs.ContainsKey(lt))
+ fwdTypeDefs.Add(lt, dummy);
+ // FIXME
+ //wr.Write((byte)VMProtect.OpCodes.icInitloc);
+ fwdTypeRefs.Add((int)ret.Position, lt);
+ wr.Write(dummy); // parTypeId fwd ref
+ }
+
+ using (var sr = new BinaryReader(new MemoryStream(ilBytes)))
+ {
+ while (sr.BaseStream.Position < sr.BaseStream.Length)
+ {
+ srcToDstInstrPositions[sr.BaseStream.Position] = (uint)ret.Position;
+ short ilByte = sr.ReadByte();
+ if (ilByte == 0xFE)
+ ilByte = (short)((ilByte << 8) | sr.ReadByte());
+ Assert.IsTrue(IlToVmInstrInfo.ContainsKey(ilByte), "Extend IlToVmInstrInfo with {0:X} or use short jump", ilByte);
+ var vmInstrInfo = IlToVmInstrInfo[ilByte];
+ ulong operand = 0;
+ switch (vmInstrInfo.Key.OperandType)
+ {
+ case OperandType.InlineNone:
+ break;
+ case OperandType.InlineI8:
+ case OperandType.InlineR:
+ operand = sr.ReadUInt64();
+ break;
+ case OperandType.InlineVar:
+ operand = sr.ReadUInt16();
+ break;
+ case OperandType.ShortInlineBrTarget:
+ case OperandType.ShortInlineI:
+ case OperandType.ShortInlineVar:
+ operand = sr.ReadByte();
+ break;
+ default:
+ operand = sr.ReadUInt32();
+ break;
+ }
+ switch ((short)vmInstrInfo.Value)
+ {
+ case (short)VMProtect.OpCodes.icNop:
+ continue;
+ case (short)VMProtect.OpCodes.icStloc_0:
+ wr.Write((byte)VMProtect.OpCodes.icStloc);
+ wr.Write((ushort)0);
+ break;
+ case (short)VMProtect.OpCodes.icStloc_1:
+ wr.Write((byte)VMProtect.OpCodes.icStloc);
+ wr.Write((ushort)1);
+ break;
+ case (short)VMProtect.OpCodes.icStloc_2:
+ wr.Write((byte)VMProtect.OpCodes.icStloc);
+ wr.Write((ushort)2);
+ break;
+ case (short)VMProtect.OpCodes.icStloc_3:
+ wr.Write((byte)VMProtect.OpCodes.icStloc);
+ wr.Write((ushort)3);
+ break;
+ case (short)VMProtect.OpCodes.icLdloc_0:
+ wr.Write((byte)VMProtect.OpCodes.icLdloc);
+ wr.Write((ushort)0);
+ break;
+ case (short)VMProtect.OpCodes.icLdloc_1:
+ wr.Write((byte)VMProtect.OpCodes.icLdloc);
+ wr.Write((ushort)1);
+ break;
+ case (short)VMProtect.OpCodes.icLdloc_2:
+ wr.Write((byte)VMProtect.OpCodes.icLdloc);
+ wr.Write((ushort)2);
+ break;
+ case (short)VMProtect.OpCodes.icLdloc_3:
+ wr.Write((byte)VMProtect.OpCodes.icLdloc);
+ wr.Write((ushort)3);
+ break;
+ case (short)VMProtect.OpCodes.icLdarg_0:
+ wr.Write((byte)VMProtect.OpCodes.icLdarg);
+ wr.Write((ushort)0);
+ break;
+ case (short)VMProtect.OpCodes.icLdarg_1:
+ wr.Write((byte)VMProtect.OpCodes.icLdarg);
+ wr.Write((ushort)1);
+ break;
+ case (short)VMProtect.OpCodes.icLdarg_2:
+ wr.Write((byte)VMProtect.OpCodes.icLdarg);
+ wr.Write((ushort)2);
+ break;
+ case (short)VMProtect.OpCodes.icLdarg_3:
+ wr.Write((byte)VMProtect.OpCodes.icLdarg);
+ wr.Write((ushort)3);
+ break;
+ case (short)VMProtect.OpCodes.icLdarga_s:
+ wr.Write((byte)VMProtect.OpCodes.icLdarga);
+ wr.Write((ushort)operand);
+ break;
+ case (short)VMProtect.OpCodes.icRet:
+ wr.Write((byte)VMProtect.OpCodes.icRet);
+ fwdTypeRefs.Add((int)ret.Position, rt);
+ wr.Write(dummy); // ReturnTypeId fwd ref
+ break;
+ case (short)VMProtect.OpCodes.icLdc_i4_0:
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ wr.Write((uint)0);
+ break;
+ case (short)VMProtect.OpCodes.icLdc_i4_1:
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ wr.Write((uint)1);
+ break;
+ case (short)VMProtect.OpCodes.icLdc_i4_2:
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ wr.Write((uint)2);
+ break;
+ case (short)VMProtect.OpCodes.icLdc_i4_3:
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ wr.Write((uint)3);
+ break;
+ case (short)VMProtect.OpCodes.icBr:
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ deferredBrTargets[ret.Position] = (uint)sr.BaseStream.Position + (uint)operand;
+ wr.Write(dummy);
+ wr.Write((byte)VMProtect.OpCodes.icBr);
+ break;
+ case (short)VMProtect.OpCodes.icBeq:
+ case (short)VMProtect.OpCodes.icBne_un:
+ case (short)VMProtect.OpCodes.icBlt:
+ case (short)VMProtect.OpCodes.icBlt_un:
+ case (short)VMProtect.OpCodes.icBle:
+ case (short)VMProtect.OpCodes.icBle_un:
+ case (short)VMProtect.OpCodes.icBgt:
+ case (short)VMProtect.OpCodes.icBgt_un:
+ case (short)VMProtect.OpCodes.icBge:
+ case (short)VMProtect.OpCodes.icBge_un:
+ case (short)VMProtect.OpCodes.icBrtrue:
+ case (short)VMProtect.OpCodes.icBrfalse:
+ switch ((short)vmInstrInfo.Value)
+ {
+ // FIXME
+ /*
+ case (short)VMProtect.OpCodes.icBeq:
+ case (short)VMProtect.OpCodes.icBne_un:
+ wr.Write((byte)VMProtect.OpCodes.icCeq);
+ break;
+ case (short)VMProtect.OpCodes.icBge:
+ wr.Write((byte)VMProtect.OpCodes.icCge);
+ break;
+ case (short)VMProtect.OpCodes.icBge_un:
+ wr.Write((byte)VMProtect.OpCodes.icCge_un);
+ break;
+ case (short)VMProtect.OpCodes.icBlt:
+ wr.Write((byte)VMProtect.OpCodes.icClt);
+ break;
+ case (short)VMProtect.OpCodes.icBlt_un:
+ wr.Write((byte)VMProtect.OpCodes.icClt_un);
+ break;
+ case (short)VMProtect.OpCodes.icBle:
+ wr.Write((byte)VMProtect.OpCodes.icCle);
+ break;
+ case (short)VMProtect.OpCodes.icBle_un:
+ wr.Write((byte)VMProtect.OpCodes.icCle_un);
+ break;
+ case (short)VMProtect.OpCodes.icBgt:
+ wr.Write((byte)VMProtect.OpCodes.icCgt);
+ break;
+ case (short)VMProtect.OpCodes.icBgt_un:
+ wr.Write((byte)VMProtect.OpCodes.icCgt_un);
+ break;
+ */
+ }
+ // FIXME
+ //wr.Write((byte)VMProtect.OpCodes.icConv_b);
+ wr.Write((byte)VMProtect.OpCodes.icNeg);
+ switch ((short)vmInstrInfo.Value)
+ {
+ case (short)VMProtect.OpCodes.icBne_un:
+ //case (short)VMProtect.OpCodes.icBle:
+ //case (short)VMProtect.OpCodes.icBle_un:
+ //case (short)VMProtect.OpCodes.icBge:
+ //case (short)VMProtect.OpCodes.icBge_un:
+ case (short)VMProtect.OpCodes.icBrfalse:
+ wr.Write((byte)VMProtect.OpCodes.icNot);
+ break;
+ }
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ deferredBrTargets[ret.Position] = (uint)sr.BaseStream.Position + (uint)operand;
+ wr.Write(dummy);
+ wr.Write((byte)VMProtect.OpCodes.icAnd);
+ wr.Write((byte)VMProtect.OpCodes.icDup);
+ // FIXME
+ //wr.Write((byte)VMProtect.OpCodes.icConv_b);
+ wr.Write((byte)VMProtect.OpCodes.icNeg);
+ wr.Write((byte)VMProtect.OpCodes.icNot);
+ wr.Write((byte)VMProtect.OpCodes.icLdc_i4);
+ deferredBrTargets[ret.Position] = (uint)sr.BaseStream.Position;
+ wr.Write(dummy);
+ wr.Write((byte)VMProtect.OpCodes.icAnd);
+ wr.Write((byte)VMProtect.OpCodes.icAdd);
+ wr.Write((byte)VMProtect.OpCodes.icBr);
+ break;
+ default:
+ wr.Write((byte)vmInstrInfo.Value);
+ break;
+ }
+ wr.Flush();
+ }
+ foreach (var t in fwdTypeDefs.Keys.ToArray())
+ {
+ fwdTypeDefs[t] = GetTypeTokenInModule(t);
+ }
+ foreach (var r in fwdTypeRefs)
+ {
+ ret.Position = r.Key;
+ wr.Write(fwdTypeDefs[r.Value]);
+ wr.Flush();
+ }
+ foreach (var r in deferredBrTargets)
+ {
+ ret.Position = r.Key;
+ var srcPos = r.Value;
+ wr.Write(srcToDstInstrPositions[srcPos]);
+ wr.Flush();
+ }
+ ret.Position = 0;
+ return ret;
+ }
+ }
+
+ public override object Invoke(object[] parameters, Stream vmStream)
+ {
+ var contents = new BinaryReader(vmStream).ReadBytes((int) vmStream.Length);
+ var unmanagedPointer = Marshal.AllocHGlobal(contents.Length);
+ Marshal.Copy(contents, 0, unmanagedPointer, contents.Length);
+ var vm = new VirtualMachine();
+ // ReSharper disable once PossibleNullReferenceException
+ typeof(VirtualMachine).GetField("_instance", BindingFlags.Instance | BindingFlags.NonPublic)
+ .SetValue(vm, unmanagedPointer.ToInt64());
+ var vmRet = vm.Invoke(parameters, 0);
+ Marshal.FreeHGlobal(unmanagedPointer);
+ return vmRet;
+ }
+ }
+
+ public class MsilToVmTestCompilerRefVm : MsilToVmTestCompiler
+ {
+ public static readonly VmInstrCodesDb InstrCodesDb = new VmInstrCodesDb();
+ #region opcodes
+ public static readonly Dictionary<short, KeyValuePair<OpCode, VmInstrInfo>> IlToVmInstrInfo = new Dictionary<short, KeyValuePair<OpCode, VmInstrInfo>>()
+ {
+ { OpCodes.Add.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Add, InstrCodesDb.Add_) },
+ { OpCodes.Add_Ovf.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Add_Ovf, InstrCodesDb.Add_ovf_) },
+ { OpCodes.Add_Ovf_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Add_Ovf_Un, InstrCodesDb.Add_ovf_un_) },
+ { OpCodes.And.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.And, InstrCodesDb.And_) },
+ //{ OpCodes.Arglist.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Arglist, InstrCodesDb.Arglist_) },
+ { OpCodes.Beq_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Beq_S, InstrCodesDb.Beq_) },
+ { OpCodes.Bge_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Bge_S, InstrCodesDb.Bge_) },
+ { OpCodes.Bge_Un_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Bge_Un_S, InstrCodesDb.Bge_un_) },
+ { OpCodes.Bgt_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Bgt_S, InstrCodesDb.Bgt_) },
+ { OpCodes.Bgt_Un_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Bgt_Un_S, InstrCodesDb.Bgt_un_) },
+ { OpCodes.Ble_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ble_S, InstrCodesDb.Ble_) },
+ { OpCodes.Ble_Un_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ble_Un_S, InstrCodesDb.Ble_un_) },
+ { OpCodes.Blt_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Blt_S, InstrCodesDb.Blt_) },
+ { OpCodes.Blt_Un_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Blt_Un_S, InstrCodesDb.Blt_un_) },
+ { OpCodes.Bne_Un_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Bne_Un_S, InstrCodesDb.Bne_un_) },
+ //{ OpCodes.Box.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Box, InstrCodesDb.Box_) },
+ { OpCodes.Br_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Br_S, InstrCodesDb.Br_) },
+ //{ OpCodes.Break.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Break, InstrCodesDb.Break_) },
+ //{ OpCodes.Brfalse_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Brfalse_S, InstrCodesDb.Brfalse_S_) },
+ //{ OpCodes.Brtrue_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Brtrue_S, InstrCodesDb.Brtrue_S_) },
+ { OpCodes.Call.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Call, InstrCodesDb.Call_) },
+ //{ OpCodes.Calli.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Calli, InstrCodesDb.Calli_) },
+ //{ OpCodes.Callvirt.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Callvirt, InstrCodesDb.Callvirt_) },
+ //{ OpCodes.Castclass.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Castclass, InstrCodesDb.Castclass_) },
+ { OpCodes.Ceq.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ceq, InstrCodesDb.Ceq_) },
+ { OpCodes.Cgt.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Cgt, InstrCodesDb.Cgt_) },
+ { OpCodes.Cgt_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Cgt_Un, InstrCodesDb.Cgt_un_) },
+ { OpCodes.Ckfinite.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ckfinite, InstrCodesDb.Ckfinite_) },
+ { OpCodes.Clt.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Clt, InstrCodesDb.Clt_) },
+ { OpCodes.Clt_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Clt_Un, InstrCodesDb.Clt_un_) },
+ //{ OpCodes.Constrained.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Constrained, InstrCodesDb.Constrained_) },
+ { OpCodes.Conv_I.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_I, InstrCodesDb.Conv_i_) },
+ { OpCodes.Conv_I1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_I1, InstrCodesDb.Conv_i1_) },
+ { OpCodes.Conv_I2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_I2, InstrCodesDb.Conv_i2_) },
+ { OpCodes.Conv_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_I4, InstrCodesDb.Conv_i4_) },
+ { OpCodes.Conv_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_I8, InstrCodesDb.Conv_i8_) },
+ { OpCodes.Conv_Ovf_I.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I, InstrCodesDb.Conv_ovf_i_) },
+ { OpCodes.Conv_Ovf_I_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I_Un, InstrCodesDb.Conv_ovf_i_un_) },
+ { OpCodes.Conv_Ovf_I1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I1, InstrCodesDb.Conv_ovf_i1_) },
+ { OpCodes.Conv_Ovf_I1_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I1_Un, InstrCodesDb.Conv_ovf_i1_un_) },
+ { OpCodes.Conv_Ovf_I2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I2, InstrCodesDb.Conv_ovf_i2_) },
+ { OpCodes.Conv_Ovf_I2_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I2_Un, InstrCodesDb.Conv_ovf_i2_un_) },
+ { OpCodes.Conv_Ovf_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I4, InstrCodesDb.Conv_ovf_i4_) },
+ { OpCodes.Conv_Ovf_I4_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I4_Un, InstrCodesDb.Conv_ovf_i4_un_) },
+ { OpCodes.Conv_Ovf_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I8, InstrCodesDb.Conv_ovf_i8_) },
+ { OpCodes.Conv_Ovf_I8_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_I8_Un, InstrCodesDb.Conv_ovf_i8_un_) },
+ { OpCodes.Conv_Ovf_U.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U, InstrCodesDb.Conv_ovf_u_) },
+ { OpCodes.Conv_Ovf_U_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U_Un, InstrCodesDb.Conv_ovf_u_un_) },
+ { OpCodes.Conv_Ovf_U1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U1, InstrCodesDb.Conv_ovf_u1_) },
+ { OpCodes.Conv_Ovf_U1_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U1_Un, InstrCodesDb.Conv_ovf_u1_un_) },
+ { OpCodes.Conv_Ovf_U2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U2, InstrCodesDb.Conv_ovf_u2_) },
+ { OpCodes.Conv_Ovf_U2_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U2_Un, InstrCodesDb.Conv_ovf_u2_un_) },
+ { OpCodes.Conv_Ovf_U4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U4, InstrCodesDb.Conv_ovf_u4_) },
+ { OpCodes.Conv_Ovf_U4_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U4_Un, InstrCodesDb.Conv_ovf_u4_un_) },
+ { OpCodes.Conv_Ovf_U8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U8, InstrCodesDb.Conv_ovf_u8_) },
+ { OpCodes.Conv_Ovf_U8_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_Ovf_U8_Un, InstrCodesDb.Conv_ovf_u8_un_) },
+ { OpCodes.Conv_R_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_R_Un, InstrCodesDb.Conv_r_un_) },
+ { OpCodes.Conv_R4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_R4, InstrCodesDb.Conv_r4_) },
+ { OpCodes.Conv_R8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_R8, InstrCodesDb.Conv_r8_) },
+ { OpCodes.Conv_U.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_U, InstrCodesDb.Conv_u_) },
+ { OpCodes.Conv_U1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_U1, InstrCodesDb.Conv_u1_) },
+ { OpCodes.Conv_U2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_U2, InstrCodesDb.Conv_u2_) },
+ { OpCodes.Conv_U4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_U4, InstrCodesDb.Conv_u4_) },
+ { OpCodes.Conv_U8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Conv_U8, InstrCodesDb.Conv_u8_) },
+ //{ OpCodes.Cpblk.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Cpblk, InstrCodesDb.Cpblk_) },
+ //{ OpCodes.Cpobj.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Cpobj, InstrCodesDb.Cpobj_) },
+ { OpCodes.Div.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Div, InstrCodesDb.Div_) },
+ { OpCodes.Div_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Div_Un, InstrCodesDb.Div_un_) },
+ //{ OpCodes.Dup.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Dup, InstrCodesDb.Dup_) },
+ //{ OpCodes.Endfilter.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Endfilter, InstrCodesDb.Endfilter_) },
+ //{ OpCodes.Endfinally.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Endfinally, InstrCodesDb.Endfinally_) },
+ //{ OpCodes.Initblk.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Initblk, InstrCodesDb.Initblk_) },
+ //{ OpCodes.Initobj.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Initobj, InstrCodesDb.Initobj_) },
+ //{ OpCodes.Isinst.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Isinst, InstrCodesDb.Isinst_) },
+ //{ OpCodes.Jmp.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Jmp, InstrCodesDb.Jmp_) },
+ //{ OpCodes.Ldarg.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarg, InstrCodesDb.Ldarg_) },
+ { OpCodes.Ldarg_0.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarg_0, InstrCodesDb.Ldarg_0_) },
+ { OpCodes.Ldarg_1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarg_1, InstrCodesDb.Ldarg_1_) },
+ //{ OpCodes.Ldarg_2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarg_2, InstrCodesDb.Ldarg_2_) },
+ //{ OpCodes.Ldarg_3.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarg_3, InstrCodesDb.Ldarg_3_) },
+ //{ OpCodes.Ldarg_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarg_S, InstrCodesDb.Ldarg_S_) },
+ //{ OpCodes.Ldarga.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarga, InstrCodesDb.Ldarga_) },
+ { OpCodes.Ldarga_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldarga_S, InstrCodesDb.Ldarga_s_) },
+ //{ OpCodes.Ldc_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4, InstrCodesDb.Ldc_i4_) },
+ { OpCodes.Ldc_I4_0.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_0, InstrCodesDb.Ldc_i4_0_) },
+ { OpCodes.Ldc_I4_1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_1, InstrCodesDb.Ldc_i4_1_) },
+ //{ OpCodes.Ldc_I4_2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_2, InstrCodesDb.Ldc_i4_2_) },
+ //{ OpCodes.Ldc_I4_3.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_3, InstrCodesDb.Ldc_I4_3_) },
+ //{ OpCodes.Ldc_I4_4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_4, InstrCodesDb.Ldc_I4_4_) },
+ //{ OpCodes.Ldc_I4_5.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_5, InstrCodesDb.Ldc_I4_5_) },
+ //{ OpCodes.Ldc_I4_6.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_6, InstrCodesDb.Ldc_I4_6_) },
+ //{ OpCodes.Ldc_I4_7.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_7, InstrCodesDb.Ldc_I4_7_) },
+ //{ OpCodes.Ldc_I4_8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_8, InstrCodesDb.Ldc_I4_8_) },
+ //{ OpCodes.Ldc_I4_M1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_M1, InstrCodesDb.Ldc_I4_M1_) },
+ //{ OpCodes.Ldc_I4_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I4_S, InstrCodesDb.Ldc_I4_S_) },
+ //{ OpCodes.Ldc_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_I8, InstrCodesDb.Ldc_I8_) },
+ //{ OpCodes.Ldc_R4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_R4, InstrCodesDb.Ldc_R4_) },
+ //{ OpCodes.Ldc_R8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldc_R8, InstrCodesDb.Ldc_R8_) },
+ //{ OpCodes.Ldelem.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem, InstrCodesDb.Ldelem_) },
+ //{ OpCodes.Ldelem_I.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_I, InstrCodesDb.Ldelem_I_) },
+ //{ OpCodes.Ldelem_I1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_I1, InstrCodesDb.Ldelem_I1_) },
+ //{ OpCodes.Ldelem_I2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_I2, InstrCodesDb.Ldelem_I2_) },
+ //{ OpCodes.Ldelem_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_I4, InstrCodesDb.Ldelem_I4_) },
+ //{ OpCodes.Ldelem_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_I8, InstrCodesDb.Ldelem_I8_) },
+ //{ OpCodes.Ldelem_R4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_R4, InstrCodesDb.Ldelem_R4_) },
+ //{ OpCodes.Ldelem_R8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_R8, InstrCodesDb.Ldelem_R8_) },
+ //{ OpCodes.Ldelem_Ref.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_Ref, InstrCodesDb.Ldelem_Ref_) },
+ //{ OpCodes.Ldelem_U1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_U1, InstrCodesDb.Ldelem_U1_) },
+ //{ OpCodes.Ldelem_U2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_U2, InstrCodesDb.Ldelem_U2_) },
+ //{ OpCodes.Ldelem_U4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelem_U4, InstrCodesDb.Ldelem_U4_) },
+ //{ OpCodes.Ldelema.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldelema, InstrCodesDb.Ldelema_) },
+ //{ OpCodes.Ldfld.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldfld, InstrCodesDb.Ldfld_) },
+ //{ OpCodes.Ldflda.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldflda, InstrCodesDb.Ldflda_) },
+ //{ OpCodes.Ldftn.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldftn, InstrCodesDb.Ldftn_) },
+ //{ OpCodes.Ldind_I.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_I, InstrCodesDb.Ldind_I_) },
+ //{ OpCodes.Ldind_I1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_I1, InstrCodesDb.Ldind_I1_) },
+ //{ OpCodes.Ldind_I2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_I2, InstrCodesDb.Ldind_I2_) },
+ //{ OpCodes.Ldind_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_I4, InstrCodesDb.Ldind_I4_) },
+ //{ OpCodes.Ldind_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_I8, InstrCodesDb.Ldind_I8_) },
+ //{ OpCodes.Ldind_R4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_R4, InstrCodesDb.Ldind_R4_) },
+ //{ OpCodes.Ldind_R8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_R8, InstrCodesDb.Ldind_R8_) },
+ //{ OpCodes.Ldind_Ref.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_Ref, InstrCodesDb.Ldind_Ref_) },
+ //{ OpCodes.Ldind_U1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_U1, InstrCodesDb.Ldind_U1_) },
+ //{ OpCodes.Ldind_U2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_U2, InstrCodesDb.Ldind_U2_) },
+ //{ OpCodes.Ldind_U4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldind_U4, InstrCodesDb.Ldind_U4_) },
+ //{ OpCodes.Ldlen.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldlen, InstrCodesDb.Ldlen_) },
+ //{ OpCodes.Ldloc.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloc, InstrCodesDb.Ldloc_) },
+ //{ OpCodes.Ldloc_0.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloc_0, InstrCodesDb.Ldloc_0_) },
+ //{ OpCodes.Ldloc_1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloc_1, InstrCodesDb.Ldloc_1_) },
+ //{ OpCodes.Ldloc_2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloc_2, InstrCodesDb.Ldloc_2_) },
+ //{ OpCodes.Ldloc_3.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloc_3, InstrCodesDb.Ldloc_3_) },
+ //{ OpCodes.Ldloc_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloc_S, InstrCodesDb.Ldloc_S_) },
+ //{ OpCodes.Ldloca.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloca, InstrCodesDb.Ldloca_) },
+ //{ OpCodes.Ldloca_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldloca_S, InstrCodesDb.Ldloca_S_) },
+ //{ OpCodes.Ldnull.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldnull, InstrCodesDb.Ldnull_) },
+ //{ OpCodes.Ldobj.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldobj, InstrCodesDb.Ldobj_) },
+ //{ OpCodes.Ldsfld.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldsfld, InstrCodesDb.Ldsfld_) },
+ //{ OpCodes.Ldsflda.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldsflda, InstrCodesDb.Ldsflda_) },
+ //{ OpCodes.Ldstr.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldstr, InstrCodesDb.Ldstr_) },
+ //{ OpCodes.Ldtoken.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldtoken, InstrCodesDb.Ldtoken_) },
+ //{ OpCodes.Ldvirtftn.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ldvirtftn, InstrCodesDb.Ldvirtftn_) },
+ //{ OpCodes.Leave.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Leave, InstrCodesDb.Leave_) },
+ //{ OpCodes.Leave_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Leave_S, InstrCodesDb.Leave_S_) },
+ //{ OpCodes.Localloc.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Localloc, InstrCodesDb.Localloc_) },
+ //{ OpCodes.Mkrefany.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Mkrefany, InstrCodesDb.Mkrefany_) },
+ { OpCodes.Mul.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Mul, InstrCodesDb.Mul_) },
+ { OpCodes.Mul_Ovf.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Mul_Ovf, InstrCodesDb.Mul_ovf_) },
+ { OpCodes.Mul_Ovf_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Mul_Ovf_Un, InstrCodesDb.Mul_ovf_un_) },
+ //{ OpCodes.Neg.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Neg, InstrCodesDb.Neg_) },
+ //{ OpCodes.Newarr.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Newarr, InstrCodesDb.Newarr_) },
+ { OpCodes.Newobj.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Newobj, InstrCodesDb.Newobj_) },
+ //{ OpCodes.Nop.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Nop, InstrCodesDb.Nop_) },
+ { OpCodes.Not.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Not, InstrCodesDb.Not_) },
+ { OpCodes.Or.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Or, InstrCodesDb.Or_) },
+ //{ OpCodes.Pop.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Pop, InstrCodesDb.Pop_) },
+ //{ OpCodes.Prefix1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix1, InstrCodesDb.Prefix1_) },
+ //{ OpCodes.Prefix2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix2, InstrCodesDb.Prefix2_) },
+ //{ OpCodes.Prefix3.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix3, InstrCodesDb.Prefix3_) },
+ //{ OpCodes.Prefix4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix4, InstrCodesDb.Prefix4_) },
+ //{ OpCodes.Prefix5.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix5, InstrCodesDb.Prefix5_) },
+ //{ OpCodes.Prefix6.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix6, InstrCodesDb.Prefix6_) },
+ //{ OpCodes.Prefix7.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefix7, InstrCodesDb.Prefix7_) },
+ //{ OpCodes.Prefixref.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Prefixref, InstrCodesDb.Prefixref_) },
+ //{ OpCodes.Readonly.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Readonly, InstrCodesDb.Readonly_) },
+ //{ OpCodes.Refanytype.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Refanytype, InstrCodesDb.Refanytype_) },
+ //{ OpCodes.Refanyval.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Refanyval, InstrCodesDb.Refanyval_) },
+ { OpCodes.Rem.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Rem, InstrCodesDb.Rem_) },
+ { OpCodes.Rem_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Rem_Un, InstrCodesDb.Rem_un_) },
+ { OpCodes.Ret.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Ret, InstrCodesDb.Ret_) },
+ //{ OpCodes.Rethrow.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Rethrow, InstrCodesDb.Rethrow_) },
+ { OpCodes.Shl.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Shl, InstrCodesDb.Shl_) },
+ { OpCodes.Shr.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Shr, InstrCodesDb.Shr_) },
+ { OpCodes.Shr_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Shr_Un, InstrCodesDb.Shr_un_) },
+ //{ OpCodes.Sizeof.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Sizeof, InstrCodesDb.Sizeof_) },
+ //{ OpCodes.Starg.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Starg, InstrCodesDb.Starg_) },
+ //{ OpCodes.Starg_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Starg_S, InstrCodesDb.Starg_S_) },
+ //{ OpCodes.Stelem.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem, InstrCodesDb.Stelem_) },
+ //{ OpCodes.Stelem_I.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_I, InstrCodesDb.Stelem_I_) },
+ //{ OpCodes.Stelem_I1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_I1, InstrCodesDb.Stelem_I1_) },
+ //{ OpCodes.Stelem_I2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_I2, InstrCodesDb.Stelem_i2_) },
+ //{ OpCodes.Stelem_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_I4, InstrCodesDb.Stelem_I4_) },
+ //{ OpCodes.Stelem_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_I8, InstrCodesDb.Stelem_I8_) },
+ //{ OpCodes.Stelem_R4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_R4, InstrCodesDb.Stelem_R4_) },
+ //{ OpCodes.Stelem_R8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_R8, InstrCodesDb.Stelem_R8_) },
+ //{ OpCodes.Stelem_Ref.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stelem_Ref, InstrCodesDb.Stelem_Ref_) },
+ //{ OpCodes.Stfld.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stfld, InstrCodesDb.Stfld_) },
+ //{ OpCodes.Stind_I.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_I, InstrCodesDb.Stind_I_) },
+ //{ OpCodes.Stind_I1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_I1, InstrCodesDb.Stind_I1_) },
+ //{ OpCodes.Stind_I2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_I2, InstrCodesDb.Stind_I2_) },
+ //{ OpCodes.Stind_I4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_I4, InstrCodesDb.Stind_I4_) },
+ //{ OpCodes.Stind_I8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_I8, InstrCodesDb.Stind_I8_) },
+ //{ OpCodes.Stind_R4.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_R4, InstrCodesDb.Stind_R4_) },
+ //{ OpCodes.Stind_R8.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_R8, InstrCodesDb.Stind_R8_) },
+ //{ OpCodes.Stind_Ref.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stind_Ref, InstrCodesDb.Stind_Ref_) },
+ //{ OpCodes.Stloc.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stloc, InstrCodesDb.Stloc_) },
+ //{ OpCodes.Stloc_0.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stloc_0, InstrCodesDb.Stloc_0_) },
+ //{ OpCodes.Stloc_1.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stloc_1, InstrCodesDb.Stloc_1_) },
+ //{ OpCodes.Stloc_2.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stloc_2, InstrCodesDb.Stloc_2_) },
+ //{ OpCodes.Stloc_3.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stloc_3, InstrCodesDb.Stloc_3_) },
+ //{ OpCodes.Stloc_S.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stloc_S, InstrCodesDb.Stloc_S_) },
+ //{ OpCodes.Stobj.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stobj, InstrCodesDb.Stobj_) },
+ //{ OpCodes.Stsfld.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Stsfld, InstrCodesDb.Stsfld_) },
+ { OpCodes.Sub.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Sub, InstrCodesDb.Sub_) },
+ { OpCodes.Sub_Ovf.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Sub_Ovf, InstrCodesDb.Sub_ovf_) },
+ { OpCodes.Sub_Ovf_Un.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Sub_Ovf_Un, InstrCodesDb.Sub_ovf_un_) },
+ //{ OpCodes.Switch.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Switch, InstrCodesDb.Switch_) },
+ //{ OpCodes.Tailcall.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Tailcall, InstrCodesDb.Tailcall_) },
+ //{ OpCodes.Throw.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Throw, InstrCodesDb.Throw_) },
+ //{ OpCodes.Unaligned.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Unaligned, InstrCodesDb.Unaligned_) },
+ //{ OpCodes.Unbox.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Unbox, InstrCodesDb.Unbox_) },
+ //{ OpCodes.Unbox_Any.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Unbox_Any, InstrCodesDb.Unbox_Any_) },
+ //{ OpCodes.Volatile.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Volatile, InstrCodesDb.Volatile_) },
+ { OpCodes.Xor.Value, new KeyValuePair<OpCode, VmInstrInfo>(OpCodes.Xor, InstrCodesDb.Xor_) },
+ };
+ #endregion
+ public override Stream CreateVmStream(Type rt, ParameterInfo[] pi, Type[] locals, byte [] ilBytes /*GetIlBytes(src)*/)
+ {
+ var ret = new MemoryStream();
+ var wr = new BinaryWriter(ret);
+ var fwdTypeDefs = new Dictionary<Type, int>();
+ var fwdTypeRefs = new Dictionary<int, Type>();
+ var fwdMethodTokenDefs = new Dictionary<UInt32, int>();
+ var fwdMethodTokenRefs = new Dictionary<long, UInt32>();
+ var deferredBrTargets = new Dictionary<long, UInt32>();
+ var srcToDstInstrPositions = new Dictionary<long, UInt32>();
+ wr.Write(0); // ClassId
+ wr.Flush();
+ const int dummy = 0x55555555;
+ fwdTypeDefs.Add(rt, dummy);
+ fwdTypeRefs.Add((int)ret.Position, rt);
+ wr.Write(dummy); // ReturnTypeId fwd ref
+ wr.Write((ushort)0); // LocalVarTypes
+ wr.Write((byte)2); // Flags - static
+ wr.Write((byte)0); // Name
+ var pars = pi;
+ wr.Write((ushort)pars.Length); // ArgsTypeToOutput
+ foreach (var parameterInfo in pars)
+ {
+ if (!fwdTypeDefs.ContainsKey(parameterInfo.ParameterType))
+ fwdTypeDefs.Add(parameterInfo.ParameterType, dummy);
+ fwdTypeRefs.Add((int)ret.Position, parameterInfo.ParameterType);
+ wr.Write(dummy); // parTypeId fwd ref
+ wr.Write(false);
+ }
+ wr.Write((ushort)locals.Length); // LocalVarTypes
+ foreach (var lt in locals)
+ {
+ if (!fwdTypeDefs.ContainsKey(lt))
+ fwdTypeDefs.Add(lt, dummy);
+ fwdTypeRefs.Add((int)ret.Position, lt);
+ wr.Write(dummy); // parTypeId fwd ref
+ }
+
+ var methodLengthPos = ret.Position;
+ wr.Write(dummy); // methodLength
+ using (var sr = new BinaryReader(new MemoryStream(ilBytes)))
+ {
+ while (sr.BaseStream.Position < sr.BaseStream.Length)
+ {
+ srcToDstInstrPositions[sr.BaseStream.Position] = (uint)ret.Position;
+ short ilByte = sr.ReadByte();
+ if (ilByte == 0xFE)
+ ilByte = (short)((ilByte << 8) | sr.ReadByte());
+ Assert.IsTrue(IlToVmInstrInfo.ContainsKey(ilByte), "Extend IlToVmInstrInfo with {0:X} or use short jump", ilByte);
+ var vmInstrInfo = IlToVmInstrInfo[ilByte];
+ var id = vmInstrInfo.Value.Id;
+ wr.Write((ushort)(id >> 16));
+ wr.Write((ushort)(id & 0xFFFF));
+ wr.Flush();
+ ulong operand = 0;
+ switch (vmInstrInfo.Key.OperandType)
+ {
+ case OperandType.InlineNone:
+ break;
+ case OperandType.InlineI8:
+ case OperandType.InlineR:
+ operand = sr.ReadUInt64();
+ break;
+ case OperandType.InlineVar:
+ operand = sr.ReadUInt16();
+ break;
+ case OperandType.ShortInlineBrTarget:
+ case OperandType.ShortInlineI:
+ case OperandType.ShortInlineVar:
+ operand = sr.ReadByte();
+ break;
+ default:
+ operand = sr.ReadUInt32();
+ break;
+ }
+ if (vmInstrInfo.Key.OperandType == OperandType.ShortInlineBrTarget)
+ {
+ deferredBrTargets[wr.BaseStream.Position] = (uint)sr.BaseStream.Position + (uint)operand;
+ }
+ if (vmInstrInfo.Key.Value == OpCodes.Newobj.Value || vmInstrInfo.Key.Value == OpCodes.Call.Value)
+ {
+ var token = (uint)operand;
+ if (!fwdMethodTokenDefs.ContainsKey(token))
+ fwdMethodTokenDefs.Add(token, dummy);
+ fwdMethodTokenRefs[wr.BaseStream.Position] = token;
+ }
+ switch (vmInstrInfo.Value.OperandType)
+ {
+ case VmOperandType.Ot11Nope:
+ break;
+ case VmOperandType.Ot2Byte:
+ case VmOperandType.Ot6SByte:
+ case VmOperandType.Ot8Byte:
+ wr.Write((byte)operand);
+ break;
+ case VmOperandType.Ot1UShort:
+ case VmOperandType.Ot3UShort:
+ wr.Write((ushort)operand);
+ break;
+ case VmOperandType.Ot0UInt:
+ case VmOperandType.Ot12Int:
+ case VmOperandType.Ot5Int:
+ case VmOperandType.Ot10Float:
+ wr.Write((uint)operand);
+ break;
+ case VmOperandType.Ot7Long:
+ case VmOperandType.Ot4Double:
+ wr.Write(operand);
+ break;
+ default:
+ throw new InvalidDataException("OperandType");
+ }
+ }
+ ret.Position = methodLengthPos;
+ wr.Write((int)(ret.Length - methodLengthPos - 4));
+ wr.Flush();
+ ret.Position = ret.Length;
+ foreach (var t in fwdTypeDefs.Keys.ToArray())
+ {
+ fwdTypeDefs[t] = (int)ret.Position;
+ wr.Write(true);
+ wr.Write((byte)0);
+ wr.Write(-1);
+ wr.Write(-1);
+ wr.Write(false);
+ // ReSharper disable once AssignNullToNotNullAttribute
+ wr.Write(t.AssemblyQualifiedName);
+ wr.Write(false);
+ wr.Write((ushort)0);
+ wr.Flush();
+ }
+ foreach (var t in fwdMethodTokenDefs.Keys.ToArray())
+ {
+ fwdMethodTokenDefs[t] = (int)ret.Position;
+ wr.Write((byte)0);
+ wr.Write(t);
+ wr.Flush();
+ }
+ foreach (var r in fwdTypeRefs)
+ {
+ ret.Position = r.Key;
+ wr.Write(fwdTypeDefs[r.Value]);
+ wr.Flush();
+ }
+ foreach (var t in fwdMethodTokenRefs)
+ {
+ ret.Position = t.Key;
+ wr.Write((ushort)(fwdMethodTokenDefs[t.Value]>>16));
+ wr.Write((ushort)fwdMethodTokenDefs[t.Value]);
+ wr.Flush();
+ }
+ foreach (var r in deferredBrTargets)
+ {
+ ret.Position = r.Key;
+ var srcPos = r.Value;
+ wr.Write(srcToDstInstrPositions[srcPos] - (uint)methodLengthPos - 4);
+ wr.Flush();
+ }
+ ret.Position = 0;
+ return ret;
+ }
+ }
+ public override object Invoke(object[] parameters, Stream vmStream)
+ {
+ var vmStreamWrapper = new VmStreamWrapper(vmStream, VmExecutor.VmXorKey());
+ var callees = new object[]
+ {
+ Assembly.GetCallingAssembly()
+ };
+ var vm = new VmExecutor(InstrCodesDb, vmStreamWrapper);
+ vm.Seek(0, vmStreamWrapper, null);
+ var vmRet = vm.Invoke(parameters, null, null, callees);
+ return vmRet;
+ }
+ }
+
+ internal static class ExtendedEcma335
+ {
+ internal static object AsStackedValue(object v, bool signedComparison) // как это значение будет лежать на стеке
+ {
+ Type t = v.GetType();
+ if (IsFloatingType(t))
+ return v;
+ //остальное приводится к Int32 или Int64
+ if (t.IsEnum) t = t.GetEnumUnderlyingType();
+ if (t == typeof (byte)) return signedComparison ? (object) (Int32) (byte) v : (UInt32) (byte)v;
+ if (t == typeof (sbyte)) return signedComparison ? (object) (Int32) (sbyte) v : (UInt32) (sbyte)v;
+ if (t == typeof (short)) return signedComparison ? (object) (Int32) (short) v : (UInt32) (short)v;
+ if (t == typeof (ushort)) return signedComparison ? (object) (Int32) (ushort)v : (UInt32)(ushort) v;
+ if (t == typeof (Char)) return signedComparison ? (object) (Int32) (Char)v : (UInt32) (Char) v;
+ if (t == typeof (Int32)) return signedComparison ? (object) (Int32) v : (UInt32) (Int32)v;
+ if (t == typeof (UInt32)) return signedComparison ? (object) (Int32) (UInt32) v : (UInt32)v;
+ if (t == typeof(Int64)) return signedComparison ? (object) (Int64)v : (UInt64) (Int64)v;
+ if (t == typeof (UInt64)) return signedComparison ? (object) (Int64) (UInt64) v : (UInt64)v;
+ if (t == typeof(bool)) return signedComparison ? (object) ((bool)v ? 1 : 0) : (UInt32) ((bool)v ? 1 : 0);
+ if (t == typeof(IntPtr))
+ {
+ if (IntPtr.Size == 4)
+ return signedComparison ? (object)((IntPtr)v).ToInt32() : (UInt32)((IntPtr)v).ToInt32();
+ return signedComparison ? (object)((IntPtr)v).ToInt64() : (UInt64)((IntPtr)v).ToInt64();
+ }
+ if (t == typeof(UIntPtr))
+ {
+ if (UIntPtr.Size == 4)
+ return signedComparison ? (object)(Int32)((UIntPtr)v).ToUInt32() : ((UIntPtr)v).ToUInt32();
+ return signedComparison ? (object)(Int64)((UIntPtr)v).ToUInt64() : ((UIntPtr)v).ToUInt64();
+ }
+ return v;
+ }
+
+ [SuppressMessage("ReSharper", "RedundantCast")]
+ internal static bool Check(KeyValuePair<OpCode, UnitTestCombine.CodeTemplate> op, object[] parameters, object vmRet)
+ {
+ try
+ {
+ if (parameters.Length == 2 && op.Value == UnitTestCombine.CodeTemplate.TwoOpAny &&
+ (op.Key.Value == OpCodes.Shl.Value || op.Key.Value == OpCodes.Shr.Value ||
+ op.Key.Value == OpCodes.Shr_Un.Value))
+ {
+ var t0 = parameters[0].GetType();
+ var t1 = parameters[1].GetType();
+ if (t0 == typeof (object) || t1 == typeof (object))
+ return true; // TODO понять бы, почему нет совпадения с фреймфорком
+ if (IsFloatingType(t0) || IsFloatingType(t1))
+ return true; // в зависимости от разрядности фреймворк дурит по-разному
+ bool sign = op.Key.Value != OpCodes.Shr_Un.Value;
+ var commonType = UnitTestCombine.CompatibleType(t0, t1, sign);
+ if (commonType == typeof (Int64) || commonType == typeof (UInt64))
+ {
+ if (sign)
+ {
+ var p0 = Convert.ToInt64(AsStackedValue(parameters[0], true));
+ var p1 = Convert.ToInt64(AsStackedValue(parameters[1], true));
+ return Convert.ToInt64(AsStackedValue(vmRet, true)) ==
+ ((op.Key.Value == OpCodes.Shl.Value) ? (p1 << (int)p0) : (p1 >> (int)p0));
+ }
+ else
+ {
+ var p0 = Convert.ToUInt64(AsStackedValue(parameters[0], false));
+ var p1 = Convert.ToUInt64(AsStackedValue(parameters[1], false));
+ return Convert.ToUInt64(AsStackedValue(vmRet, false)) == (p1 >> (int) p0);
+ }
+ }
+ }
+ if (parameters.Length == 2 && op.Value == UnitTestCombine.CodeTemplate.TwoOpAny &&
+ (op.Key.Value == OpCodes.And.Value || op.Key.Value == OpCodes.Or.Value || op.Key.Value == OpCodes.Xor.Value))
+ {
+ var t0 = parameters[0].GetType();
+ var t1 = parameters[1].GetType();
+ if (t0 == typeof (object) || t1 == typeof (object))
+ return true; // TODO понять бы, почему нет совпадения с фреймфорком
+ if (IntPtr.Size == 8)
+ {
+ if (t0 == typeof (double) || t1 == typeof (double))
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return Convert.ToDouble(vmRet) == ((4 == IntPtr.Size) ? Double.NaN : (double) 0);
+ if (t0 == typeof (float) || t1 == typeof (float))
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return Convert.ToSingle(vmRet) == ((4 == IntPtr.Size) ? Single.NaN : (float) 0);
+ }
+ //x64, как более точный в фреймворке, не даёт сюда срабатываний
+ if (IntPtr.Size == 4 && t0 != t1)
+ {
+ var p0 = Convert.ToInt64(AsStackedValue(parameters[0], true));
+ var p1 = Convert.ToInt64(AsStackedValue(parameters[1], true));
+ Int64 check = 0;
+ if (op.Key.Value == OpCodes.And.Value) check = p0 & p1;
+ if (op.Key.Value == OpCodes.Or.Value) check = p0 | p1;
+ if (op.Key.Value == OpCodes.Xor.Value) check = p0 ^ p1;
+ return Convert.ToInt64(AsStackedValue(vmRet, true)) == check;
+ }
+ }
+ bool bAdd = op.Key.Value == OpCodes.Add.Value || op.Key.Value == OpCodes.Add_Ovf.Value ||
+ op.Key.Value == OpCodes.Add_Ovf_Un.Value;
+ bool bSub = op.Key.Value == OpCodes.Sub.Value || op.Key.Value == OpCodes.Sub_Ovf.Value ||
+ op.Key.Value == OpCodes.Sub_Ovf_Un.Value;
+ bool bMul = op.Key.Value == OpCodes.Mul.Value || op.Key.Value == OpCodes.Mul_Ovf.Value ||
+ op.Key.Value == OpCodes.Mul_Ovf_Un.Value;
+ bool bDiv = op.Key.Value == OpCodes.Div.Value || op.Key.Value == OpCodes.Div_Un.Value;
+ bool bRem = op.Key.Value == OpCodes.Rem.Value || op.Key.Value == OpCodes.Rem_Un.Value;
+ if (parameters.Length == 2 && op.Value == UnitTestCombine.CodeTemplate.TwoOpAny && (bAdd || bSub || bMul || bDiv || bRem))
+ {
+ var t0 = parameters[0].GetType();
+ var t1 = parameters[1].GetType();
+ if ((t0 == typeof (object) || t1 == typeof (object)) && (!(vmRet is Exception) || (op.Key.Value == OpCodes.Mul_Ovf.Value) || (op.Key.Value == OpCodes.Mul_Ovf_Un.Value) || (op.Key.Value == OpCodes.Sub_Ovf_Un.Value)))
+ return true; // TODO понять бы, почему нет совпадения с фреймфорком
+ // баг фреймворка в x64 Mul_Ovf_Un для плавающих
+ if (t0 == t1 && !(IntPtr.Size == 8 && op.Key.Value == OpCodes.Mul_Ovf_Un.Value && IsFloatingType(t0) && t0==t1)) return false;
+ bool sign = op.Key.Value != OpCodes.Add_Ovf_Un.Value && op.Key.Value != OpCodes.Sub_Ovf_Un.Value && op.Key.Value != OpCodes.Mul_Ovf_Un.Value && op.Key.Value != OpCodes.Div_Un.Value && op.Key.Value != OpCodes.Rem_Un.Value;
+ var commonType = UnitTestCombine.CompatibleType(t0, t1, sign);
+ if (commonType == typeof (Int64) || commonType == typeof (UInt64))
+ {
+ if (sign)
+ {
+ var p0 = Convert.ToInt64(AsStackedValue(parameters[0], true));
+ var p1 = Convert.ToInt64(AsStackedValue(parameters[1], true));
+ if (vmRet is OverflowException && (op.Key.Value == OpCodes.Add_Ovf.Value || op.Key.Value == OpCodes.Sub_Ovf.Value || op.Key.Value == OpCodes.Mul_Ovf.Value))
+ {
+ decimal res = bAdd ? ((decimal)p0 + (decimal)p1) : bSub ? ((decimal)p1 - (decimal)p0) : ((decimal)p1 * (decimal)p0);
+ if (commonType == typeof(Int64))
+ return res > (decimal)Int64.MaxValue || res < (decimal)Int64.MinValue;
+ if (commonType == typeof(UInt64))
+ return res > (decimal)UInt64.MaxValue || res < 0;
+ }
+ else
+ {
+ if (p0 == 0 && (bDiv || bRem)) return vmRet is DivideByZeroException;
+ try
+ {
+ return (bAdd ? (p0 + p1) : bSub ? (p1 - p0) : bMul ? (p1 * p0) : bDiv ? (p1 / p0) : (p1 % p0)) == Convert.ToInt64(AsStackedValue(vmRet, true));
+ }
+ catch (Exception e)
+ {
+ return e.GetType() == vmRet.GetType();
+ }
+ }
+ } else
+ {
+ var p0 = Convert.ToUInt64(AsStackedValue(parameters[0], false));
+ var p1 = Convert.ToUInt64(AsStackedValue(parameters[1], false));
+ if (vmRet is OverflowException && op.Key.Value == OpCodes.Sub_Ovf_Un.Value && 4 == IntPtr.Size)
+ {
+ decimal res = (decimal)p1 - (decimal)p0;
+ if (commonType == typeof(UInt64))
+ return res > (decimal)UInt64.MaxValue || res < 0;
+ }
+ else
+ {
+ if (p0 == 0 && (bDiv || bRem)) return vmRet is DivideByZeroException;
+ return Convert.ToUInt64(AsStackedValue(vmRet, false)) == (bAdd ? (p0 + p1) : bSub ? (p1 - p0) : bMul ? (p1 * p0) : bDiv ? (p1 / p0) : (p1 % p0));
+ }
+ }
+ } else if (commonType == typeof(float))
+ {
+ var p0 = Convert.ToSingle(AsStackedValue(parameters[0], sign));
+ var p1 = Convert.ToSingle(AsStackedValue(parameters[1], sign));
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ if (p0 == 0 && (bDiv || bRem)) return vmRet is DivideByZeroException;
+ var vm = Convert.ToSingle(AsStackedValue(vmRet, sign));
+ if (float.IsNaN(p0) || float.IsNaN(p1) || float.IsNaN(vm)) return true;
+ // ReSharper disable once RedundantCast
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return vm == (float)(bAdd ? (p0 + p1) : bSub ? (p1 - p0) : bMul ? (p1 * p0) : bDiv ? (p1 / p0) : (p1 % p0));
+ } else if (commonType == typeof(double))
+ {
+ var p0 = Convert.ToDouble(AsStackedValue(parameters[0], sign));
+ var p1 = Convert.ToDouble(AsStackedValue(parameters[1], sign));
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ if (p0 == 0 && (bDiv || bRem)) return vmRet is DivideByZeroException;
+ var vm = Convert.ToDouble(AsStackedValue(vmRet, sign));
+ if (double.IsNaN(p0) || double.IsNaN(p1) || double.IsNaN(vm)) return true;
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return vm == (bAdd ? (p0 + p1) : bSub ? (p1 - p0) : bMul ? (p1 * p0) : bDiv ? (p1 / p0) : (p1 % p0));
+ }
+ }
+ if (parameters.Length == 1 && op.Value == UnitTestCombine.CodeTemplate.SingleOpAny && op.Key.Value == OpCodes.Conv_U.Value)
+ {
+ if (IsFloatingType(parameters[0].GetType()) && !(vmRet is Exception))
+ {
+ // Framework использует мусор, мы возврвщаем 0
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return Convert.ToDouble(vmRet) == 0.0;
+ }
+ }
+ if (parameters.Length == 1 && op.Value == UnitTestCombine.CodeTemplate.SingleOpAny && op.Key.Value == OpCodes.Ckfinite.Value)
+ {
+ if (!IsFloatingType(parameters[0].GetType()) && !(vmRet is Exception))
+ {
+ double d = Double.NaN;
+ if (parameters[0] is IConvertible)
+ {
+ d = Convert.ToDouble(AsStackedValue(parameters[0], true));
+ }
+ return Convert.ToDouble(vmRet).Equals(d);
+ }
+ }
+ if (parameters.Length == 2 && (op.Value == UnitTestCombine.CodeTemplate.BranchTwoOpBool || op.Value == UnitTestCombine.CodeTemplate.TwoOpBool))
+ {
+ var signedComparison = (op.Key.Value == OpCodes.Bgt_S.Value || op.Key.Value == OpCodes.Ble_S.Value ||
+ op.Key.Value == OpCodes.Bge_S.Value || op.Key.Value == OpCodes.Blt_S.Value || op.Key.Value == OpCodes.Beq_S.Value ||
+ op.Key.Value == OpCodes.Cgt.Value || op.Key.Value == OpCodes.Clt.Value || op.Key.Value == OpCodes.Ceq.Value);
+ var unsignedUnorderedComparison = (op.Key.Value == OpCodes.Bgt_Un_S.Value || op.Key.Value == OpCodes.Ble_Un_S.Value ||
+ op.Key.Value == OpCodes.Bge_Un_S.Value || op.Key.Value == OpCodes.Blt_Un_S.Value ||
+ op.Key.Value == OpCodes.Cgt_Un.Value || op.Key.Value == OpCodes.Clt_Un.Value || op.Key.Value == OpCodes.Bne_Un_S.Value);
+ if (signedComparison || unsignedUnorderedComparison)
+ {
+ var isFloat = parameters.Select(o => IsFloatingType(o.GetType())).ToArray();
+ // разрешаем сравнивать такие типы
+ if (isFloat[0] != isFloat[1])
+ {
+ //F and int32/64
+ var vStacked = parameters.Select(o => AsStackedValue(o, true)).ToArray();
+ if (vStacked.Any(o => !(o is IConvertible)))
+ {
+ return (bool)vmRet == (op.Key.Value == OpCodes.Bne_Un_S.Value);
+ }
+ double a = Convert.ToDouble(vStacked[1]), b = Convert.ToDouble(vStacked[0]);
+ return Compare(op, vmRet, a, b, unsignedUnorderedComparison);
+ }
+ else if (isFloat.All(o => o == false))
+ {
+ var vStacked = parameters.Select(o => AsStackedValue(o, signedComparison)).ToArray();
+ if (vStacked.Any(o => !(o is IConvertible)))
+ {
+ return (bool)vmRet == false;
+ }
+ var vStackSize = vStacked.Select(o => Marshal.SizeOf(o.GetType())).ToArray();
+ if (vStackSize[0] != vStackSize[1])
+ {
+ //32 bit and 64 bit ints
+ if (signedComparison)
+ {
+ Int64 a = (vStackSize[1] == 8) ? (Int64)vStacked[1] : (Int32)vStacked[1];
+ Int64 b = (vStackSize[0] == 8) ? (Int64)vStacked[0] : (Int32)vStacked[0];
+ return Compare(op, vmRet, a, b);
+ }
+ else
+ {
+ UInt64 a = (vStackSize[1] == 8) ? (UInt64)vStacked[1] : (UInt32)vStacked[1];
+ UInt64 b = (vStackSize[0] == 8) ? (UInt64)vStacked[0] : (UInt32)vStacked[0];
+ return Compare(op, vmRet, a, b);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ Console.Error.WriteLine(exc);
+ }
+
+ return false;
+ }
+
+ private static bool Compare(KeyValuePair<OpCode, UnitTestCombine.CodeTemplate> op, object vmRet, Double a, Double b, bool unordered)
+ {
+ if (unordered && (Double.IsNaN(a) || Double.IsNaN(b)))
+ {
+ return true;
+ }
+ if (op.Key.Value == OpCodes.Bgt_S.Value || op.Key.Value == OpCodes.Bgt_Un_S.Value || op.Key.Value == OpCodes.Cgt.Value || op.Key.Value == OpCodes.Cgt_Un.Value)
+ return ((a > b) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Ble_S.Value || op.Key.Value == OpCodes.Ble_Un_S.Value)
+ return ((a <= b) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Bge_S.Value || op.Key.Value == OpCodes.Bge_Un_S.Value)
+ return ((a >= b) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Blt_S.Value || op.Key.Value == OpCodes.Blt_Un_S.Value || op.Key.Value == OpCodes.Clt.Value || op.Key.Value == OpCodes.Clt_Un.Value)
+ return ((a < b) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Ceq.Value || op.Key.Value == OpCodes.Beq_S.Value)
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return ((a == b) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Bne_Un_S.Value)
+ // ReSharper disable once CompareOfFloatsByEqualityOperator
+ return ((a != b) == (bool)vmRet);
+ Assert.Fail("Bad op for Compare");
+ return false;
+ }
+
+ private static bool Compare<T>(KeyValuePair<OpCode, UnitTestCombine.CodeTemplate> op, object vmRet, T a, T b) where T : IComparable<T>
+ {
+ if (op.Key.Value == OpCodes.Bgt_S.Value || op.Key.Value == OpCodes.Bgt_Un_S.Value || op.Key.Value == OpCodes.Cgt.Value || op.Key.Value == OpCodes.Cgt_Un.Value)
+ return ((a.CompareTo(b) > 0) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Ble_S.Value || op.Key.Value == OpCodes.Ble_Un_S.Value)
+ return ((a.CompareTo(b) <= 0) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Bge_S.Value || op.Key.Value == OpCodes.Bge_Un_S.Value)
+ return ((a.CompareTo(b) >= 0) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Blt_S.Value || op.Key.Value == OpCodes.Blt_Un_S.Value || op.Key.Value == OpCodes.Clt.Value || op.Key.Value == OpCodes.Clt_Un.Value)
+ return ((a.CompareTo(b) < 0) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Ceq.Value || op.Key.Value == OpCodes.Beq_S.Value)
+ return (a.Equals(b) == (bool)vmRet);
+ if (op.Key.Value == OpCodes.Bne_Un_S.Value)
+ return ((!a.Equals(b)) == (bool)vmRet);
+ Assert.Fail("Bad op for Compare");
+ return false;
+ }
+
+ private static bool IsFloatingType(Type t)
+ {
+ return t == typeof (Single) || t == typeof (Double);
+ }
+ }
+}