Additional info about opcodes.
예제 #1
0
 private static bool CanThrowException(OpCode opcode)
 {
     if (opcode.OpCodeType == OpCodeType.Prefix)
     {
         return(false);
     }
     return(OpCodeInfo.Get(opcode).CanThrow);
 }
예제 #2
0
        private void CreateRegularControlFlow()
        {
            CreateEdge(entryPoint, methodBody.Instructions[0], JumpType.Normal);
            foreach (ControlFlowNode node in nodes)
            {
                if (node.End != null)
                {
                    // create normal edges from one instruction to the next
                    if (!OpCodeInfo.IsUnconditionalBranch(node.End.OpCode))
                    {
                        CreateEdge(node, node.End.Next, JumpType.Normal);
                    }

                    // create edges for branch instructions
                    if (node.End.OpCode.OperandType == OperandType.InlineBrTarget || node.End.OpCode.OperandType == OperandType.ShortInlineBrTarget)
                    {
                        if (node.End.OpCode == OpCodes.Leave || node.End.OpCode == OpCodes.Leave_S)
                        {
                            var handlerBlock = FindInnermostHandlerBlock(node.End.Offset);
                            if (handlerBlock.NodeType == ControlFlowNodeType.FinallyOrFaultHandler)
                            {
                                CreateEdge(node, (Instruction)node.End.Operand, JumpType.LeaveTry);
                            }
                            else
                            {
                                CreateEdge(node, (Instruction)node.End.Operand, JumpType.Normal);
                            }
                        }
                        else
                        {
                            CreateEdge(node, (Instruction)node.End.Operand, JumpType.Normal);
                        }
                    }
                    else if (node.End.OpCode.OperandType == OperandType.InlineSwitch)
                    {
                        foreach (Instruction i in (Instruction[])node.End.Operand)
                        {
                            CreateEdge(node, i, JumpType.Normal);
                        }
                    }

                    // create edges for return instructions
                    if (node.End.OpCode.FlowControl == FlowControl.Return)
                    {
                        switch (node.End.OpCode.Code)
                        {
                        case Code.Ret:
                            CreateEdge(node, regularExit, JumpType.Normal);
                            break;

                        case Code.Endfinally:
                            ControlFlowNode handlerBlock = FindInnermostHandlerBlock(node.End.Offset);
                            if (handlerBlock.EndFinallyOrFaultNode == null)
                            {
                                throw new InvalidProgramException("Found endfinally in block " + handlerBlock);
                            }
                            CreateEdge(node, handlerBlock.EndFinallyOrFaultNode, JumpType.Normal);
                            break;

                        default:
                            throw new NotSupportedException(node.End.OpCode.ToString());
                        }
                    }
                }
            }
        }