using System; using System.Collections.Generic; using System.Linq; namespace Indy.IL2CPU.IL { partial class ILReader { private static byte GetOperandSize(OpCodeEnum aOpCode) { switch (aOpCode) { case OpCodeEnum.Add: case OpCodeEnum.Add_Ovf: case OpCodeEnum.Add_Ovf_Un: case OpCodeEnum.And: case OpCodeEnum.Arglist: case OpCodeEnum.Break: case OpCodeEnum.Ceq: case OpCodeEnum.Cgt: case OpCodeEnum.Cgt_Un: case OpCodeEnum.Ckfinite: case OpCodeEnum.Clt: case OpCodeEnum.Clt_Un: case OpCodeEnum.Conv_I: case OpCodeEnum.Conv_I1: case OpCodeEnum.Conv_I2: case OpCodeEnum.Conv_I4: case OpCodeEnum.Conv_I8: case OpCodeEnum.Conv_Ovf_I: case OpCodeEnum.Conv_Ovf_I_Un: case OpCodeEnum.Conv_Ovf_I1: case OpCodeEnum.Conv_Ovf_I1_Un: case OpCodeEnum.Conv_Ovf_I2: case OpCodeEnum.Conv_Ovf_I2_Un: case OpCodeEnum.Conv_Ovf_I4: case OpCodeEnum.Conv_Ovf_I4_Un: case OpCodeEnum.Conv_Ovf_I8: case OpCodeEnum.Conv_Ovf_I8_Un: case OpCodeEnum.Conv_Ovf_U: case OpCodeEnum.Conv_Ovf_U_Un: case OpCodeEnum.Conv_Ovf_U1: case OpCodeEnum.Conv_Ovf_U1_Un: case OpCodeEnum.Conv_Ovf_U2: case OpCodeEnum.Conv_Ovf_U2_Un: case OpCodeEnum.Conv_Ovf_U4: case OpCodeEnum.Conv_Ovf_U4_Un: case OpCodeEnum.Conv_Ovf_U8: case OpCodeEnum.Conv_Ovf_U8_Un: case OpCodeEnum.Conv_R_Un: case OpCodeEnum.Conv_R4: case OpCodeEnum.Conv_R8: case OpCodeEnum.Conv_U: case OpCodeEnum.Conv_U1: case OpCodeEnum.Conv_U2: case OpCodeEnum.Conv_U4: case OpCodeEnum.Conv_U8: case OpCodeEnum.Cpblk: case OpCodeEnum.Div: case OpCodeEnum.Div_Un: case OpCodeEnum.Dup: case OpCodeEnum.Endfilter: case OpCodeEnum.Endfinally: case OpCodeEnum.Initblk: case OpCodeEnum.Ldarg_0: case OpCodeEnum.Ldarg_1: case OpCodeEnum.Ldarg_2: case OpCodeEnum.Ldarg_3: case OpCodeEnum.Ldc_I4_0: case OpCodeEnum.Ldc_I4_1: case OpCodeEnum.Ldc_I4_2: case OpCodeEnum.Ldc_I4_3: case OpCodeEnum.Ldc_I4_4: case OpCodeEnum.Ldc_I4_5: case OpCodeEnum.Ldc_I4_6: case OpCodeEnum.Ldc_I4_7: case OpCodeEnum.Ldc_I4_8: case OpCodeEnum.Ldc_I4_M1: case OpCodeEnum.Ldelem_I: case OpCodeEnum.Ldelem_I1: case OpCodeEnum.Ldelem_I2: case OpCodeEnum.Ldelem_I4: case OpCodeEnum.Ldelem_I8: case OpCodeEnum.Ldelem_R4: case OpCodeEnum.Ldelem_R8: case OpCodeEnum.Ldelem_Ref: case OpCodeEnum.Ldelem_U1: case OpCodeEnum.Ldelem_U2: case OpCodeEnum.Ldelem_U4: case OpCodeEnum.Ldind_I: case OpCodeEnum.Ldind_I1: case OpCodeEnum.Ldind_I2: case OpCodeEnum.Ldind_I4: case OpCodeEnum.Ldind_I8: case OpCodeEnum.Ldind_R4: case OpCodeEnum.Ldind_R8: case OpCodeEnum.Ldind_Ref: case OpCodeEnum.Ldind_U1: case OpCodeEnum.Ldind_U2: case OpCodeEnum.Ldind_U4: case OpCodeEnum.Ldlen: case OpCodeEnum.Ldloc_0: case OpCodeEnum.Ldloc_1: case OpCodeEnum.Ldloc_2: case OpCodeEnum.Ldloc_3: case OpCodeEnum.Ldnull: case OpCodeEnum.Localloc: case OpCodeEnum.Mul: case OpCodeEnum.Mul_Ovf: case OpCodeEnum.Mul_Ovf_Un: case OpCodeEnum.Neg: case OpCodeEnum.Nop: case OpCodeEnum.Not: case OpCodeEnum.Or: case OpCodeEnum.Pop: case OpCodeEnum.Prefix1: case OpCodeEnum.Prefix2: case OpCodeEnum.Prefix3: case OpCodeEnum.Prefix4: case OpCodeEnum.Prefix5: case OpCodeEnum.Prefix6: case OpCodeEnum.Prefix7: case OpCodeEnum.Prefixref: case OpCodeEnum.Readonly: case OpCodeEnum.Refanytype: case OpCodeEnum.Rem: case OpCodeEnum.Rem_Un: case OpCodeEnum.Ret: case OpCodeEnum.Rethrow: case OpCodeEnum.Shl: case OpCodeEnum.Shr: case OpCodeEnum.Shr_Un: case OpCodeEnum.Stelem_I: case OpCodeEnum.Stelem_I1: case OpCodeEnum.Stelem_I2: case OpCodeEnum.Stelem_I4: case OpCodeEnum.Stelem_I8: case OpCodeEnum.Stelem_R4: case OpCodeEnum.Stelem_R8: case OpCodeEnum.Stelem_Ref: case OpCodeEnum.Stind_I: case OpCodeEnum.Stind_I1: case OpCodeEnum.Stind_I2: case OpCodeEnum.Stind_I4: case OpCodeEnum.Stind_I8: case OpCodeEnum.Stind_R4: case OpCodeEnum.Stind_R8: case OpCodeEnum.Stind_Ref: case OpCodeEnum.Stloc_0: case OpCodeEnum.Stloc_1: case OpCodeEnum.Stloc_2: case OpCodeEnum.Stloc_3: case OpCodeEnum.Sub: case OpCodeEnum.Sub_Ovf: case OpCodeEnum.Sub_Ovf_Un: case OpCodeEnum.Switch: case OpCodeEnum.Tailcall: case OpCodeEnum.Throw: case OpCodeEnum.Volatile: case OpCodeEnum.Xor: return 0; case OpCodeEnum.Beq_S: case OpCodeEnum.Bge_S: case OpCodeEnum.Bge_Un_S: case OpCodeEnum.Bgt_S: case OpCodeEnum.Bgt_Un_S: case OpCodeEnum.Ble_S: case OpCodeEnum.Ble_Un_S: case OpCodeEnum.Blt_S: case OpCodeEnum.Blt_Un_S: case OpCodeEnum.Bne_Un_S: case OpCodeEnum.Br_S: case OpCodeEnum.Brfalse_S: case OpCodeEnum.Brtrue_S: case OpCodeEnum.Ldarg_S: case OpCodeEnum.Ldarga_S: case OpCodeEnum.Ldc_I4_S: case OpCodeEnum.Ldloc_S: case OpCodeEnum.Ldloca_S: case OpCodeEnum.Leave_S: case OpCodeEnum.Starg_S: case OpCodeEnum.Stloc_S: case OpCodeEnum.Unaligned: return 8; case OpCodeEnum.Ldarg: case OpCodeEnum.Ldarga: case OpCodeEnum.Ldloc: case OpCodeEnum.Ldloca: case OpCodeEnum.Starg: case OpCodeEnum.Stloc: return 16; case OpCodeEnum.Beq: case OpCodeEnum.Bge: case OpCodeEnum.Bge_Un: case OpCodeEnum.Bgt: case OpCodeEnum.Bgt_Un: case OpCodeEnum.Ble: case OpCodeEnum.Ble_Un: case OpCodeEnum.Blt: case OpCodeEnum.Blt_Un: case OpCodeEnum.Bne_Un: case OpCodeEnum.Box: case OpCodeEnum.Br: case OpCodeEnum.Brfalse: case OpCodeEnum.Brtrue: case OpCodeEnum.Call: case OpCodeEnum.Calli: case OpCodeEnum.Callvirt: case OpCodeEnum.Castclass: case OpCodeEnum.Constrained: case OpCodeEnum.Cpobj: case OpCodeEnum.Initobj: case OpCodeEnum.Isinst: case OpCodeEnum.Jmp: case OpCodeEnum.Ldc_I4: case OpCodeEnum.Ldc_R4: case OpCodeEnum.Ldelem: case OpCodeEnum.Ldelema: case OpCodeEnum.Ldfld: case OpCodeEnum.Ldflda: case OpCodeEnum.Ldftn: case OpCodeEnum.Ldobj: case OpCodeEnum.Ldsfld: case OpCodeEnum.Ldsflda: case OpCodeEnum.Ldstr: case OpCodeEnum.Ldtoken: case OpCodeEnum.Ldvirtftn: case OpCodeEnum.Leave: case OpCodeEnum.Mkrefany: case OpCodeEnum.Newarr: case OpCodeEnum.Newobj: case OpCodeEnum.Refanyval: case OpCodeEnum.Sizeof: case OpCodeEnum.Stelem: case OpCodeEnum.Stfld: case OpCodeEnum.Stobj: case OpCodeEnum.Stsfld: case OpCodeEnum.Unbox: case OpCodeEnum.Unbox_Any: return 32; case OpCodeEnum.Ldc_I8: case OpCodeEnum.Ldc_R8: return 64; default: throw new NotSupportedException("OpCode not supported: " + aOpCode.ToString()); } } private static OpCodeEnum GetNonShortcutOpCode(OpCodeEnum aOpCode) { switch (aOpCode) { case OpCodeEnum.Beq_S: return OpCodeEnum.Beq; case OpCodeEnum.Bge_S: return OpCodeEnum.Bge; case OpCodeEnum.Bge_Un_S: return OpCodeEnum.Bge_Un; case OpCodeEnum.Bgt_S: return OpCodeEnum.Bgt; case OpCodeEnum.Bgt_Un_S: return OpCodeEnum.Bgt_Un; case OpCodeEnum.Ble_S: return OpCodeEnum.Ble; case OpCodeEnum.Ble_Un_S: return OpCodeEnum.Ble_Un; case OpCodeEnum.Blt_S: return OpCodeEnum.Blt; case OpCodeEnum.Blt_Un_S: return OpCodeEnum.Blt_Un; case OpCodeEnum.Bne_Un_S: return OpCodeEnum.Bne_Un; case OpCodeEnum.Br_S: return OpCodeEnum.Br; case OpCodeEnum.Brfalse_S: return OpCodeEnum.Brfalse; case OpCodeEnum.Brtrue_S: return OpCodeEnum.Brtrue; case OpCodeEnum.Ldarg_0: return OpCodeEnum.Ldarg; case OpCodeEnum.Ldarg_1: return OpCodeEnum.Ldarg; case OpCodeEnum.Ldarg_2: return OpCodeEnum.Ldarg; case OpCodeEnum.Ldarg_3: return OpCodeEnum.Ldarg; case OpCodeEnum.Ldarg_S: return OpCodeEnum.Ldarg; case OpCodeEnum.Ldarga_S: return OpCodeEnum.Ldarga; case OpCodeEnum.Ldc_I4_0: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_1: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_2: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_3: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_4: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_5: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_6: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_7: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_8: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_M1: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldc_I4_S: return OpCodeEnum.Ldc_I4; case OpCodeEnum.Ldloc_0: return OpCodeEnum.Ldloc; case OpCodeEnum.Ldloc_1: return OpCodeEnum.Ldloc; case OpCodeEnum.Ldloc_2: return OpCodeEnum.Ldloc; case OpCodeEnum.Ldloc_3: return OpCodeEnum.Ldloc; case OpCodeEnum.Ldloc_S: return OpCodeEnum.Ldloc; case OpCodeEnum.Ldloca_S: return OpCodeEnum.Ldloca; case OpCodeEnum.Leave_S: return OpCodeEnum.Leave; case OpCodeEnum.Starg_S: return OpCodeEnum.Starg; case OpCodeEnum.Stloc_0: return OpCodeEnum.Stloc; case OpCodeEnum.Stloc_1: return OpCodeEnum.Stloc; case OpCodeEnum.Stloc_2: return OpCodeEnum.Stloc; case OpCodeEnum.Stloc_3: return OpCodeEnum.Stloc; case OpCodeEnum.Stloc_S: return OpCodeEnum.Stloc; default: return aOpCode; } } private static long? GetShortcutOperand(OpCodeEnum aOpCode) { switch (aOpCode) { case OpCodeEnum.Ldarg_0: return 0; case OpCodeEnum.Ldarg_1: return 1; case OpCodeEnum.Ldarg_2: return 2; case OpCodeEnum.Ldarg_3: return 3; case OpCodeEnum.Ldc_I4_0: return 0; case OpCodeEnum.Ldc_I4_1: return 1; case OpCodeEnum.Ldc_I4_2: return 2; case OpCodeEnum.Ldc_I4_3: return 3; case OpCodeEnum.Ldc_I4_4: return 4; case OpCodeEnum.Ldc_I4_5: return 5; case OpCodeEnum.Ldc_I4_6: return 6; case OpCodeEnum.Ldc_I4_7: return 7; case OpCodeEnum.Ldc_I4_8: return 8; case OpCodeEnum.Ldc_I4_M1: return -1; case OpCodeEnum.Ldloc_0: return 0; case OpCodeEnum.Ldloc_1: return 1; case OpCodeEnum.Ldloc_2: return 2; case OpCodeEnum.Ldloc_3: return 3; case OpCodeEnum.Stloc_0: return 0; case OpCodeEnum.Stloc_1: return 1; case OpCodeEnum.Stloc_2: return 2; case OpCodeEnum.Stloc_3: return 3; default: return null; } } } }