1 package jp.sourceforge.stigmata.birthmarks;
\r
3 import java.util.ArrayList;
\r
4 import java.util.HashSet;
\r
5 import java.util.List;
\r
6 import java.util.Set;
\r
8 import org.objectweb.asm.tree.AbstractInsnNode;
\r
9 import org.objectweb.asm.tree.JumpInsnNode;
\r
10 import org.objectweb.asm.tree.LabelNode;
\r
11 import org.objectweb.asm.tree.LookupSwitchInsnNode;
\r
12 import org.objectweb.asm.tree.MethodNode;
\r
13 import org.objectweb.asm.tree.TableSwitchInsnNode;
\r
14 import org.objectweb.asm.tree.TryCatchBlockNode;
\r
16 public class ControlFlowGraph {
\r
17 private String name;
\r
18 private boolean includeException;
\r
19 private MethodNode method;
\r
20 private BasicBlock[] blocks;
\r
22 public ControlFlowGraph(String name, MethodNode node){
\r
23 this(name, node, false);
\r
26 public ControlFlowGraph(String name, MethodNode node, boolean includeException){
\r
27 this.includeException = includeException;
\r
33 public String getName(){
\r
37 public int getBasicBlockSize(){
\r
38 return blocks.length;
\r
41 public boolean isIncludingExceptionFlow(){
\r
42 return includeException;
\r
45 public void setIncludingExceptionFlow(boolean includeException){
\r
46 boolean oldvalue = this.includeException;
\r
47 this.includeException = includeException;
\r
48 if(oldvalue != includeException){
\r
53 private void separateBasicBlock(MethodNode node){
\r
54 Set<LabelNode> jumpedTarget = new HashSet<LabelNode>();
\r
55 int size = node.instructions.size();
\r
57 for(int i = 0; i < size; i++){
\r
58 AbstractInsnNode inst = node.instructions.get(i);
\r
59 switch(inst.getType()){
\r
60 case AbstractInsnNode.JUMP_INSN:
\r
61 jumpedTarget.add(((JumpInsnNode)inst).label);
\r
63 case AbstractInsnNode.LOOKUPSWITCH_INSN:
\r
65 LookupSwitchInsnNode lookup = (LookupSwitchInsnNode)inst;
\r
66 jumpedTarget.add(lookup.dflt);
\r
67 for(Object label: lookup.labels){
\r
68 jumpedTarget.add((LabelNode)label);
\r
71 case AbstractInsnNode.TABLESWITCH_INSN:
\r
73 TableSwitchInsnNode lookup = (TableSwitchInsnNode)inst;
\r
74 jumpedTarget.add(lookup.dflt);
\r
75 for(Object label: lookup.labels){
\r
76 jumpedTarget.add((LabelNode)label);
\r
81 if(isIncludingExceptionFlow()){
\r
82 for(Object object: node.tryCatchBlocks){
\r
83 jumpedTarget.add(((TryCatchBlockNode)object).handler);
\r
87 List<BasicBlock> blockList = new ArrayList<BasicBlock>();
\r
88 BasicBlock block = new BasicBlock();
\r
89 for(int i = 0; i < size; i++){
\r
90 AbstractInsnNode inst = node.instructions.get(i);
\r
91 if(jumpedTarget.contains(inst)){
\r
92 blockList.add(block);
\r
93 block = new BasicBlock();
\r
96 block.addNode(inst);
\r
98 if(inst.getType() == AbstractInsnNode.JUMP_INSN
\r
99 || inst.getType() == AbstractInsnNode.TABLESWITCH_INSN
\r
100 || inst.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN){
\r
101 blockList.add(block);
\r
102 block = new BasicBlock();
\r
105 this.blocks = blockList.toArray(new BasicBlock[blockList.size()]);
\r
109 *
\83R
\83\93\83g
\83\8d\81[
\83\8b\83t
\83\8d\81[
\83O
\83\89\83t
\82ð
\8dì
\90¬
\82·
\82é
\81D
\r
111 private void parse(MethodNode node){
\r
112 separateBasicBlock(node);
\r