Exemplo n.º 1
0
 public TStackFrame BuildAndExecute(List <ILInstruction> stream,
                                    IILInstructionResolver resolver = null,
                                    object[] args       = null,
                                    ILVariable[] locals = null)
 {
     return(BuildAndExecute(stream, 0, resolver, args, locals));
 }
Exemplo n.º 2
0
        public TStackFrame Build(List <OpCode> opCodes,
                                 IILInstructionResolver resolver = null,
                                 object[] args       = null,
                                 ILVariable[] locals = null)
        {
            var streamWriter = new ILInstructionWriter(opCodes);
            var stream       = streamWriter.GetInstructionStream();

            return(Build(stream, resolver, args, locals));
        }
Exemplo n.º 3
0
        public TStackFrame BuildAndExecute(List <OpCode> opCodes, int timeout,
                                           IILInstructionResolver resolver = null,
                                           object[] args       = null,
                                           ILVariable[] locals = null)
        {
            var frame = Build(opCodes, resolver, args, locals);

            Execute(frame, timeout);
            return(frame);
        }
        protected TStackFrame BuildTestFrame(List <ILInstruction> stream,
                                             IILInstructionResolver resolver = null,
                                             object[] args       = null,
                                             ILVariable[] locals = null)
        {
            var result = NewFrame();

            result.Stream   = stream;
            result.Resolver = resolver;
            result.Args     = args;
            result.Locals   = locals;
            result.Reset();
            return(result);
        }
Exemplo n.º 5
0
        public TStackFrame Build(List <ILInstruction> stream,
                                 IILInstructionResolver resolver = null,
                                 object[] args       = null,
                                 ILVariable[] locals = null)
        {
            var result = new TStackFrame
            {
                Stream   = stream,
                Resolver = resolver,
                Args     = args,
                Locals   = locals
            };

            return(result);
        }
Exemplo n.º 6
0
        //Execution using strongly typed enumerations. Working implementation will be converted native integer values
        //  to allow native MSIL instruction
        public object ExecuteTyped(List <ILInstruction> stream,
                                   IILInstructionResolver resolver = null,
                                   object[] args             = null,
                                   ILVariable[] locals       = null,
                                   ILOperandStack frameStack = null)
        {
            //getArglistHandle(__arglist(1, 2, "s", 8)); <-- can't support dynamic/reflection based invocation
            //  probably best we can do is detect varargs, convert them to object[] and reinterprit msil.
            //  for now will just have to throw excpetion.


            if (resolver is null)
            {
                resolver = ILInstructionResolver.ExecutingAssemblyResolver;
            }

            var resolveField     = resolver.ResolveFieldToken;
            var resolveMember    = resolver.ResolveMemberToken;
            var resolveMethod    = resolver.ResolveMethodToken;
            var resolveSignature = resolver.ResolveSignatureToken;
            var resolveString    = resolver.ResolveStringToken;
            var resolveType      = resolver.ResolveTypeToken;



            var                   stack = frameStack ?? new ILOperandStack();
            ILInstruction         current;
            OpCode                code;
            int                   pos      = -1;
            Dictionary <int, int> jmptable = stream.ToDictionary(x => (int)x.ByteIndex, x => ++ pos);

            pos = -1;
            goto Inc;

ReadNext:
            current = stream[pos];
            code    = current.OpCode;

            short opCodeValue = code.Value;

            switch (opCodeValue)
            {
            case (short)ILOpCodeValues.Nop: break;

            case (short)ILOpCodeValues.Ret: goto Ret;

            case (short)ILOpCodeValues.Stloc_0:
                locals[0].Value = stack.Pop();
                break;

            case (short)ILOpCodeValues.Stloc_1:
                locals[1].Value = stack.Pop();
                break;

            case (short)ILOpCodeValues.Stloc_2:
                locals[2].Value = stack.Pop();
                break;

            case (short)ILOpCodeValues.Stloc_3:
                locals[3].Value = stack.Pop();
                break;

            case unchecked ((short)ILOpCodeValues.Stloc):
                locals[(int)current.Arg].Value = stack.Pop();
                break;

            case (short)ILOpCodeValues.Stloc_S:
                locals[(byte)current.Arg].Value = stack.Pop();
                break;

            case (short)ILOpCodeValues.Stobj:
                throw new NotImplementedException();

            case (short)ILOpCodeValues.Ldloc_0:
                stack.Push(locals[0].Value);
                break;

            case (short)ILOpCodeValues.Ldloc_1:
                stack.Push(locals[1].Value);
                break;

            case (short)ILOpCodeValues.Ldloc_2:
                stack.Push(locals[2].Value);
                break;

            case (short)ILOpCodeValues.Ldloc_3:
                stack.Push(locals[3].Value);
                break;

            case unchecked ((short)ILOpCodeValues.Ldloc):
                stack.Push(locals[(int)current.Arg].Value);
                break;

            case (short)ILOpCodeValues.Ldloc_S:
                stack.Push(locals[(byte)current.Arg].Value);
                break;

            case unchecked ((short)ILOpCodeValues.Ldloca):
                stack.Push(locals[(int)current.Arg]);
                break;

            case (short)ILOpCodeValues.Ldloca_S:
                stack.Push(locals[(byte)current.Arg]);
                break;

            case (short)ILOpCodeValues.Ldarg_0:
                stack.Push(args[0]);
                break;

            case (short)ILOpCodeValues.Ldarg_1:
                stack.Push(args[1]);
                break;

            case (short)ILOpCodeValues.Ldarg_2:
                stack.Push(args[2]);
                break;

            case (short)ILOpCodeValues.Ldarg_3:
                stack.Push(args[3]);
                break;

            case unchecked ((short)ILOpCodeValues.Ldarg):
                stack.Push(args[(int)current.Arg]);
                break;

            case unchecked ((short)ILOpCodeValues.Ldarg_S):
                stack.Push(args[(byte)current.Arg]);
                break;

            case (short)ILOpCodeValues.Ldarga_S:
                stack.Push(args[(byte)current.Arg]);
                break;

            case unchecked ((short)ILOpCodeValues.Ldarga):
                stack.Push(args[(int)current.Arg]);
                break;

            case (short)ILOpCodeValues.Ldc_I4:
                stack.Push((int)current.Arg);
                break;

            case (short)ILOpCodeValues.Ldc_I4_0:
                stack.Push(0);
                break;

            case (short)ILOpCodeValues.Ldc_I4_1:
                stack.Push(1);
                break;

            case (short)ILOpCodeValues.Ldc_I4_2:
                stack.Push(2);
                break;

            case (short)ILOpCodeValues.Ldc_I4_3:
                stack.Push(3);
                break;

            case (short)ILOpCodeValues.Ldc_I4_4:
                stack.Push(4);
                break;

            case (short)ILOpCodeValues.Ldc_I4_5:
                stack.Push(5);
                break;

            case (short)ILOpCodeValues.Ldc_I4_6:
                stack.Push(6);
                break;

            case (short)ILOpCodeValues.Ldc_I4_7:
                stack.Push(7);
                break;

            case (short)ILOpCodeValues.Ldc_I4_8:
                stack.Push(8);
                break;

            case (short)ILOpCodeValues.Ldc_I4_S:
                stack.Push(Convert.ToInt32(current.Arg));
                break;

            case (short)ILOpCodeValues.Ldc_I4_M1:
                stack.Push(-1);
                break;

            case (short)ILOpCodeValues.Ldc_I8:
                stack.Push(Convert.ToInt64(current.Arg));
                break;

            case (short)ILOpCodeValues.Ldc_R4:
                stack.Push(Convert.ToSingle(current.Arg));
                break;

            case (short)ILOpCodeValues.Ldc_R8:
                stack.Push(Convert.ToDouble(current.Arg));
                break;

            case (short)ILOpCodeValues.Box:     // 140: //box
                stack.Push(((object)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Ckfinite:     // 195: //ckfinite
                var ckval = stack.Pop(); stack.Push((ckval is float?float.IsInfinity((float)ckval) : double.IsInfinity((double)ckval)));
                break;

            case (short)ILOpCodeValues.Conv_I1:    // 103: //conv.i1
                stack.Push(unchecked ((sbyte)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_I2:     //104: //conv.i2
                stack.Push(unchecked ((short)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_I4:     //105: //conv.i4
                stack.Push(unchecked ((int)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_I8:     //106: //conv.i8
            {
                var arg = stack.Pop();
                try
                {
                    stack.Push(unchecked (Convert.ToInt64(arg)));
                }
                catch
                {
                    stack.Push(unchecked ((long)Convert.ToUInt64(arg)));
                }
            }

            break;

            case (short)ILOpCodeValues.Conv_Ovf_I1:     //179: //conv.ovf.i1
                stack.Push(checked ((sbyte)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I1_Un:     //130: //conv.ovf.i1.un
                stack.Push(checked ((sbyte)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I2:     //181: //conv.ovf.i2
                stack.Push(checked ((short)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I2_Un:     //131: //conv.ovf.i2.un
                stack.Push(checked ((short)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I4:     //183: //conv.ovf.i4
                stack.Push(checked ((int)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I4_Un:     //132: //conv.ovf.i4.un
                stack.Push(checked ((int)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I8:     //185: //conv.ovf.i8
                stack.Push(checked ((long)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_I8_Un:     //133: //conv.ovf.i8.un
                stack.Push(checked ((long)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U1:     //180: //conv.ovf.u1
                stack.Push(checked ((byte)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U1_Un:     //134: //conv.ovf.u1.un
                stack.Push(checked ((byte)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U2:     //182: //conv.ovf.u2
                stack.Push(checked ((ushort)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U2_Un:     //135: //conv.ovf.u2.un
                stack.Push(checked ((ushort)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U4:     //184: //conv.ovf.u4
                stack.Push(checked ((uint)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U4_Un:     //136: //conv.ovf.u4.un
                stack.Push(checked ((uint)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U8:     //186: //conv.ovf.u8
                stack.Push(checked ((ulong)Convert.ToInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_Ovf_U8_Un:     //137: //conv.ovf.u8.un
                stack.Push(checked ((ulong)Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_R4:     //107: //conv.r4
                stack.Push(Convert.ToSingle(stack.Pop()));
                break;

            case (short)ILOpCodeValues.Conv_R8:     //108: //conv.r8
                stack.Push(Convert.ToDouble(stack.Pop()));
                break;

            case (short)ILOpCodeValues.Conv_R_Un:     //118: //conv.r.un
                stack.Push(Convert.ToSingle(stack.Pop()));
                break;

            case (short)ILOpCodeValues.Conv_U1:     //210: //conv.u1
                stack.Push(unchecked (Convert.ToByte(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_U2:     //209: //conv.u2
                stack.Push(unchecked (Convert.ToUInt16(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Conv_U4:     //109: //conv.u4
                stack.Push(unchecked ((uint)(Convert.ToInt64(stack.Pop()))));
                break;

            case (short)ILOpCodeValues.Conv_U8:     //110: //conv.u8
                stack.Push(unchecked (Convert.ToUInt64(stack.Pop())));
                break;

            case (short)ILOpCodeValues.Neg:     //101: //neg
                stack.Push(-((dynamic)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Newarr:     //141: //newarr
                stack.Push(Array.CreateInstance(((current.Arg is int) ? resolveType((int)current.Arg) : (Type)current.Arg), (int)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Not:     //102: //not
                stack.Push(!((dynamic)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Pop: //38: //pop
                stack.Pop();                // no push
                break;

            case (short)ILOpCodeValues.Shl:     //98: //shl
                stack.Push(((dynamic)stack.Pop()) << ((int)current.Arg));
                break;

            case (short)ILOpCodeValues.Shr:     //99: //shr
                stack.Push(((dynamic)stack.Pop()) >> ((int)current.Arg));
                break;

            case (short)ILOpCodeValues.Shr_Un:     //100: //shr.un
                stack.Push(((dynamic)stack.Pop()) >> ((int)current.Arg));
                break;

            case (short)ILOpCodeValues.Unbox:     //121: //unbox
                stack.Push(Convert.ChangeType(stack.Pop(), resolveType((int)current.Arg)));
                break;

            case (short)ILOpCodeValues.Unbox_Any:     //165: //unbox.any
                stack.Push(Convert.ChangeType(stack.Pop(), resolveType((int)current.Arg)));
                break;

            case (short)ILOpCodeValues.Add:     //: //add
                stack.Push(unchecked ((dynamic)stack.Pop() + (dynamic)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Add_Ovf:     // 214: //add.ovf
                stack.Push(checked ((dynamic)stack.Pop() + (dynamic)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Add_Ovf_Un:     // 215: //add.ovf.un
                stack.Push(checked ((dynamic)stack.Pop() + (dynamic)stack.Pop()));
                break;

            case (short)ILOpCodeValues.And:     //95: //and
                stack.Push(((dynamic)stack.Pop()) & ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Ceq):    //: //ceq
            {
                var opa = stack.Pop();
                var opb = stack.Pop();

                if (opa is IConvertible && opb is IConvertible)
                {
                    var compc = ((IComparable)(opa)).CompareTo(Convert.ChangeType(opb, Convert.GetTypeCode(opa)));
                    stack.Push(compc == 0 ? 1 : 0);
                }
                else
                {
                    stack.Push(Convert.ToInt32(((dynamic)opa) == ((dynamic)opb)));
                }
            }

            break;

            case unchecked ((short)ILOpCodeValues.Cgt):    // -510: //cgt
                stack.Push(Convert.ToInt32(((dynamic)stack.Pop()) < ((dynamic)stack.Pop())));
                break;

            case unchecked ((short)ILOpCodeValues.Cgt_Un):    //- 509: //cgt.un
                stack.Push(Convert.ToInt32(((dynamic)stack.Pop()) < ((dynamic)stack.Pop())));
                break;

            case unchecked ((short)ILOpCodeValues.Clt):                                       // -508: //clt
                stack.Push(Convert.ToInt32(((dynamic)stack.Pop()) > ((dynamic)stack.Pop()))); //either swap pop order or sign
                break;

            case unchecked ((short)ILOpCodeValues.Clt_Un):    // -507: //clt.un
                stack.Push(Convert.ToInt32(((dynamic)stack.Pop()) > ((dynamic)stack.Pop())));
                break;

            case unchecked ((short)ILOpCodeValues.Div):    // 91: //div
                stack.Push(((dynamic)stack.Pop()) / ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Div_Un):    // 92: //div.un
                stack.Push(((dynamic)stack.Pop()) / ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Mul):    // 90: //mul
                stack.Push(unchecked (((dynamic)stack.Pop()) * ((dynamic)stack.Pop())));
                break;

            case unchecked ((short)ILOpCodeValues.Mul_Ovf):    // 216: //mul.ovf
                stack.Push(((dynamic)stack.Pop()) * ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Mul_Ovf_Un):    // 217: //mul.ovf.un
                stack.Push(((dynamic)stack.Pop()) * ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Or):    // 96: //or
                stack.Push(((dynamic)stack.Pop()) | ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Rem):    // 93: //rem
                stack.Push(((dynamic)stack.Pop()) % ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Rem_Un):    // 94: //rem.un
                stack.Push(((dynamic)stack.Pop()) % ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Sub):    // 89: //sub
                stack.Push(unchecked (((dynamic)stack.Pop()) - ((dynamic)stack.Pop())));
                break;

            case unchecked ((short)ILOpCodeValues.Sub_Ovf):    // 218: //sub.ovf
                stack.Push(((dynamic)stack.Pop()) - ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Sub_Ovf_Un):    // 219: //sub.ovf.un
                stack.Push(((dynamic)stack.Pop()) - ((dynamic)stack.Pop()));
                break;

            case unchecked ((short)ILOpCodeValues.Xor):    // 97: //xor
                stack.Push(((dynamic)stack.Pop()) ^ ((dynamic)stack.Pop()));
                break;

            case (short)ILOpCodeValues.Ldstr:
            {
                if (current.Arg is string)
                {
                    stack.Push((string)current.Arg);
                }
                else
                {
                    stack.Push(resolveString((int)current.Arg));
                }
                break;
            }

            case (short)ILOpCodeValues.Newobj:
            {
                var ctor     = (System.Reflection.ConstructorInfo)resolveMethod((int)current.Arg);
                var ctorArgs = new object[ctor.GetParameters().Length];
                for (var i = ctorArgs.Length - 1; i > -1; i--)
                {
                    ctorArgs[i] = stack.Pop();
                }
                //var reversed = ctorArgs.Reverse().ToArray();
                var ctorResult = ctor.Invoke(ctorArgs);
                stack.Push(ctorResult);
                break;
            }

            case (short)ILOpCodeValues.Ldfld:
            {
                var field  = resolveField((int)current.Arg);
                var target = stack.Pop();
                var value  = field.GetValue(target);
                stack.Push(value);
                break;
            }

            case (short)ILOpCodeValues.Ldsfld:
            {
                var field = resolveField((int)current.Arg);
                var value = field.GetValue(null);
                stack.Push(value);
                break;
            }

            case (short)ILOpCodeValues.Stfld:
            {
                var field  = resolveField((int)current.Arg);
                var fo     = stack.Pop();
                var target = stack.Pop();
                field.SetValue(target, fo);
                //stack.Push(value);
                break;
            }

            case (short)ILOpCodeValues.Stsfld:
            {
                var field = resolveField((int)current.Arg);
                var fo    = stack.Pop();
                //var target = stack.Pop();
                field.SetValue(null, fo);
                break;
            }

            case (short)ILOpCodeValues.Ldlen:
            {
                var array = stack.Pop();
                var arr   = (Array)array;
                stack.Push(arr.Length);
                break;
            }

            case (short)ILOpCodeValues.Stelem:
            {
                object el    = stack.Pop();
                int    index = (int)stack.Pop();
                var    array = (Array)stack.Pop();

                array.GetType()
                .GetMethod("SetValue", new[] { typeof(object), typeof(int) })
                .Invoke(array, new object[] { el, index });
                break;
            }

            case (short)ILOpCodeValues.Stelem_I1:
            {
                object el        = stack.Pop();
                int    index     = (int)stack.Pop();
                var    array     = stack.Pop();
                var    arrType   = array.GetType();
                var    arrElType = arrType.GetElementType();
                var    elType    = el.GetType();
                if (elType == arrElType)
                {
                    ((Array)array).SetValue(el, index);
                }
                else if (arrElType == typeof(sbyte))
                {
                    ((sbyte[])array)[index] = (sbyte)(int)el;
                }
                else
                {
                    ((byte[])array)[index] = (byte)(int)el;
                }
                break;
            }

            case (short)ILOpCodeValues.Stelem_I2:
            {
                object el        = stack.Pop();
                int    index     = (int)stack.Pop();
                var    array     = stack.Pop();
                var    arrType   = array.GetType();
                var    arrElType = arrType.GetElementType();
                var    elType    = el.GetType();

                if (elType == arrElType)
                {
                    ((Array)array).SetValue(el, index);
                }
                else if (arrElType == typeof(short))
                {
                    ((Array)array).SetValue((short)(int)el, index);
                }
                else if (arrElType == typeof(short))
                {
                    ((Array)array).SetValue((ushort)(int)el, index);
                }
                else
                {
                    ((Array)array).SetValue(Convert.ChangeType(el, arrElType), index);
                }
                break;
            }

            case (short)ILOpCodeValues.Stelem_I4:
            {
                object el        = stack.Pop();
                int    index     = (int)stack.Pop();
                var    array     = stack.Pop();
                var    arrType   = array.GetType();
                var    arrElType = arrType.GetElementType();
                var    elType    = el.GetType();
                if (elType == arrElType)
                {
                    ((Array)array).SetValue(el, index);
                }
                else if (arrElType == typeof(int))
                {
                    ((int[])array)[index] = (int)el;
                }
                else
                {
                    ((uint[])array)[index] = (uint)el;
                }
                break;
            }

            case (short)ILOpCodeValues.Stelem_I8:
            {
                object el        = stack.Pop();
                int    index     = (int)stack.Pop();
                var    array     = stack.Pop();
                var    arrType   = array.GetType();
                var    arrElType = arrType.GetElementType();
                var    elType    = el.GetType();
                if (elType == arrElType)
                {
                    ((Array)array).SetValue(el, index);
                }
                else if (arrElType == typeof(long))
                {
                    ((long[])array)[index] = (long)el;
                }
                else
                {
                    ((ulong[])array)[index] = (ulong)el;
                }
                break;
            }

            case (short)ILOpCodeValues.Stelem_R4:
            {
                object el        = stack.Pop();
                int    index     = (int)stack.Pop();
                var    array     = stack.Pop();
                var    arrType   = array.GetType();
                var    arrElType = arrType.GetElementType();
                var    elType    = el.GetType();
                if (elType == arrElType)
                {
                    ((Array)array).SetValue(el, index);
                }
                else if (arrElType == typeof(float))
                {
                    ((float[])array)[index] = (float)el;
                }
                //else ((ulong[])array)[index] = (ulong)el;
                break;
            }

            case (short)ILOpCodeValues.Stelem_R8:
            {
                object el        = stack.Pop();
                int    index     = (int)stack.Pop();
                var    array     = stack.Pop();
                var    arrType   = array.GetType();
                var    arrElType = arrType.GetElementType();
                var    elType    = el.GetType();
                if (elType == arrElType)
                {
                    ((Array)array).SetValue(el, index);
                }
                else if (arrElType == typeof(double))
                {
                    ((double[])array)[index] = (double)el;
                }
                //else ((ulong[])array)[index] = (ulong)el;
                break;
            }

            case (short)ILOpCodeValues.Stelem_Ref:
            {
                object val   = stack.Pop();
                int    index = (int)stack.Pop();
                var    array = stack.Pop();
                ((Array)array).SetValue(val, index);
                break;
            }

            case (short)ILOpCodeValues.Ldelem:
            case (short)ILOpCodeValues.Ldelema:
            case (short)ILOpCodeValues.Ldelem_I:
            case (short)ILOpCodeValues.Ldelem_Ref:
            {
                var idx   = (int)stack.Pop();
                var array = (Array)stack.Pop();
                var val   = array.GetValue(idx);
                stack.Push(val);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_I1:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = (sbyte)Convert.ToInt32(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_I2:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = (short)Convert.ToInt32(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_I4:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = Convert.ToInt32(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_I8:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = Convert.ToInt64(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_U1:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = (byte)Convert.ToUInt32(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_U2:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = (ushort)Convert.ToUInt32(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_U4:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = Convert.ToUInt32(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_R4:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = Convert.ToSingle(val);
                stack.Push(target);
                break;
            }

            case (short)ILOpCodeValues.Ldelem_R8:
            {
                var idx    = (int)stack.Pop();
                var array  = (Array)stack.Pop();
                var val    = array.GetValue(idx);
                var target = Convert.ToDouble(val);
                stack.Push(target);
                break;
            }


            case (short)ILOpCodeValues.Conv_I:
            case (short)ILOpCodeValues.Conv_Ovf_I_Un:
            case (short)ILOpCodeValues.Conv_Ovf_I:
                //Todo: native int operations
                throw new OpCodeNotImplementedException(code);

            case (short)ILOpCodeValues.Dup:
                stack.Push(stack.Peek());
                break;

            //TODO: Implemented scopre validation for branch: (EG, inside try, catch, finally,etc)
            case (short)ILOpCodeValues.Leave_S:
            case (short)ILOpCodeValues.Br_S:     //0x2b:
            {
                var delta     = (int)(sbyte)Convert.ToByte(current.Arg);
                var directpos = (int)stream[pos + 1].ByteIndex + delta;
                pos = jmptable[directpos];
                goto MoveNext;
            }

            case (short)ILOpCodeValues.Leave:
            case (short)ILOpCodeValues.Br:     // 0x38:
            {
                var delta     = Convert.ToInt32(current.Arg);
                var directpos = (int)stream[pos + 1].ByteIndex + delta;
                pos = jmptable[directpos];
                goto MoveNext;
            }

            case (short)ILOpCodeValues.Beq:
            {
                var opa = stack.Pop();
                var opb = stack.Pop();
                if (opa is IConvertible && opb is IConvertible)
                {
                    var compc = ((IComparable)(opa)).CompareTo(Convert.ChangeType(opb, Convert.GetTypeCode(opa)));
                    stack.Push(compc == 0 ? 1 : 0);
                }
                else
                {
                    stack.Push(Convert.ToInt32(((dynamic)opa) == ((dynamic)opb)));
                }
                goto case (short)ILOpCodeValues.Brtrue;
            }

            case (short)ILOpCodeValues.Beq_S:
            {
                var opa = stack.Pop();
                var opb = stack.Pop();

                if (opa is IConvertible && opb is IConvertible)
                {
                    var compc = ((IComparable)(opa)).CompareTo(Convert.ChangeType(opb, Convert.GetTypeCode(opa)));
                    stack.Push(compc == 0 ? 1 : 0);
                }
                else
                {
                    stack.Push(Convert.ToInt32(((dynamic)opa) == ((dynamic)opb)));
                }
                goto case (short)ILOpCodeValues.Brtrue_S;
            }

            case (short)ILOpCodeValues.Brfalse:     //‭00111001‬
            {
                var chk        = stack.Pop();
                int cond       = Convert.ToInt32((chk is IConvertible) ? Convert.ToBoolean(chk) : Convert.ToBoolean(!(chk is null)));
                var condtarget = -1;
                if (cond == 0)
                {
                    condtarget = (int)stream[pos + 1].ByteIndex + Convert.ToInt32(current.Arg);
                    pos        = jmptable[condtarget];
                    goto MoveNext;
                }
                break;
            }

            case (short)ILOpCodeValues.Brfalse_S:
            {
                var chk        = stack.Pop();
                int cond       = Convert.ToInt32((chk is IConvertible) ? Convert.ToBoolean(chk) : Convert.ToBoolean(!(chk is null)));
                var condtarget = -1;
                if (cond == 0)
                {
                    condtarget = (int)stream[pos + 1].ByteIndex + (int)(sbyte)Convert.ToByte(current.Arg);
                    pos        = jmptable[condtarget];
                    goto MoveNext;
                }
                break;
            }

            case (short)ILOpCodeValues.Brtrue:
            {
                var chk        = stack.Pop();
                int cond       = Convert.ToInt32((chk is IConvertible) ? Convert.ToBoolean(chk) : Convert.ToBoolean(!(chk is null)));
                var condtarget = -1;
                if (cond == 1)
                {
                    condtarget = (int)stream[pos + 1].ByteIndex + Convert.ToInt32(current.Arg);
                    pos        = jmptable[condtarget];
                    goto MoveNext;
                }
                break;
            }

            case (short)ILOpCodeValues.Brtrue_S:
            {
                var chk        = stack.Pop();
                int cond       = Convert.ToInt32((chk is IConvertible) ? Convert.ToBoolean(chk) : Convert.ToBoolean(!(chk is null)));
                var condtarget = -1;
                if (cond == 1)
                {
                    condtarget = (int)stream[pos + 1].ByteIndex + (int)(sbyte)Convert.ToByte(current.Arg);
                    pos        = jmptable[condtarget];
                    goto MoveNext;
                }
                break;
            }

            case (short)ILOpCodeValues.Call:
            case (short)ILOpCodeValues.Calli:
            case (short)ILOpCodeValues.Callvirt:
                System.Reflection.MethodBase method = null;
                object resolved = null;
                if (current.Arg is System.Reflection.MethodInfo)
                {
                    method = (System.Reflection.MethodInfo)current.Arg;
                }
                else
                {
                    resolved = resolveMethod((int)current.Arg);
                }


                if (resolved is ConstructorInfo)
                {
                    method = (ConstructorInfo)resolved;
                }
                else
                {
                    method = (System.Reflection.MethodInfo)resolved;
                }

                var parameters = method.GetParameters();
                var methodArgs = new object[parameters.Length];

                for (var i = methodArgs.Length - 1; i >= 0; i--)
                {
                    var val = stack.Pop();
                    if (val is ILVariable)
                    {
                        methodArgs[i] = ((ILVariable)(val)).Value;
                    }
                    else
                    {
                        methodArgs[i] = val;
                    }
                }

                object methodTarget = null;
                if (!method.IsStatic && !method.IsConstructor)
                {
                    methodTarget = stack.Pop();
                }
                if (methodTarget is ILVariable)
                {
                    methodTarget = ((ILVariable)methodTarget).Value;
                }
                //var t = default(RuntimeTypeHandle);
                //var t1 = default(ArgIterator);
                //var tobject = new object[] { t, t };
                //var del = Delegate.CreateDelegate()
                //((ConstructorInfo)method).Invoke( new object[]{ t});
                for (var i = methodArgs.Length - 1; i >= 0; i--)
                {
                    if (methodArgs[i] is IConvertible)
                    {
                        methodArgs[i] = Convert.ChangeType(methodArgs[i], parameters[i].ParameterType);
                    }
                }

                //if the current method is invoking another method then convert the arguments for the inner method.
                if (methodTarget is MethodBase && methodArgs.Length == 2 && methodArgs[1] is Array)
                {
                    var invokeArgs       = (Array)methodArgs[1];
                    var invokeParameters = ((MethodInfo)methodTarget).GetParameters();
                    for (var i = invokeArgs.Length - 1; i >= 0; i--)
                    {
                        var arg = invokeArgs.GetValue(i);
                        if (arg is IConvertible)
                        {
                            invokeArgs.SetValue(Convert.ChangeType(arg, invokeParameters[i].ParameterType), i);
                        }
                    }
                    //if (invokeArgs.GetValue(i) is IConvertible)
                    //    invokeArgs.SetValue(Convert.ChangeType(invokeArgs[i], invokeParameters[i].ParameterType));
                }

                // Roadblock here: Int.CompareTo(object value) -> argument value must be of type int but there is no way to programatically determine the expected destination type.

                var methodresult = (method is MethodInfo) ? method.Invoke(methodTarget, methodArgs) : ((ConstructorInfo)method).Invoke(methodArgs);
                if (code.StackBehaviourPush == StackBehaviour.Varpush)
                {
                    if ((method as MethodInfo)?.ReturnType != typeof(void) || method.IsConstructor)
                    {
                        stack.Push(methodresult);
                    }
                }
                break;

            case unchecked ((short)ILOpCodeValues.Ldobj):
                stack.Push(current.Arg);
                break;

            case (short)ILOpCodeValues.Ldnull:
                stack.Push(null);
                break;

            case unchecked ((short)ILOpCodeValues.Ldftn):
                var ftnToken  = (int)current.Arg;
                var ftnMethod = resolver.ResolveMethodToken(ftnToken);
                stack.Push(ftnMethod.MethodHandle.GetFunctionPointer());
                break;

            case unchecked ((short)ILOpCodeValues.Initobj):

                var newObj = Activator.CreateInstance(resolver.ResolveTypeToken((int)current.Arg));
                var inst   = stack.Pop();
                if (inst is ILVariable ilvar)
                {
                    ilvar.Value         = newObj;
                    locals[ilvar.Index] = ilvar;
                }
                else
                {
                    inst = newObj;
                }

                break;

            case (short)ILOpCodeValues.Ldtoken:
                var metaToken = (int)current.Arg;
                var memToken  = resolver.ResolveMemberToken(metaToken);
                var tokenType = memToken.GetType();


                switch (tokenType.Name)
                {
                case "RtFieldInfo":
                {
                    var fieldInfo = resolver.ResolveFieldToken(metaToken);
                    var handle    = (FieldInfo)fieldInfo;
                    stack.Push(handle.FieldHandle);
                }
                break;

                case "RuntimeType":
                {
                    var type   = resolver.ResolveTypeToken(metaToken);
                    var handle = (Type)type;
                    stack.Push(handle.TypeHandle);
                }

                break;

                default:

                    throw new OpCodeNotImplementedException(code);
                }


                break;

            case (short)ILOpCodeValues.Castclass:

                var targetClassToken = (int)current.Arg;
                var targetType       = resolver.ResolveTypeToken(targetClassToken);

                var listType = typeof(List <>).MakeGenericType(new[] { targetType });
                var instance = Activator.CreateInstance(listType);
                var prop     = listType.GetProperty("Item");
                var src      = stack.Pop();


                var add = listType.GetMethod("Add");
                add.Invoke(instance, new[] { src });
                var get        = listType.GetMethod("get_Item");
                var listresult = get.Invoke(instance, new object[] { 0 });
                stack.Push(listresult);

                break;

            case (short)ILOpCodeValues.Break:
                if (TriggerBreak)
                {
                    System.Diagnostics.Debugger.Break();
                }
                break;

            default:
                throw new OpCodeNotImplementedException(code);
            }


Inc:
            pos++;
MoveNext:
            if (pos < stream.Count)
            {
                goto ReadNext;
            }

Ret:
            var result = (stack.Count > 0) ? stack.Pop() : null;

            if (TriggerBreak)
            {
                System.Diagnostics.Debug.Assert(stack.Count == 0);
            }
            else
            {
                //if (stack.Count > 0) throw new InvalidProgramException("Stack is not empty {stack.Count}");
            }

            return(result);
        }
Exemplo n.º 7
0
        public T ExecuteTyped <T>(List <ILInstruction> stream, IILInstructionResolver resolver = null, object[] args = null, ILVariable[] locals = null)
        {
            var result = ExecuteTyped(stream, resolver, args, locals);

            return((T)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);
        }