Exemplo n.º 1
0
        public static ILInstruction Create(ILOpCodeValues ilOpCodeValue, object arg)
        {
            RequireOperand(unchecked ((short)ilOpCodeValue));
            var opCode = OpCodeLookup.GetILOpcode((int)ilOpCodeValue);
            var result = new ILInstruction {
                OpCode = opCode, Arg = arg
            };

            return(result);
        }
Exemplo n.º 2
0
        public static List <ILInstruction> FromByteCode(byte[] byteCode)
        {
            var result = new List <ILInstruction>();

            //TODO: Unit test for emtpy method bodies. For now just return a NOP|RET.
            if (byteCode == null || byteCode.Length == 0)
            {
                result = (new[] { ILInstruction.NoOp, ILInstruction.Ret }).ToList();
                return(result);
            }
            var  ms  = new MemoryStream(byteCode);
            var  br  = new BinaryReader(ms);
            long idx = 0;

            while (ms.Position < ms.Length)
            {
                idx = ms.Position;
                byte first = br.ReadByte(); //todo; opcodes are short, need to determine  0xfe00 && idx <= 0xfe1e

                var code = OpCodeLookup.GetILOpcode(first);
                if (code == OpCodes.Prefix1)
                {
                    var second = br.ReadByte();

                    var shortVal = (short)((((ushort)first) << 8) + (second));// const sthort
                    code = OpCodeLookup.GetILOpcode(shortVal);
                }
                var instruction = new ILInstruction {
                    OpCode = code, ByteIndex = idx
                };
                switch (code.OperandType)
                {
                //     The operand is a 32-bit integer branch target.
                case OperandType.InlineBrTarget:     // = 0,
                    instruction.Arg = br.ReadInt32();
                    break;

                //     The operand is a 32-bit metadata token.
                case OperandType.InlineField:     // = 1,
                    instruction.Arg = br.ReadInt32();
                    break;

                //     The operand is a 32-bit integer.
                case OperandType.InlineI:     // = 2,
                    instruction.Arg = br.ReadInt32();
                    break;

                //     The operand is a 64-bit integer.
                case OperandType.InlineI8:     // = 3,
                    instruction.Arg = br.ReadInt64();
                    break;

                //     The operand is a 32-bit metadata token.
                case OperandType.InlineMethod:     // = 4,
                    instruction.Arg = br.ReadInt32();
                    break;

                //     No operand.
                case OperandType.InlineNone:     // = 5,
                    break;

                    //     The operand is reserved and should not be used.
#pragma warning disable CS0618              // Type or member is obsolete
                case OperandType.InlinePhi: // = 6,
#pragma warning restore CS0618              // Type or member is obsolete
                    throw new NotImplementedException();

                //     The operand is a 64-bit IEEE floating point number.
                case OperandType.InlineR:     // = 7,
                    instruction.Arg = br.ReadDouble();
                    break;

                //     The operand is a 32-bit metadata signature token.
                case OperandType.InlineSig:     // = 9,
                    instruction.Arg = br.ReadInt32();
                    break;

                //     The operand is a 32-bit metadata string token.
                case OperandType.InlineString:     // = 10,
                    instruction.Arg = br.ReadInt32();
                    //throw new NotImplementedException();
                    break;

                //     The operand is the 32-bit integer argument to a switch instruction.
                case OperandType.InlineSwitch:     // = 11,
                    instruction.Arg = br.ReadInt32();
                    var switchLength     = (int)instruction.Arg;
                    var switchByteLength = switchLength * 4;
                    var jmps             = new List <int>();
                    var target           = br.BaseStream.Position + switchByteLength;
                    while (ms.Position < target)
                    {
                        jmps.Add(br.ReadInt32());
                    }
                    instruction.Arg = jmps.ToArray();

                    break;

                //     The operand is a FieldRef, MethodRef, or TypeRef token.
                case OperandType.InlineTok:     // = 12,
                    instruction.Arg = br.ReadInt32();
                    //throw new NotImplementedException();
                    break;

                //     The operand is a 32-bit metadata token.
                case OperandType.InlineType:     // = 13,
                    instruction.Arg = br.ReadInt32();
                    break;

                //     The operand is 16-bit integer containing the ordinal of a local variable or an
                //     argument.
                case OperandType.InlineVar:     // = 14,
                    instruction.Arg = br.ReadInt16();
                    break;

                //     The operand is an 8-bit integer branch target.
                case OperandType.ShortInlineBrTarget:     // = 15,
                    instruction.Arg = br.ReadByte();
                    break;

                //     The operand is an 8-bit integer.
                case OperandType.ShortInlineI:     // = 16,
                    instruction.Arg = br.ReadByte();
                    break;

                //     The operand is a 32-bit IEEE floating point number.
                case OperandType.ShortInlineR:     // = 17,
                    instruction.Arg = br.ReadSingle();
                    break;

                //     The operand is an 8-bit integer containing the ordinal of a local variable or
                //     an argumenta.
                case OperandType.ShortInlineVar:     // = 18
                    instruction.Arg = br.ReadByte();
                    break;

                default: break;
                }

                result.Add(instruction);
            }
            //TODO: Add Labels to Instructions;
            //result[0].SetLabel();
            return(result);
        }
        public object ExecuteTyped(Stream stream, IILInstructionResolver resolver = null, object[] args = null, ILVariable[] locals = null)
        {
            var        stack  = new Stack <object>();
            var        br     = new BinaryReader(stream);
            int        op     = 0;
            int        i      = 0;
            MethodBase method = null;
            Type       type;
            object     obj = null;

            object[] arr = null;
Read:
            op = stream.ReadByte();

            //Execute:
            // can we keep tables at 255 to implement br_S. else jumps will be BR and use 4 bytes.
            // to implement need two switches to keep table at 127 entries
            switch (op)
            {
            case 0: goto Nop;              // 0x00

            case 1: goto Break;            // 0x01

            case 2: goto Ldarg_0;          // 0x02

            case 3: goto Ldarg_1;          // 0x03

            case 4: goto Ldarg_2;          // 0x04

            case 5: goto Ldarg_3;          // 0x05

            case 6: goto Ldloc_0;          // 0x06

            case 7: goto Ldloc_1;          // 0x07

            case 8: goto Ldloc_2;          // 0x08

            case 9: goto Ldloc_3;          // 0x09

            case 10: goto Stloc_0;         // 0x0a

            case 11: goto Stloc_1;         // 0x0b

            case 12: goto Stloc_2;         // 0x0c

            case 13: goto Stloc_3;         // 0x0d

            case 14: goto Ldarg_S;         // 0x0e

            case 15: goto Ldarga_S;        // 0x0f

            case 16: goto Starg_S;         // 0x10

            case 17: goto Ldloc_S;         // 0x11

            case 18: goto Ldloca_S;        // 0x12

            case 19: goto Stloc_S;         // 0x13

            case 20: goto Ldnull;          // 0x14

            case 21: goto Ldc_I4_M1;       // 0x15

            case 22: goto Ldc_I4_0;        // 0x16

            case 23: goto Ldc_I4_1;        // 0x17

            case 24: goto Ldc_I4_2;        // 0x18

            case 25: goto Ldc_I4_3;        // 0x19

            case 26: goto Ldc_I4_4;        // 0x1a

            case 27: goto Ldc_I4_5;        // 0x1b

            case 28: goto Ldc_I4_6;        // 0x1c

            case 29: goto Ldc_I4_7;        // 0x1d

            case 30: goto Ldc_I4_8;        // 0x1e

            case 31: goto Ldc_I4_S;        // 0x1f

            case 32: goto Ldc_I4;          // 0x20

            case 33: goto Ldc_I8;          // 0x21

            case 34: goto Ldc_R4;          // 0x22

            case 35: goto Ldc_R8;          // 0x23

            case 36: goto Exec_MSIL_I;     // 0x24

            case 37: goto Dup;             // 0x25

            case 38: goto Pop;             // 0x26

            case 39: goto Jmp;             // 0x27

            case 40: goto Call;            // 0x28

            case 41: goto Calli;           // 0x29

            case 42: goto Ret;             // 0x2a

            case 43: goto Br_S;            // 0x2b

            case 44: goto Brfalse_S;       // 0x2c

            case 45: goto Brtrue_S;        // 0x2d

            case 46: goto Beq_S;           // 0x2e

            case 47: goto Bge_S;           // 0x2f

            case 48: goto Bgt_S;           // 0x30

            case 49: goto Ble_S;           // 0x31

            case 50: goto Blt_S;           // 0x32

            case 51: goto Bne_Un_S;        // 0x33

            case 52: goto Bge_Un_S;        // 0x34

            case 53: goto Bgt_Un_S;        // 0x35

            case 54: goto Ble_Un_S;        // 0x36

            case 55: goto Blt_Un_S;        // 0x37

            case 56: goto Br;              // 0x38

            case 57: goto Brfalse;         // 0x39

            case 58: goto Brtrue;          // 0x3a

            case 59: goto Beq;             // 0x3b

            case 60: goto Bge;             // 0x3c

            case 61: goto Bgt;             // 0x3d

            case 62: goto Ble;             // 0x3e

            case 63: goto Blt;             // 0x3f

            case 64: goto Bne_Un;          // 0x40

            case 65: goto Bge_Un;          // 0x41

            case 66: goto Bgt_Un;          // 0x42

            case 67: goto Ble_Un;          // 0x43

            case 68: goto Blt_Un;          // 0x44

            case 69: goto Switch;          // 0x45

            case 70: goto Ldind_I1;        // 0x46

            case 71: goto Ldind_U1;        // 0x47

            case 72: goto Ldind_I2;        // 0x48

            case 73: goto Ldind_U2;        // 0x49

            case 74: goto Ldind_I4;        // 0x4a

            case 75: goto Ldind_U4;        // 0x4b

            case 76: goto Ldind_I8;        // 0x4c

            case 77: goto Ldind_I;         // 0x4d

            case 78: goto Ldind_R4;        // 0x4e

            case 79: goto Ldind_R8;        // 0x4f

            case 80: goto Ldind_Ref;       // 0x50

            case 81: goto Stind_Ref;       // 0x51

            case 82: goto Stind_I1;        // 0x52

            case 83: goto Stind_I2;        // 0x53

            case 84: goto Stind_I4;        // 0x54

            case 85: goto Stind_I8;        // 0x55

            case 86: goto Stind_R4;        // 0x56

            case 87: goto Stind_R8;        // 0x57

            case 88: goto Add;             // 0x58

            case 89: goto Sub;             // 0x59

            case 90: goto Mul;             // 0x5a

            case 91: goto Div;             // 0x5b

            case 92: goto Div_Un;          // 0x5c

            case 93: goto Rem;             // 0x5d

            case 94: goto Rem_Un;          // 0x5e

            case 95: goto And;             // 0x5f

            case 96: goto Or;              // 0x60

            case 97: goto Xor;             // 0x61

            case 98: goto Shl;             // 0x62

            case 99: goto Shr;             // 0x63

            case 100: goto Shr_Un;         // 0x64

            case 101: goto Neg;            // 0x65

            case 102: goto Not;            // 0x66

            case 103: goto Conv_I1;        // 0x67

            case 104: goto Conv_I2;        // 0x68

            case 105: goto Conv_I4;        // 0x69

            case 106: goto Conv_I8;        // 0x6a

            case 107: goto Conv_R4;        // 0x6b

            case 108: goto Conv_R8;        // 0x6c

            case 109: goto Conv_U4;        // 0x6d

            case 110: goto Conv_U8;        // 0x6e

            case 111: goto Callvirt;       // 0x6f

            case 112: goto Cpobj;          // 0x70

            case 113: goto Ldobj;          // 0x71

            case 114: goto Ldstr;          // 0x72

            case 115: goto Newobj;         // 0x73

            case 116: goto Castclass;      // 0x74

            case 117: goto Isinst;         // 0x75

            case 118: goto Conv_R_Un;      // 0x76

            case 119: goto Exec_MSIL_S;    // 0x77

            case 120: goto NotSupported_S; //0x78

            case 121: goto Unbox;          // 0x79

            case 122: goto Throw;          // 0x7a

            case 123: goto Ldfld;          // 0x7b

            case 124: goto Ldflda;         // 0x7c

            case 125: goto Stfld;          // 0x7d

            case 126: goto Ldsfld;         // 0x7e

            case 127: goto Ldsflda;        // 0x7f

            case 128: goto Stsfld;         // 0x80

            case 129: goto Stobj;          // 0x81

            case 130: goto Conv_Ovf_I1_Un; // 0x82

            case 131: goto Conv_Ovf_I2_Un; // 0x83

            case 132: goto Conv_Ovf_I4_Un; // 0x84

            case 133: goto Conv_Ovf_I8_Un; // 0x85

            case 134: goto Conv_Ovf_U1_Un; // 0x86

            case 135: goto Conv_Ovf_U2_Un; // 0x87

            case 136: goto Conv_Ovf_U4_Un; // 0x88

            case 137: goto Conv_Ovf_U8_Un; // 0x89

            case 138: goto Conv_Ovf_I_Un;  // 0x8a

            case 139: goto Conv_Ovf_U_Un;  // 0x8b

            case 140: goto Box;            // 0x8c

            case 141: goto Newarr;         // 0x8d

            case 142: goto Ldlen;          // 0x8e

            case 143: goto Ldelema;        // 0x8f

            case 144: goto Ldelem_I1;      // 0x90

            case 145: goto Ldelem_U1;      // 0x91

            case 146: goto Ldelem_I2;      // 0x92

            case 147: goto Ldelem_U2;      // 0x93

            case 148: goto Ldelem_I4;      // 0x94

            case 149: goto Ldelem_U4;      // 0x95

            case 150: goto Ldelem_I8;      // 0x96

            case 151: goto Ldelem_I;       // 0x97

            case 152: goto Ldelem_R4;      // 0x98

            case 153: goto Ldelem_R8;      // 0x99

            case 154: goto Ldelem_Ref;     // 0x9a

            case 155: goto Stelem_I;       // 0x9b

            case 156: goto Stelem_I1;      // 0x9c

            case 157: goto Stelem_I2;      // 0x9d

            case 158: goto Stelem_I4;      // 0x9e

            case 159: goto Stelem_I8;      // 0x9f

            case 160: goto Stelem_R4;      // 0xa0

            case 161: goto Stelem_R8;      // 0xa1

            case 162: goto Stelem_Ref;     // 0xa2

            case 163: goto Ldelem;         // 0xa3

            case 164: goto Stelem;         // 0xa4

            case 165: goto Unbox_Any;      // 0xa5

            case 166: goto NotSupported_S; //0xA6

            case 167: goto NotSupported_S; //0xA7

            case 168: goto NotSupported_S; //0xA8

            case 169: goto NotSupported_S; //0xA9

            case 170: goto NotSupported_S; //0xAA

            case 171: goto NotSupported_S; //0xAB

            case 172: goto NotSupported_S; //0xAC

            case 173: goto NotSupported_S; //0xAD

            case 174: goto NotSupported_S; //0xAE

            case 175: goto NotSupported_S; //0xAF

            case 176: goto NotSupported_S; //0xB0

            case 177: goto NotSupported_S; //0xB1

            case 178: goto NotSupported_S; //0xB2

            case 179: goto Conv_Ovf_I1;    // 0xb3

            case 180: goto Conv_Ovf_U1;    // 0xb4

            case 181: goto Conv_Ovf_I2;    // 0xb5

            case 182: goto Conv_Ovf_U2;    // 0xb6

            case 183: goto Conv_Ovf_I4;    // 0xb7

            case 184: goto Conv_Ovf_U4;    // 0xb8

            case 185: goto Conv_Ovf_I8;    // 0xb9

            case 186: goto Conv_Ovf_U8;    // 0xba

            case 187: goto NotSupported_S; //0xBB

            case 188: goto NotSupported_S; //0xBC

            case 189: goto NotSupported_S; //0xBD

            case 190: goto NotSupported_S; //0xBE

            case 191: goto NotSupported_S; //0xBF

            case 192: goto NotSupported_S; //0xC0

            case 193: goto NotSupported_S; //0xC1

            case 194: goto Refanyval;      // 0xc2

            case 195: goto Ckfinite;       // 0xc3

            case 196: goto NotSupported_S; //0xC4

            case 197: goto NotSupported_S; //0xC5

            case 198: goto Mkrefany;       // 0xc6

            case 199: goto NotSupported_S; //0xC7

            case 200: goto NotSupported_S; //0xC8

            case 201: goto NotSupported_S; //0xC9

            case 202: goto NotSupported_S; //0xCA

            case 203: goto NotSupported_S; //0xCB

            case 204: goto NotSupported_S; //0xCC

            case 205: goto NotSupported_S; //0xCD

            case 206: goto NotSupported_S; //0xCE

            case 207: goto NotSupported_S; //0xCF

            case 208: goto Ldtoken;        // 0xd0

            case 209: goto Conv_U2;        // 0xd1

            case 210: goto Conv_U1;        // 0xd2

            case 211: goto Conv_I;         // 0xd3

            case 212: goto Conv_Ovf_I;     // 0xd4

            case 213: goto Conv_Ovf_U;     // 0xd5

            case 214: goto Add_Ovf;        // 0xd6

            case 215: goto Add_Ovf_Un;     // 0xd7

            case 216: goto Mul_Ovf;        // 0xd8

            case 217: goto Mul_Ovf_Un;     // 0xd9

            case 218: goto Sub_Ovf;        // 0xda

            case 219: goto Sub_Ovf_Un;     // 0xdb

            case 220: goto Endfinally;     // 0xdc

            case 221: goto Leave;          // 0xdd

            case 222: goto Leave_S;        // 0xde

            case 223: goto Stind_I;        // 0xdf

            case 224: goto Conv_U;         // 0xe0

            case 225: goto NotSupported_S; //0xE1

            case 226: goto NotSupported_S; //0xE2

            case 227: goto NotSupported_S; //0xE3

            case 228: goto NotSupported_S; //0xE4

            case 229: goto NotSupported_S; //0xE5

            case 230: goto NotSupported_S; //0xE6

            case 231: goto NotSupported_S; //0xE7

            case 232: goto NotSupported_S; //0xE8

            case 233: goto NotSupported_S; //0xE9

            case 234: goto NotSupported_S; //0xEA

            case 235: goto NotSupported_S; //0xEB

            case 236: goto NotSupported_S; //0xEC

            case 237: goto NotSupported_S; //0xED

            case 238: goto NotSupported_S; //0xEE

            case 239: goto NotSupported_S; //0xEF

            case 240: goto NotSupported_S; //0xF0

            case 241: goto NotSupported_S; //0xF1

            case 242: goto NotSupported_S; //0xF2

            case 243: goto NotSupported_S; //0xF3

            case 244: goto NotSupported_S; //0xF4

            case 245: goto NotSupported_S; //0xF5

            case 246: goto NotSupported_S; //0xF6

            case 247: goto NotSupported_S; //0xF7

            case 248: goto Prefix7;        // 0xf8

            case 249: goto Prefix6;        // 0xf9

            case 250: goto Prefix5;        // 0xfa

            case 251: goto Prefix4;        // 0xfb

            case 252: goto Prefix3;        // 0xfc

            case 253: goto Prefix2;        // 0xfd

            case 254: goto Prefix1;        // 0xfe

            case 255: goto Prefixref;      // 0xff

            default: throw new NotImplementedException();
            }

            NotSupported_S   : goto NotSupported;
            NotImplemented_S : goto NotImplemented;

            Nop         : goto Read;
            Break       : System.Diagnostics.Debugger.Break(); goto Read;
            Ldarg_0     : stack.Push(args[0]); goto Read;
            Ldarg_1     : stack.Push(args[1]); goto Read;
            Ldarg_2     : stack.Push(args[2]); goto Read;
            Ldarg_3     : stack.Push(args[3]); goto Read;
            Ldloc_0     : stack.Push(locals[0].Value); goto Read;
            Ldloc_1     : stack.Push(locals[1].Value); goto Read;
            Ldloc_2     : stack.Push(locals[2].Value); goto Read;
            Ldloc_3     : stack.Push(locals[3].Value); goto Read;
            Stloc_0     : locals[0].Value = stack.Pop(); goto Read;
            Stloc_1     : locals[2].Value = stack.Pop(); goto Read;
            Stloc_2     : locals[3].Value = stack.Pop(); goto Read;
            Stloc_3     : locals[4].Value = stack.Pop(); goto Read;
            Ldarg_S     : stack.Push(args[stream.ReadByte()]); goto Read;
            Ldarga_S    : stack.Push(args[stream.ReadByte()]); goto Read;
            Starg_S     : args[stream.ReadByte()] = stack.Pop(); goto Read;
            Ldloc_S     : stack.Push(locals[stream.ReadByte()].Value); goto Read;
            Ldloca_S    : stack.Push(locals[stream.ReadByte()].Value); goto Read;
            Stloc_S     : locals[stream.ReadByte()].Value = stack.Pop(); goto Read;
            Ldnull      : stack.Push(null); goto Read;
            Ldc_I4_M1   : stack.Push(-1); goto Read;
            Ldc_I4_0    : stack.Push(0); goto Read;
            Ldc_I4_1    : stack.Push(1); goto Read;
            Ldc_I4_2    : stack.Push(2); goto Read;
            Ldc_I4_3    : stack.Push(3); goto Read;
            Ldc_I4_4    : stack.Push(4); goto Read;
            Ldc_I4_5    : stack.Push(5); goto Read;
            Ldc_I4_6    : stack.Push(6); goto Read;
            Ldc_I4_7    : stack.Push(7); goto Read;
            Ldc_I4_8    : stack.Push(8); goto Read;
            Ldc_I4_S    : stack.Push(stream.ReadByte()); goto Read;
            Ldc_I4      : stack.Push(br.ReadInt32()); goto Read;
            Ldc_I8      : stack.Push(br.ReadInt64()); goto Read;
            Ldc_R4      : stack.Push(br.ReadSingle()); goto Read;
            Ldc_R8      : stack.Push(br.ReadDouble()); goto Read;
            Exec_MSIL_I : goto NotSupported_S;
            Dup         : stack.Push(stack.Peek()); goto Read;
            Pop         : stack.Pop(); goto Read;
            Jmp         : goto NotImplemented_S;
Call:
            method = resolver.ResolveMethodToken(br.ReadInt32());
            arr    = new object[method.GetParameters().Length];
            for (i = arr.Length - 1; i >= 0; i--)
            {
                arr[i] = stack.Pop();
            }
            var methodResult = method.Invoke(method.IsStatic ? null : stack.Pop(), arr);

            if (((MethodInfo)method).ReturnType != typeof(void))
            {
                stack.Push(methodResult);
            }
            goto Read;
            Calli : goto Call;
            Ret   : goto RetResult;
            //Br_S: stream.Position += br.ReadByte(); goto Read;
            //Brfalse_S: //jmp = stream.ReadByte(); if ((int)stack.Pop() == 0) stream.Position += jmp; goto Read;
            //Brtrue_S: jmp = stream.ReadByte(); if ((int)stack.Pop() == 1) stream.Position += jmp; goto Read;
            //Beq_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() == (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bge_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() <= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bgt_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() < (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Ble_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() >= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Blt_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() > (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bne_Un_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() != (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bge_Un_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() <= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bgt_Un_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() < (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Ble_Un_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() >= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Blt_Un_S: jmp = stream.ReadByte(); if ((dynamic)stack.Pop() > (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Br: stream.Position += br.ReadInt32(); goto Execute;
            //Brfalse: jmp = br.ReadInt32(); if ((int)stack.Pop() == 0) stream.Position += jmp; goto Read;
            //Brtrue: jmp = br.ReadInt32(); if ((int)stack.Pop() == 1) stream.Position += jmp; goto Read;
            //Beq: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() == (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bge: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() <= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bgt: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() < (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Ble: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() >= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Blt: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() > (dynamic)stack.Pop()) stream.Position += jmp; goto Read; ;
            //Bne_Un: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() != (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bge_Un: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() <= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Bgt_Un: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() < (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Ble_Un: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() >= (dynamic)stack.Pop()) stream.Position += jmp; goto Read;
            //Blt_Un: jmp = br.ReadInt32(); if ((dynamic)stack.Pop() > (dynamic)stack.Pop()) stream.Position += jmp; goto Read;

            Br_S      : stream.Seek(br.ReadByte(), SeekOrigin.Current); goto Read;
            Brfalse_S : stream.Seek((int)stack.Pop() == 0 ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;//jmp = stream.ReadByte(); if ((int)stack.Pop() == 0) stream.Position += jmp; goto Read;
            Brtrue_S  : stream.Seek((int)stack.Pop() == 1 ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Beq_S     : stream.Seek((dynamic)stack.Pop() == (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Bge_S     : stream.Seek((dynamic)stack.Pop() <= (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Bgt_S     : stream.Seek((dynamic)stack.Pop() < (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Ble_S     : stream.Seek((dynamic)stack.Pop() >= (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Blt_S     : stream.Seek((dynamic)stack.Pop() > (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Bne_Un_S  : stream.Seek((dynamic)stack.Pop() != (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Bge_Un_S  : stream.Seek((dynamic)stack.Pop() <= (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Bgt_Un_S  : stream.Seek((dynamic)stack.Pop() < (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Ble_Un_S  : stream.Seek((dynamic)stack.Pop() >= (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Blt_Un_S  : stream.Seek((dynamic)stack.Pop() > (dynamic)stack.Pop() ? br.ReadByte() : 1, SeekOrigin.Current); goto Read;
            Br        : stream.Seek(br.ReadInt32(), SeekOrigin.Current); goto Read;
            Brfalse   : stream.Seek((int)stack.Pop() == 0 ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Brtrue    : stream.Seek((int)stack.Pop() == 1 ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Beq       : stream.Seek((dynamic)stack.Pop() == (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Bge       : stream.Seek((dynamic)stack.Pop() <= (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Bgt       : stream.Seek((dynamic)stack.Pop() < (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Ble       : stream.Seek((dynamic)stack.Pop() >= (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Blt       : stream.Seek((dynamic)stack.Pop() > (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Bne_Un    : stream.Seek((dynamic)stack.Pop() != (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Bge_Un    : stream.Seek((dynamic)stack.Pop() <= (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Bgt_Un    : stream.Seek((dynamic)stack.Pop() < (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Ble_Un    : stream.Seek((dynamic)stack.Pop() >= (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;
            Blt_Un    : stream.Seek((dynamic)stack.Pop() > (dynamic)stack.Pop() ? br.ReadInt32() : 4, SeekOrigin.Current); goto Read;

            Switch    : goto NotImplemented_S; //TODO: implementation requrires full scan of msil instructions, jmp table, etc.
            Ldind_I1  : goto NotImplemented_S;
            Ldind_U1  : goto NotImplemented_S;
            Ldind_I2  : goto NotImplemented_S;
            Ldind_U2  : goto NotImplemented_S;
            Ldind_I4  : goto NotImplemented_S;
            Ldind_U4  : goto NotImplemented_S;
            Ldind_I8  : goto NotImplemented_S;
            Ldind_I   : goto NotImplemented_S;
            Ldind_R4  : goto NotImplemented_S;
            Ldind_R8  : goto NotImplemented_S;
            Ldind_Ref : goto NotImplemented_S;
            Stind_Ref : goto NotImplemented_S;
            Stind_I1  : goto NotImplemented_S;
            Stind_I2  : goto NotImplemented_S;
            Stind_I4  : goto NotImplemented_S;
            Stind_I8  : goto NotImplemented_S;
            Stind_R4  : goto NotImplemented_S;
            Stind_R8  : goto NotImplemented_S;
            Add       : stack.Push((dynamic)stack.Pop() + (dynamic)stack.Pop()); goto Read;
            Sub       : stack.Push((dynamic)stack.Pop() - (dynamic)stack.Pop()); goto Read;
            Mul       : stack.Push((dynamic)stack.Pop() * (dynamic)stack.Pop()); goto Read;
            Div       : stack.Push((dynamic)stack.Pop() / (dynamic)stack.Pop()); goto Read;
            Div_Un    : stack.Push((dynamic)stack.Pop() / (dynamic)stack.Pop()); goto Read;
            Rem       : stack.Push((dynamic)stack.Pop() % (dynamic)stack.Pop()); goto Read;
            Rem_Un    : stack.Push((dynamic)stack.Pop() % (dynamic)stack.Pop()); goto Read;
            And       : stack.Push((dynamic)stack.Pop() & (dynamic)stack.Pop()); goto Read;
            Or        : stack.Push((dynamic)stack.Pop() | (dynamic)stack.Pop()); goto Read;
            Xor       : stack.Push((dynamic)stack.Pop() ^ (dynamic)stack.Pop()); goto Read;
            Shl       : stack.Push((dynamic)stack.Pop() << br.ReadInt32()); goto Read;
            Shr       : stack.Push((dynamic)stack.Pop() >> br.ReadInt32()); goto Read;
            Shr_Un    : stack.Push((dynamic)stack.Pop() >> br.ReadInt32()); goto Read;
            Neg       : stack.Push(-(dynamic)stack.Pop()); goto Read;
            Not       : stack.Push(!(dynamic)stack.Pop()); goto Read;
            Conv_I1   : stack.Push(Convert.ToSByte(stack.Pop())); goto Read;
            Conv_I2   : stack.Push(Convert.ToInt16(stack.Pop())); goto Read;
            Conv_I4   : stack.Push(Convert.ToInt32(stack.Pop())); goto Read;
            Conv_I8   : stack.Push(Convert.ToInt64(stack.Pop())); goto Read;
            Conv_R4   : stack.Push(Convert.ToSingle(stack.Pop())); goto Read;
            Conv_R8   : stack.Push(Convert.ToDouble(stack.Pop())); goto Read;
            Conv_U4   : stack.Push(Convert.ToUInt32(stack.Pop())); goto Read;
            Conv_U8   : stack.Push(Convert.ToUInt64(stack.Pop())); goto Read;
            Callvirt  : goto Call;
            Cpobj     : goto NotImplemented_S;
            Ldobj     : goto NotImplemented_S;
            Ldstr     : stack.Push(resolver.ResolveStringToken(br.ReadInt32())); goto Read;
Newobj:
            method = resolver.ResolveMethodToken(br.ReadInt32());
            arr    = new object[method.GetParameters().Length];
            for (i = arr.Length - 1; i >= 0; i--)
            {
                arr[i] = stack.Pop();
            }
            stack.Push(((ConstructorInfo)method).Invoke(arr));
            goto Read;
            Castclass : stack.Push(Convert.ChangeType(stack.Pop(), resolver.ResolveTypeToken(br.ReadInt32()))); goto Read;
Isinst:
            type = resolver.ResolveTypeToken(br.ReadInt32());
            obj  = stack.Pop();
            if (obj.GetType().IsAssignableFrom(type))
            {
                stack.Push(Convert.ChangeType(obj, type));
            }
            else
            {
                stack.Push(0);
            }

            Conv_R_Un      : stack.Push(Convert.ToSingle(stack.Pop())); goto Read;
            Exec_MSIL_S    : goto NotSupported_S;
            Unbox          : stack.Push(Convert.ChangeType(stack.Pop(), resolver.ResolveTypeToken(br.ReadInt32())));
            Throw          : goto NotSupported_S;
            Ldfld          : stack.Push(resolver.ResolveFieldToken(br.ReadInt32()).GetValue(stack.Pop())); goto Read;
            Ldflda         : goto NotSupported_S;
            Stfld          : var val = stack.Pop(); resolver.ResolveFieldToken(br.ReadInt32()).SetValue(stack.Pop(), val); goto Read;
            Ldsfld         : stack.Push(resolver.ResolveFieldToken(br.ReadInt32()).GetValue(null)); goto Read;
            Ldsflda        : goto NotSupported_S;
            Stsfld         : resolver.ResolveFieldToken(br.ReadInt32()).SetValue(null, stack.Pop()); goto Read;
            Stobj          : goto NotSupported_S;
            Conv_Ovf_I1_Un : stack.Push(Convert.ToSByte(stack.Pop())); goto Read;
            Conv_Ovf_I2_Un : stack.Push(Convert.ToInt16(stack.Pop())); goto Read;
            Conv_Ovf_I4_Un : stack.Push(Convert.ToInt32(stack.Pop())); goto Read;
            Conv_Ovf_I8_Un : stack.Push(Convert.ToInt64(stack.Pop())); goto Read;
            Conv_Ovf_U1_Un : stack.Push(Convert.ToByte(stack.Pop())); goto Read;
            Conv_Ovf_U2_Un : stack.Push(Convert.ToUInt16(stack.Pop())); goto Read;
            Conv_Ovf_U4_Un : stack.Push(Convert.ToUInt32(stack.Pop())); goto Read;
            Conv_Ovf_U8_Un : stack.Push(Convert.ToUInt64(stack.Pop())); goto Read;
            Conv_Ovf_I_Un  : goto NotSupported_S;
            Conv_Ovf_U_Un  : goto NotSupported_S;
            Box            : stack.Push((object)stack.Pop()); goto Read;
            Newarr         : stack.Push(Array.CreateInstance(resolver.ResolveTypeToken(br.ReadInt32()), (int)(stack.Pop())));
            goto Read;
            Ldlen       : stack.Push(((Array)stack.Pop()).Length); goto Read;
            Ldelema     : goto Read;
            Ldelem_I1   : i = (int)stack.Pop(); stack.Push(Convert.ToSByte(((object[])stack.Pop())[i])); goto Read;
            Ldelem_U1   : i = (int)stack.Pop(); stack.Push(Convert.ToByte(((object[])stack.Pop())[i])); goto Read;
            Ldelem_I2   : i = (int)stack.Pop(); stack.Push(Convert.ToInt16(((object[])stack.Pop())[i])); goto Read;
            Ldelem_U2   : i = (int)stack.Pop(); stack.Push(Convert.ToUInt32(((object[])stack.Pop())[i])); goto Read;
            Ldelem_I4   : i = (int)stack.Pop(); stack.Push(Convert.ToInt32(((object[])stack.Pop())[i])); goto Read;
            Ldelem_U4   : i = (int)stack.Pop(); stack.Push(Convert.ToUInt32(((object[])stack.Pop())[i])); goto Read;
            Ldelem_I8   : i = (int)stack.Pop(); stack.Push(Convert.ToInt64(((object[])stack.Pop())[i])); goto Read;
            Ldelem_I    : goto NotSupported_S;
            Ldelem_R4   : i = (int)stack.Pop(); stack.Push((float)((object[])stack.Pop())[i]); goto Read;
            Ldelem_R8   : i = (int)stack.Pop(); stack.Push((double)((object[])stack.Pop())[i]); goto Read;
            Ldelem_Ref  : i = (int)stack.Pop(); stack.Push(((object[])stack.Pop())[i]); goto Read;
            Stelem_I    : goto NotSupported_S;
            Stelem_I1   : obj = Convert.ToSByte(stack.Pop()); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Stelem_I2   : obj = Convert.ToInt16(stack.Pop()); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Stelem_I4   : obj = Convert.ToInt32(stack.Pop()); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Stelem_I8   : obj = Convert.ToInt64(stack.Pop()); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Stelem_R4   : obj = Convert.ToSingle(stack.Pop()); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Stelem_R8   : obj = Convert.ToInt64(stack.Pop()); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Stelem_Ref  : obj = stack.Pop(); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Ldelem      : i   = (int)stack.Pop(); stack.Push(Convert.ChangeType(((object[])stack.Pop())[i], resolver.ResolveTypeToken(br.ReadInt32()))); goto Read;
            Stelem      : obj = Convert.ChangeType(stack.Pop(), resolver.ResolveTypeToken(br.ReadInt32())); i = (int)stack.Pop(); ((object[])stack.Pop())[i] = obj; goto Read;
            Unbox_Any   : stack.Push(Convert.ChangeType(stack.Pop(), resolver.ResolveTypeToken(br.ReadInt32()))); goto Read;
            Conv_Ovf_I1 : stack.Push(Convert.ToSByte(stack.Pop())); goto Read;
            Conv_Ovf_U1 : stack.Push(Convert.ToByte(stack.Pop())); goto Read;
            Conv_Ovf_I2 : stack.Push(Convert.ToInt16(stack.Pop())); goto Read;
            Conv_Ovf_U2 : stack.Push(Convert.ToUInt16(stack.Pop())); goto Read;
            Conv_Ovf_I4 : stack.Push(Convert.ToInt32(stack.Pop())); goto Read;
            Conv_Ovf_U4 : stack.Push(Convert.ToUInt32(stack.Pop())); goto Read;
            Conv_Ovf_I8 : stack.Push(Convert.ToInt32(stack.Pop())); goto Read;
            Conv_Ovf_U8 : stack.Push(Convert.ToUInt64(stack.Pop())); goto Read;
            Refanyval   : goto NotSupported_S;
            Ckfinite    : var ckval = stack.Pop(); stack.Push(Convert.ToInt32(ckval is float?float.IsInfinity((float)ckval) : double.IsInfinity((double)ckval))); goto Read;
            Mkrefany    : goto NotSupported_S;
            Ldtoken     : stack.Push(resolver.ResolveMemberToken(br.ReadInt32())); goto Read;
            Conv_U2     : stack.Push(unchecked ((ushort)stack.Pop())); goto Read;
            Conv_U1     : stack.Push(unchecked ((byte)stack.Pop())); goto Read;
            Conv_I      : goto NotSupported_S;
            Conv_Ovf_I  : goto NotSupported_S;
            Conv_Ovf_U  : goto NotSupported_S;
            Add_Ovf     : goto Add;
            Add_Ovf_Un  : goto Add;
            Mul_Ovf     : goto Mul;
            Mul_Ovf_Un  : goto Mul;
            Sub_Ovf     : goto Sub;
            Sub_Ovf_Un  : goto Sub;
            Endfinally  : goto NotSupported_S;
            Leave       : goto NotSupported_S;
            Leave_S     : goto NotSupported_S;
            Stind_I     : goto NotSupported_S;
            Conv_U      : goto NotSupported_S;
            Prefix7     : goto NotSupported_S;
            Prefix6     : goto NotSupported_S;
            Prefix5     : goto NotSupported_S;
            Prefix4     : goto NotSupported_S;
            Prefix3     : goto NotSupported_S;
            Prefix2     : goto NotSupported_S;

Prefix1:

            switch (op = stream.ReadByte())
            {
            case 0: goto NotSupportedLong;                                                                //arglist

            case 1: stack.Push(Convert.ToInt32((dynamic)stack.Pop() == (dynamic)stack.Pop())); goto Read; // Ceq = 0xfe01,

            case 2: stack.Push(Convert.ToInt32((dynamic)stack.Pop() < (dynamic)stack.Pop())); goto Read;  // Cgt = 0xfe02,

            case 3: stack.Push(Convert.ToInt32((dynamic)stack.Pop() < (dynamic)stack.Pop())); goto Read;  // Cgt_Un = 0xfe03,

            case 4: stack.Push(Convert.ToInt32((dynamic)stack.Pop() > (dynamic)stack.Pop())); goto Read;  //     Clt = 0xfe04,

            case 5: stack.Push(Convert.ToInt32((dynamic)stack.Pop() < (dynamic)stack.Pop())); goto Read;  //       Clt_Un = 0xfe05,

            case 6: goto NotSupportedLong;                                                                // Ldftn = 0xfe06,

            case 7: goto NotSupportedLong;                                                                // Ldvirtftn = 0xfe07,

            case 8: goto NotImplementedLong;                                                              // 0xfe08,

            case 9: stack.Push(args[br.ReadInt16()]); goto Read;                                          // Ldarg = 0xfe09,

            case 10: stack.Push(args[br.ReadInt16()]); goto Read;                                         // Ldarga = 0xfe0a,

            case 11: args[br.ReadInt16()] = stack.Pop(); goto Read;                                       // Starg = 0xfe0b,

            case 12: stack.Push(locals[br.ReadInt16()].Value); goto Read;                                 // Ldloc = 0xfe0c,

            case 13: stack.Push(locals[br.ReadInt16()].Value); goto Read;                                 // Ldloca = 0xfe0d,

            case 14: locals[br.ReadInt16()].Value = stack.Pop(); goto Read;                               // Stloc = 0xfe0e,

            case 15: goto NotSupportedLong;                                                               // Localloc = 0xfe0f,

            case 16: goto NotImplementedLong;                                                             //0xfe10,

            case 17: goto NotSupportedLong;                                                               //  Endfilter = 0xfe11,

            case 18: goto NotSupportedLong;                                                               // Unaligned_ = 0xfe12,

            case 19: goto NotSupportedLong;                                                               // Volatile_ = 0xfe13,

            case 20: goto NotSupportedLong;                                                               // Tail_ = 0xfe14,

            case 21: goto NotSupportedLong;                                                               // Initobj = 0xfe15,

            case 22: goto NotSupportedLong;                                                               // Constrained_ = 0xfe16,

            case 23: goto NotSupportedLong;                                                               // Cpblk = 0xfe17,

            case 24: goto NotSupportedLong;                                                               // Initblk = 0xfe18,

            case 25: goto NotImplementedLong;                                                             //0xfe19

            case 26: goto NotSupportedLong;                                                               // Rethrow = 0xfe1a

            case 27: goto NotImplementedLong;                                                             //  = 0xfe1b

            case 28: goto NotSupportedLong;                                                               // Sizeof = 0xfe1c,

            case 29: goto NotSupportedLong;                                                               // Refanytype = 0xfe1d,

            case 30: goto NotSupportedLong;                                                               //  Readonly_ = 0xfe1e,
            }

            Prefixref : goto Read;

            NotImplemented     : throw new NotImplementedException($"OpCode {op} is not implemented");
            NotImplementedLong : throw new NotImplementedException($"OpCode { (short)((ushort)(0xFE00) | op)} is not implemented");

            NotSupported     : throw new NotImplementedException($"OpCode { OpCodeLookup.GetILOpcode(op)} is not supported");
            NotSupportedLong : throw new NotImplementedException($"OpCode { OpCodeLookup.GetILOpcode((short)((ushort)(0xFE00) | op))} is not supported");



            RetResult : return((stack.Count > 0) ? stack.Pop() : null);
        }