private static bool CanThrowException(OpCode opcode) { if (opcode.OpCodeType == OpCodeType.Prefix) { return(false); } return(OpCodeInfo.Get(opcode).CanThrow); }
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()); } } } } }