Example #1
0
            /// <summary>
            /// Executes instructions in finally blocks that protect the region the specified leave instruction exits.
            /// </summary>
            /// <param name="leaveIL">The IL instruction that exits a protected region of code. </param>
            void ExecuteFinallyBlocks(BranchInstruction leaveIL)
            {
                SortedList <int, ExceptionHandlingClause> finallyblocks = new SortedList <int, ExceptionHandlingClause>();

                // finds nested finally blocks, candidates should meet two conditions:
                // 1. the leave instruction is in the protected region of the finally block
                // 2. the branch target is out of the the protected region of the finally block
                foreach (ExceptionHandlingClause clause in methodBody.ExceptionHandlingClauses)
                {
                    if (clause.Flags == ExceptionHandlingClauseOptions.Finally)
                    {
                        if (leaveIL.Offset >= clause.TryOffset && leaveIL.Offset <= clause.TryOffset + clause.TryLength &&
                            leaveIL.Target >= clause.HandlerOffset + clause.HandlerLength)
                        {
                            ILInstruction instruction = instructions[clause.HandlerOffset];
                            if (!instruction.Visited)
                            {
                                finallyblocks.Add(clause.TryOffset, clause);
                            }
                        }
                    }
                }

                // executes the most deeply nested blocks before the blocks that enclose them
                foreach (ExceptionHandlingClause clause in finallyblocks.Values.Reverse())
                {
                    ILInstruction instruction = instructions[clause.HandlerOffset];
                    if (!instruction.Visited)
                    {
                        //System.Diagnostics.Debug.WriteLine("*** enter finally *** " + PrintInstruction(instruction));
                        Analysis(instruction, delegate(ILInstruction next) { return(next.OpCode.Name != "endfinally"); });
                        //System.Diagnostics.Debug.WriteLine("*** end finally *** ");
                    }
                }
            }
Example #2
0
 private Operator(OpCode opCode, bool invertOpResult, BranchInstruction branchOp, string methodName, IMemberInfo[] standardCandidates, SpecificOperatorProvider[] standardTemplates)
 {
     this.opCode             = this.opCodeUn = this.opCodeChk = this.opCodeChkUn = opCode;
     this.invertOpResult     = invertOpResult;
     this.branchOp           = branchOp;
     this.methodName         = methodName;
     this.standardCandidates = standardCandidates;
     this.standardTemplates  = standardTemplates;
 }
 private Operator(OpCode opCode, bool invertOpResult, BranchInstruction branchOp, string methodName, IMemberInfo[] standardCandidates, SpecificOperatorProvider[] standardTemplates)
 {
     OpCode              = OpCodeUn = OpCodeChk = OpCodeChkUn = opCode;
     InvertOpResult      = invertOpResult;
     BranchOp            = branchOp;
     MethodName          = methodName;
     _standardCandidates = standardCandidates ?? new IMemberInfo[0];
     _standardTemplates  = standardTemplates;
 }
        public void GetBytes_BranchInstruction(BranchKind branchKind)
        {
            var instruction   = new BranchInstruction(branchKind, 42);
            var expectedBytes = InstructionByteBuilder.Create()
                                .Opcode(Opcode.Branch, branchKind, 42)
                                .AsSpan();

            Assert.True(expectedBytes.SequenceEqual(instruction.GetBytes()));
        }
Example #5
0
 public OpCode Get(BranchInstruction ins, bool unsigned)
 {
     switch (ins)
     {
         case BranchInstruction.True: return brTrue;
         case BranchInstruction.False: return brFalse;
         case BranchInstruction.Eq: return brEq;
         case BranchInstruction.Ne: return brNe;
         case BranchInstruction.Lt: return unsigned ? brLtUn : brLt;
         case BranchInstruction.Gt: return unsigned ? brGtUn : brGt;
         case BranchInstruction.Le: return unsigned ? brLeUn : brLe;
         case BranchInstruction.Ge: return unsigned ? brGeUn : brGe;
         default:
             throw new NotSupportedException();
     }
 }
Example #6
0
        public void PatchEcu(ICode ecuCode)
        {
            if (ecuCode == null)
            {
                throw new ArgumentNullException("ecuCode");
            }

            if (!valueRead)
            {
                ReadValue();
            }

            int calculatedAddress = (Constants.INJECT_CODE_ADDRESS + branchOffsetInCode) - indexInEcu;
            BranchInstruction branchInstruction = new BranchInstruction();

            branchInstruction.value = (UInt32)calculatedAddress;
            byteConverter.CopyBytesGeneric(branchInstruction, ecuCode.CodeBytes, indexInEcu);
        }
Example #7
0
            int GetFirstConditionalBranchTarget(ILInstruction instruction)
            {
                int returnValue;

                // register the branch target for re-run after normal control flow completes.
                if (instruction is SwitchInstruction)
                {
                    SwitchInstruction switchIL = instruction as SwitchInstruction;
                    // run the first "case" target and register other targets(including "default") for re-run
                    if (switchIL.Cases.Length > 1)
                    {
                        returnValue = switchIL.Next + switchIL.Cases[0];
                        branchTargetsToVisit[switchIL.Next] = new Stack <Vertex>(evaluationStack);

                        for (int i = 1; i < switchIL.Cases.Length; i++)
                        {
                            branchTargetsToVisit[switchIL.Next + switchIL.Cases[i]] = new Stack <Vertex>(evaluationStack);
                        }
                    }
                    else
                    {
                        returnValue = switchIL.Next;
                    }
                }
                else
                {
                    BranchInstruction branchIL = instruction as BranchInstruction;
                    if (branchIL.Offset > branchIL.Target)
                    {
                        returnValue = branchIL.Target;
                        branchTargetsToVisit[branchIL.Next] = new Stack <Vertex>(evaluationStack);
                    }
                    else
                    {
                        returnValue = branchIL.Next;
                        branchTargetsToVisit[branchIL.Target] = new Stack <Vertex>(evaluationStack);
                    }
                }
                return(returnValue);
            }
Example #8
0
        static AssemblerController()
        {
            Assemblers["ADD"] = new AddInstruction();
            Assemblers["AND"] = new AndInstruction();

            Assemblers["BR"]    = new BranchInstruction("BR", true, true, true); // Alias of BRNZP
            Assemblers["BRN"]   = new BranchInstruction("BRN", true, false, false);
            Assemblers["BRZ"]   = new BranchInstruction("BRZ", false, true, false);
            Assemblers["BRP"]   = new BranchInstruction("BRP", false, false, true);
            Assemblers["BRZP"]  = new BranchInstruction("BRZP", false, true, true);
            Assemblers["BRNP"]  = new BranchInstruction("BRNP", true, false, true);
            Assemblers["BRNZ"]  = new BranchInstruction("BRNZ", true, true, false);
            Assemblers["BRNZP"] = new BranchInstruction("BRNZP", true, true, true);

            Assemblers["JMP"]  = new RegisterBasedPCAccessInstruction("JMP", 0b1100);
            Assemblers["JSR"]  = new JSRInstruction();
            Assemblers["JSRR"] = new RegisterBasedPCAccessInstruction("JSRR", 0b0100);
            Assemblers["LD"]   = new LabelBasedMemoryAccessInstruction("LD", 0b0010);
            Assemblers["LDI"]  = new LabelBasedMemoryAccessInstruction("LDI", 0b1010);
            Assemblers["LDR"]  = new OffsetBasedMemoryAccessInstruction("LDR", 0b0110);
            Assemblers["LEA"]  = new LabelBasedMemoryAccessInstruction("LEA", 0b1110);
            Assemblers["NOT"]  = new NotInstruction();
            Assemblers["RET"]  = new ZeroArgumentsInstruction("RET", 0xC1C0); // 1100 000 111 000000, i.e. JMP R7
            Assemblers["RTI"]  = new ZeroArgumentsInstruction("RTI", 0x8000); // 1000 000000000000
            Assemblers["ST"]   = new LabelBasedMemoryAccessInstruction("ST", 0b0011);
            Assemblers["STI"]  = new LabelBasedMemoryAccessInstruction("STI", 0b1011);
            Assemblers["STR"]  = new OffsetBasedMemoryAccessInstruction("STR", 0b0111);
            Assemblers["TRAP"] = new TrapInstruction();

            Assemblers["GETC"]  = new ZeroArgumentsInstruction("GETC", 0xF020);  // TRAP x20
            Assemblers["OUT"]   = new ZeroArgumentsInstruction("OUT", 0xF021);   // TRAP x21
            Assemblers["PUTS"]  = new ZeroArgumentsInstruction("PUTS", 0xF022);  // TRAP x22
            Assemblers["IN"]    = new ZeroArgumentsInstruction("IN", 0xF023);    // TRAP x23
            Assemblers["PUTSP"] = new ZeroArgumentsInstruction("PUTSP", 0xF024); // TRAP x24
            Assemblers["HALT"]  = new ZeroArgumentsInstruction("HALT", 0xF025);  // TRAP x25
        }
Example #9
0
        public OpCode Get(BranchInstruction ins, bool unsigned)
        {
            switch (ins)
            {
            case BranchInstruction.True: return(brTrue);

            case BranchInstruction.False: return(brFalse);

            case BranchInstruction.Eq: return(brEq);

            case BranchInstruction.Ne: return(brNe);

            case BranchInstruction.Lt: return(unsigned ? brLtUn : brLt);

            case BranchInstruction.Gt: return(unsigned ? brGtUn : brGt);

            case BranchInstruction.Le: return(unsigned ? brLeUn : brLe);

            case BranchInstruction.Ge: return(unsigned ? brGeUn : brGe);

            default:
                throw new NotSupportedException();
            }
        }
        public override CILInstructionBranchTarget BuildNode(ParseTreeNode node)
        {
            var instructionBranchTargetParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.INSTR_BRTARGET);

            CILInstructionBranchTarget result = null;

            var beqsParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_beqs);

            if (beqsParseTreeNode != null)
            {
                result = new BranchOnEqualShortInstruction();
            }

            var bgesParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_bges);

            if (bgesParseTreeNode != null)
            {
                result = new BranchOnGreaterOrEqualShortInstruction();
            }

            var blesParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_bles);

            if (blesParseTreeNode != null)
            {
                result = new BranchOnLessOrEqualShortInstruction();
            }

            var bltsParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_blts);

            if (bltsParseTreeNode != null)
            {
                result = new BranchOnLessShortInstruction();
            }

            var bneunsParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_bneuns);

            if (bneunsParseTreeNode != null)
            {
                result = new BranchOnNotEqualOrUnorderedShortInstruction();
            }

            var brParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_br);

            if (brParseTreeNode != null)
            {
                result = new BranchInstruction();
            }

            var brfalsesParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_brfalses);

            if (brfalsesParseTreeNode != null)
            {
                result = new BranchOnFalseShortInstruction();
            }

            var brsParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_brs);

            if (brsParseTreeNode != null)
            {
                result = new BranchShortInstruction();
            }

            var brtruesParseTreeNode = instructionBranchTargetParseTreeNode?.GetFirstChildWithGrammarName(GrammarNames.keyword_brtrues);

            if (brtruesParseTreeNode != null)
            {
                result = new BranchOnTrueShortInstruction();
            }

            if (result != null)
            {
                var idParseTreeNode = node.GetFirstChildWithGrammarName(GrammarNames.id);
                result.Label = IdParseTreeNodeHelper.GetValue(idParseTreeNode);

                return(result);
            }

            throw new ArgumentException("Cannot recognize CIL instruction branch target.");
        }
        public void Visit(BranchInstruction instruction)
        {
            var instructionName = instruction.Operator.GetAssemblySymbol();

            lines.Add($"{label}\t{instructionName} {instruction.One.GetAssemblySymbol()},{instruction.Another.GetAssemblySymbol()},{instruction.Target.GetAssemblySymbol()}");
        }
        public void ToString_BranchInstruction(BranchKind branchKind, string expectedString)
        {
            var branchInstruction = new BranchInstruction(branchKind, 42);

            Assert.Equal(expectedString, branchInstruction.ToString());
        }
Example #13
0
        internal Instruction ReadInstruction()
        {
            OpCodes     opcode = (OpCodes)this.ReadByte();
            Instruction result = Instruction.FixedOpCodes[(int)opcode];

            if (null != result)
            {
                return(result);
            }
            switch (opcode)
            {
            case OpCodes.Block:
                return(BlockInstruction.Create(this));

            case OpCodes.Loop:
                return(LoopInstruction.Create(this));

            case OpCodes.If:
                // block_type
                return(IfInstruction.Create(this));

            case OpCodes.Br:
            case OpCodes.BrIf:
                // varuint32
                return(BranchInstruction.Create(this, opcode));

            case OpCodes.BrTable:
                // custom
                return(BranchTableInstruction.Create(this));

            case OpCodes.Call:
            case OpCodes.CallIndirect:
                // varuint32 + varuint1
                return(CallInstruction.Create(this, opcode));

            case OpCodes.GetLocal:
            case OpCodes.SetLocal:
            case OpCodes.TeeLocal:
                // local_index
                return(LocalAccessorInstruction.Create(this, opcode));

            case OpCodes.GetGlobal:
            case OpCodes.SetGlobal:
                // global_index
                return(GlobalAccessorInstruction.Create(this, (OpCodes.GetGlobal == opcode)));

            case OpCodes.I32Load:
            case OpCodes.I64Load:
            case OpCodes.F32Load:
            case OpCodes.F64Load:
            case OpCodes.I32Load8_s:
            case OpCodes.I32Load8_u:
            case OpCodes.I32Load16_s:
            case OpCodes.I32Load16_u:
            case OpCodes.I64Load8_s:
            case OpCodes.I64Load8_u:
            case OpCodes.I64Load16_s:
            case OpCodes.I64Load16_u:
            case OpCodes.I64Load32_s:
            case OpCodes.I64Load32_u:
            case OpCodes.I32Store:
            case OpCodes.I64Store:
            case OpCodes.F32Store:
            case OpCodes.F64Store:
            case OpCodes.I32Store8:
            case OpCodes.I32Store16:
            case OpCodes.I64Store8:
            case OpCodes.I64Store16:
            case OpCodes.I64Store32:
                // memory_immediate
                return(MemoryAccessInstruction.Create(this, opcode));

            case OpCodes.CurrentMemory:
            case OpCodes.GrowMemory:
                // varuint1
                return(MemoryControlInstruction.Create(this, opcode));

            case OpCodes.I32Const:
                // varint32
                return(ConstantValueInstruction <int> .Create(this, OpCodes.I32Const, this.ReadVarInt32()));

            case OpCodes.I64Const:
                // varint64
                return(ConstantValueInstruction <long> .Create(this, OpCodes.I64Const, this.ReadVarInt64()));

            case OpCodes.F32Const:
                // uint32
                return(ConstantValueInstruction <float> .Create(this, OpCodes.F32Const, this.ReadVarFloat32()));

            case OpCodes.F64Const:
                // uint64
                return(ConstantValueInstruction <double> .Create(this, OpCodes.F64Const, this.ReadVarFloat64()));

            case OpCodes.F32eq:
            case OpCodes.F32ge:
            case OpCodes.F32gt:
            case OpCodes.F32le:
            case OpCodes.F32lt:
            case OpCodes.F32ne:
            case OpCodes.F64eq:
            case OpCodes.F64ge:
            case OpCodes.F64gt:
            case OpCodes.F64le:
            case OpCodes.F64lt:
            case OpCodes.F64ne:
            case OpCodes.I32eq:
            case OpCodes.I32ge_s:
            case OpCodes.I32ge_u:
            case OpCodes.I32gt_s:
            case OpCodes.I32gt_u:
            case OpCodes.I32le_s:
            case OpCodes.I32le_u:
            case OpCodes.I32lt_s:
            case OpCodes.I32lt_u:
            case OpCodes.I32ne:
            case OpCodes.I64eq:
            case OpCodes.I64ge_s:
            case OpCodes.I64ge_u:
            case OpCodes.I64gt_s:
            case OpCodes.I64gt_u:
            case OpCodes.I64le_s:
            case OpCodes.I64le_u:
            case OpCodes.I64lt_s:
            case OpCodes.I64lt_u:
            case OpCodes.I64ne:
                return(RelationalInstruction.GetInstruction(opcode));

            case OpCodes.F32Convert_sI32:
            case OpCodes.F32Convert_uI32:
            case OpCodes.F32Convert_sI64:
            case OpCodes.F32Convert_uI64:
            case OpCodes.F32demoteF64:
            case OpCodes.F64Convert_sI32:
            case OpCodes.F64Convert_uI32:
            case OpCodes.F64Convert_sI64:
            case OpCodes.F64Convert_uI64:
            case OpCodes.F64PromoteF32:
            case OpCodes.I32Trunc_sF32:
            case OpCodes.I32Trunc_uF32:
            case OpCodes.I32Trunc_sF64:
            case OpCodes.I32Trunc_uF64:
            case OpCodes.I32wrapI64:
            case OpCodes.I64Extend_sI32:
            case OpCodes.I64Extend_uI32:
            case OpCodes.I64Trunc_sF32:
            case OpCodes.I64Trunc_uF32:
            case OpCodes.I64Trunc_sF64:
            case OpCodes.I64Trunc_uF64:
                return(ConversionInstruction.GetInstruction(opcode));

            default:
                throw new NotSupportedException();
            }
        }
Example #14
0
 protected abstract void VisitBranchInstruction(BranchInstruction instruction);
Example #15
0
 public void VisitBranch(BranchInstruction instruction) => IncrementCallCount(nameof(VisitBranch));
Example #16
0
 public virtual void Visit(BranchInstruction instruction)
 {
 }
Example #17
0
        ExecuteComparisonInstructionBackward(CompareInstruction compareInstruction,
                                             Operand varOperand, Path path)
        {
            Expression result             = null;
            Operator   comparisonOperator = null;

            switch (compareInstruction.ConditionCode)
            {
            case ConditionCode.GT:
                comparisonOperator = OperatorStore.GreaterThanOp;
                break;

            case ConditionCode.UGT:
                comparisonOperator = OperatorStore.UGreaterThanOp;
                break;

            case ConditionCode.FGT:
                comparisonOperator = OperatorStore.FGreaterThanOp;
                break;

            case ConditionCode.GE:
                comparisonOperator = OperatorStore.GreaterThanEqualOp;
                break;

            case ConditionCode.UGE:
                comparisonOperator = OperatorStore.UGreaterThanEqualOp;
                break;

            case ConditionCode.FGE:
                comparisonOperator = OperatorStore.FGreaterThanEqualOp;
                break;

            case ConditionCode.LT:
                comparisonOperator = OperatorStore.LessThanOp;
                break;

            case ConditionCode.ULT:
                comparisonOperator = OperatorStore.ULessThanOp;
                break;

            case ConditionCode.FLT:
                comparisonOperator = OperatorStore.FLessThanOp;
                break;

            case ConditionCode.LE:
                comparisonOperator = OperatorStore.LessThanEqualOp;
                break;

            case ConditionCode.ULE:
                comparisonOperator = OperatorStore.ULessThanEqualOp;
                break;

            case ConditionCode.FLE:
                comparisonOperator = OperatorStore.FLessThanEqualOp;
                break;

            case ConditionCode.EQ:
                comparisonOperator = OperatorStore.EqualOp;
                break;

            case ConditionCode.NE:
                comparisonOperator = OperatorStore.NotEqualOp;
                break;

            default:
                throw new NotImplementedException("PHOENIX: Compare instruction Opcode " +
                                                  "not implemented in symbolic tracer: " + compareInstruction.ToString());
            }

            Operand    srcOp1   = compareInstruction.SourceOperand1;
            Operand    srcOp2   = compareInstruction.SourceOperand2;
            Expression srcExpr1 = TraceOperandBackward(srcOp1, varOperand, path);
            Expression srcExpr2 = TraceOperandBackward(srcOp2, varOperand, path);

            result = new Expression(comparisonOperator, srcExpr1, srcExpr2,
                                    path.Config.WORD_BITSIZE);
            result.Type = compareInstruction.DestinationOperand.Type;

            BranchInstruction branchInstruction = compareInstruction.Next.AsBranchInstruction;

            if (branchInstruction != null)
            {
                if (path.Blocks[path.Blocks.IndexOf(compareInstruction.BasicBlock) + 1] ==
                    branchInstruction.FalseLabelInstruction.BasicBlock)
                {
                    result      = new Expression(OperatorStore.NotOp, result, result.BitSize);
                    result.Type = compareInstruction.DestinationOperand.Type;
                }
            }

            return(result);
        }
Example #18
0
        public IList <IInstruction> ParseAssembly(Stream assembly, int baseAddress)
        {
            var result        = new List <IInstruction>();
            var startPosition = assembly.Position;

            while (assembly.Position < assembly.Length)
            {
                var instructionPosition = (int)(baseAddress + assembly.Position - startPosition);
                var instruction         = ReadUInt32(assembly);
                var condition           = (byte)(instruction >> 28);

                switch (GetInstructionType(instruction))
                {
                case InstructionType.DataProcessing:
                    result.Add(DataProcessingInstructionFactory.Create(instructionPosition, condition,
                                                                       instruction));
                    break;

                case InstructionType.Multiply:
                    // TODO: Implement multiply
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'Multiply'.");
                    break;

                case InstructionType.MultiplyLong:
                    // TODO: Implement Multiply long
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'MultiplyLong'.");
                    break;

                case InstructionType.SingleDataSwap:
                    // TODO: Implement Data swap
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'SingleDataSwap'.");
                    break;

                case InstructionType.BranchExchange:
                    result.Add(BranchAndExchangeInstruction.Parse(instructionPosition, condition, instruction));
                    break;

                case InstructionType.HalfwordDataTransferReg:
                    // TODO: Implement halfword data transfer reg
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'HalfwordDataTransferReg'.");
                    break;

                case InstructionType.HalfwordDataTransferImm:
                    // TODO: Implement halfword data transer imm
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'HalfwordDataTransferImm'.");
                    break;

                case InstructionType.SingleDataTransfer:
                    result.Add(SingleDataTransferInstruction.Parse(instructionPosition, condition, instruction));
                    break;

                case InstructionType.BlockDataTransfer:
                    result.Add(BlockDataTransferInstruction.Parse(instructionPosition, condition, instruction));
                    break;

                case InstructionType.Branch:
                    result.Add(BranchInstruction.Parse(instructionPosition, condition, instruction));
                    break;

                case InstructionType.CoprocessorDataTransfer:
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'CoprocessorDataTransfer'.");
                    break;

                case InstructionType.CoprocessorDataOperation:
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'CoprocessorDataOperation'.");
                    break;

                case InstructionType.CoprocessorRegTransfer:
                    _logger?.Log(LogLevel.Fatal, "Unimplemented Instructiontype 'CoprocessorRegTransfer'.");
                    break;

                case InstructionType.SoftwareInterrupt:
                    result.Add(SvcInstruction.Parse(instructionPosition, condition, instruction));
                    break;

                case InstructionType.Undefined:
                default:
                    throw new UndefinedInstructionException(instruction, instructionPosition);
                }
            }

            return(result);
        }
Example #19
0
 public virtual void Visit(BranchInstruction instruction)
 {
 }                                                                    // { Default(instruction); }
Example #20
0
		public void Read(ref BlobReader reader)
		{
			this.ReadStart();

			while (reader.RemainingBytes > 0)
			{
				int offset = reader.Offset;

				ILOpCode opCode = reader.DecodeILOpCode();
				switch (opCode)
				{
					case ILOpCode.Nop:
						this.Read(NopInstruction.Nop(), offset);
						break;

					case ILOpCode.Ldarg_0:
						this.Read(LoadArgumentInstruction.FromIndex(0), offset);
						break;
					case ILOpCode.Ldarg_1:
						this.Read(LoadArgumentInstruction.FromIndex(1), offset);
						break;

					case ILOpCode.Ldloc_0:
						this.Read(LoadLocalInstruction.FromIndex(0), offset);
						break;
					case ILOpCode.Ldloc_1:
						this.Read(LoadLocalInstruction.FromIndex(1), offset);
						break;

					case ILOpCode.Ldloca_s:
						this.Read(LoadLocalAddressInstruction.FromIndex(reader.ReadSByte()), offset);
						break;

					case ILOpCode.Stloc_0:
						this.Read(StoreLocalInstruction.ToIndex(0), offset);
						break;
					case ILOpCode.Stloc_1:
						this.Read(StoreLocalInstruction.ToIndex(1), offset);
						break;

					case ILOpCode.Ldc_i4_0:
						this.Read(PushInt32Instruction.Constant(0), offset);
						break;
					case ILOpCode.Ldc_i4_1:
						this.Read(PushInt32Instruction.Constant(1), offset);
						break;
					case ILOpCode.Ldc_i4_2:
						this.Read(PushInt32Instruction.Constant(2), offset);
						break;
					case ILOpCode.Ldc_i4_3:
						this.Read(PushInt32Instruction.Constant(3), offset);
						break;
					case ILOpCode.Ldc_i4_s:
						this.Read(PushInt32Instruction.Constant(reader.ReadSByte()), offset);
						break;

					case ILOpCode.Ldc_i4:
						this.Read(PushInt32Instruction.Constant(reader.ReadInt32()), offset);
						break;
					case ILOpCode.Ldc_i8:
						this.Read(PushInt64Instruction.Constant(reader.ReadInt64()), offset);
						break;

					case ILOpCode.Br_s:
						this.Read(BranchInstruction.ILIndex(reader.ReadSByte() + reader.Offset), offset);
						break;
					case ILOpCode.Bgt_s:
						this.Read(BranchGreaterInstruction.ILIndex(reader.ReadSByte() + reader.Offset), offset);
						break;
					case ILOpCode.Brfalse_s:
						this.Read(BranchFalseInstruction.ILIndex(reader.ReadSByte() + reader.Offset), offset);
						break;

					case ILOpCode.Call:
						this.Read(CallInstruction.Handle(reader.ReadInt32()), offset);
						break;

					case ILOpCode.Pop:
						this.Read(PopInstruction.Pop(), offset);
						break;
					case ILOpCode.Ret:
						this.Read(ReturnInstruction.Return(), offset);
						break;

					case ILOpCode.Add:
						this.Read(AddInstruction.Add(), offset);
						break;
					case ILOpCode.Sub:
						this.Read(SubtractInstruction.Subtract(), offset);
						break;

					case ILOpCode.Initobj:
						this.Read(InitObjectInstruction.Handle(reader.ReadInt32()), offset);
						break;

					case ILOpCode.Ldfld:
						this.Read(LoadFieldValueInstruction.Handle(reader.ReadInt32()), offset);
						break;

					case ILOpCode.Stfld:
						this.Read(SaveFieldValueInstruction.Handle(reader.ReadInt32()), offset);
						break;

					default:
						throw new NotSupportedException("Opcode: " + opCode);
				}
			}

			this.ReadEnd();
		}
 protected override void VisitBranchInstruction(BranchInstruction instruction)
 {
     ControlState.Move(instruction.Offset, instruction.Label);
 }