// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Emit { /// /// A CIL opcode. If the high byte is 0 or if it's , it's a 1-byte opcode, /// else it's a two-byte opcode and the highest byte is the first byte of the opcode. /// public enum Code : ushort { #pragma warning disable 1591 // disable XML doc warning UNKNOWN1 = 0x0100, UNKNOWN2 = 0x0101, Add = 0x0058, Add_Ovf = 0x00D6, Add_Ovf_Un = 0x00D7, And = 0x005F, Arglist = 0xFE00, Beq = 0x003B, Beq_S = 0x002E, Bge = 0x003C, Bge_S = 0x002F, Bge_Un = 0x0041, Bge_Un_S = 0x0034, Bgt = 0x003D, Bgt_S = 0x0030, Bgt_Un = 0x0042, Bgt_Un_S = 0x0035, Ble = 0x003E, Ble_S = 0x0031, Ble_Un = 0x0043, Ble_Un_S = 0x0036, Blt = 0x003F, Blt_S = 0x0032, Blt_Un = 0x0044, Blt_Un_S = 0x0037, Bne_Un = 0x0040, Bne_Un_S = 0x0033, Box = 0x008C, Br = 0x0038, Br_S = 0x002B, Break = 0x0001, Brfalse = 0x0039, Brfalse_S = 0x002C, Brtrue = 0x003A, Brtrue_S = 0x002D, Call = 0x0028, Calli = 0x0029, Callvirt = 0x006F, Castclass = 0x0074, Ceq = 0xFE01, Cgt = 0xFE02, Cgt_Un = 0xFE03, Ckfinite = 0x00C3, Clt = 0xFE04, Clt_Un = 0xFE05, Constrained = 0xFE16, Conv_I = 0x00D3, Conv_I1 = 0x0067, Conv_I2 = 0x0068, Conv_I4 = 0x0069, Conv_I8 = 0x006A, Conv_Ovf_I = 0x00D4, Conv_Ovf_I_Un = 0x008A, Conv_Ovf_I1 = 0x00B3, Conv_Ovf_I1_Un = 0x0082, Conv_Ovf_I2 = 0x00B5, Conv_Ovf_I2_Un = 0x0083, Conv_Ovf_I4 = 0x00B7, Conv_Ovf_I4_Un = 0x0084, Conv_Ovf_I8 = 0x00B9, Conv_Ovf_I8_Un = 0x0085, Conv_Ovf_U = 0x00D5, Conv_Ovf_U_Un = 0x008B, Conv_Ovf_U1 = 0x00B4, Conv_Ovf_U1_Un = 0x0086, Conv_Ovf_U2 = 0x00B6, Conv_Ovf_U2_Un = 0x0087, Conv_Ovf_U4 = 0x00B8, Conv_Ovf_U4_Un = 0x0088, Conv_Ovf_U8 = 0x00BA, Conv_Ovf_U8_Un = 0x0089, Conv_R_Un = 0x0076, Conv_R4 = 0x006B, Conv_R8 = 0x006C, Conv_U = 0x00E0, Conv_U1 = 0x00D2, Conv_U2 = 0x00D1, Conv_U4 = 0x006D, Conv_U8 = 0x006E, Cpblk = 0xFE17, Cpobj = 0x0070, Div = 0x005B, Div_Un = 0x005C, Dup = 0x0025, Endfilter = 0xFE11, Endfinally = 0x00DC, Initblk = 0xFE18, Initobj = 0xFE15, Isinst = 0x0075, Jmp = 0x0027, Ldarg = 0xFE09, Ldarg_0 = 0x0002, Ldarg_1 = 0x0003, Ldarg_2 = 0x0004, Ldarg_3 = 0x0005, Ldarg_S = 0x000E, Ldarga = 0xFE0A, Ldarga_S = 0x000F, Ldc_I4 = 0x0020, Ldc_I4_0 = 0x0016, Ldc_I4_1 = 0x0017, Ldc_I4_2 = 0x0018, Ldc_I4_3 = 0x0019, Ldc_I4_4 = 0x001A, Ldc_I4_5 = 0x001B, Ldc_I4_6 = 0x001C, Ldc_I4_7 = 0x001D, Ldc_I4_8 = 0x001E, Ldc_I4_M1 = 0x0015, Ldc_I4_S = 0x001F, Ldc_I8 = 0x0021, Ldc_R4 = 0x0022, Ldc_R8 = 0x0023, Ldelem = 0x00A3, Ldelem_I = 0x0097, Ldelem_I1 = 0x0090, Ldelem_I2 = 0x0092, Ldelem_I4 = 0x0094, Ldelem_I8 = 0x0096, Ldelem_R4 = 0x0098, Ldelem_R8 = 0x0099, Ldelem_Ref = 0x009A, Ldelem_U1 = 0x0091, Ldelem_U2 = 0x0093, Ldelem_U4 = 0x0095, Ldelema = 0x008F, Ldfld = 0x007B, Ldflda = 0x007C, Ldftn = 0xFE06, Ldind_I = 0x004D, Ldind_I1 = 0x0046, Ldind_I2 = 0x0048, Ldind_I4 = 0x004A, Ldind_I8 = 0x004C, Ldind_R4 = 0x004E, Ldind_R8 = 0x004F, Ldind_Ref = 0x0050, Ldind_U1 = 0x0047, Ldind_U2 = 0x0049, Ldind_U4 = 0x004B, Ldlen = 0x008E, Ldloc = 0xFE0C, Ldloc_0 = 0x0006, Ldloc_1 = 0x0007, Ldloc_2 = 0x0008, Ldloc_3 = 0x0009, Ldloc_S = 0x0011, Ldloca = 0xFE0D, Ldloca_S = 0x0012, Ldnull = 0x0014, Ldobj = 0x0071, Ldsfld = 0x007E, Ldsflda = 0x007F, Ldstr = 0x0072, Ldtoken = 0x00D0, Ldvirtftn = 0xFE07, Leave = 0x00DD, Leave_S = 0x00DE, Localloc = 0xFE0F, Mkrefany = 0x00C6, Mul = 0x005A, Mul_Ovf = 0x00D8, Mul_Ovf_Un = 0x00D9, Neg = 0x0065, Newarr = 0x008D, Newobj = 0x0073, No = 0xFE19, Nop = 0x0000, Not = 0x0066, Or = 0x0060, Pop = 0x0026, Prefix1 = 0x00FE, Prefix2 = 0x00FD, Prefix3 = 0x00FC, Prefix4 = 0x00FB, Prefix5 = 0x00FA, Prefix6 = 0x00F9, Prefix7 = 0x00F8, Prefixref = 0x00FF, Readonly = 0xFE1E, Refanytype = 0xFE1D, Refanyval = 0x00C2, Rem = 0x005D, Rem_Un = 0x005E, Ret = 0x002A, Rethrow = 0xFE1A, Shl = 0x0062, Shr = 0x0063, Shr_Un = 0x0064, Sizeof = 0xFE1C, Starg = 0xFE0B, Starg_S = 0x0010, Stelem = 0x00A4, Stelem_I = 0x009B, Stelem_I1 = 0x009C, Stelem_I2 = 0x009D, Stelem_I4 = 0x009E, Stelem_I8 = 0x009F, Stelem_R4 = 0x00A0, Stelem_R8 = 0x00A1, Stelem_Ref = 0x00A2, Stfld = 0x007D, Stind_I = 0x00DF, Stind_I1 = 0x0052, Stind_I2 = 0x0053, Stind_I4 = 0x0054, Stind_I8 = 0x0055, Stind_R4 = 0x0056, Stind_R8 = 0x0057, Stind_Ref = 0x0051, Stloc = 0xFE0E, Stloc_0 = 0x000A, Stloc_1 = 0x000B, Stloc_2 = 0x000C, Stloc_3 = 0x000D, Stloc_S = 0x0013, Stobj = 0x0081, Stsfld = 0x0080, Sub = 0x0059, Sub_Ovf = 0x00DA, Sub_Ovf_Un = 0x00DB, Switch = 0x0045, Tailcall = 0xFE14, Throw = 0x007A, Unaligned = 0xFE12, Unbox = 0x0079, Unbox_Any = 0x00A5, Volatile = 0xFE13, Xor = 0x0061, #pragma warning restore } public static partial class Extensions { /// /// Determines whether a is experimental /// /// The code /// true if the is experimental; otherwise, false public static bool IsExperimental(this Code code) { byte hi = (byte)((ushort)code >> 8); return hi >= 0xF0 && hi <= 0xFB; } /// /// Converts a to an /// /// The code /// A or null if it's invalid public static OpCode ToOpCode(this Code code) { byte hi = (byte)((ushort)code >> 8); byte lo = (byte)code; if (hi == 0) return OpCodes.OneByteOpCodes[lo]; if (hi == 0xFE) return OpCodes.TwoByteOpCodes[lo]; if (code == Code.UNKNOWN1) return OpCodes.UNKNOWN1; if (code == Code.UNKNOWN2) return OpCodes.UNKNOWN2; return null; } /// /// Converts a to an , using a module context to look /// up potential experimental opcodes /// /// The code /// The module context /// A or null if it's invalid public static OpCode ToOpCode(this Code code, ModuleContext context) { byte hi = (byte)((ushort)code >> 8); byte lo = (byte)code; if (hi == 0) return OpCodes.OneByteOpCodes[lo]; if (hi == 0xFE) return OpCodes.TwoByteOpCodes[lo]; if (context.GetExperimentalOpCode(hi, lo) is OpCode op) return op; if (code == Code.UNKNOWN1) return OpCodes.UNKNOWN1; if (code == Code.UNKNOWN2) return OpCodes.UNKNOWN2; return null; } } }