OSDN Git Service

コントロールフローを抽出可能にした.
[stigmata/stigmata-plugins.git] / opcodes / src / main / java / jp / sourceforge / stigmata / birthmarks / BasicBlock.java
1 package jp.sourceforge.stigmata.birthmarks;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collections;\r
5 import java.util.HashSet;\r
6 import java.util.Iterator;\r
7 import java.util.List;\r
8 import java.util.Set;\r
9 \r
10 import org.objectweb.asm.Label;\r
11 import org.objectweb.asm.tree.AbstractInsnNode;\r
12 import org.objectweb.asm.tree.InsnNode;\r
13 \r
14 public class BasicBlock {\r
15     private Set<BasicBlock> nexts = new HashSet<BasicBlock>();\r
16     private List<Opcode> opcodes = new ArrayList<Opcode>();\r
17     private Set<BasicBlock> prevs = new HashSet<BasicBlock>();\r
18 \r
19     BasicBlock(){\r
20     }\r
21 \r
22     public BasicBlock(InsnNode[] nodeArray){\r
23         for(InsnNode node: nodeArray){\r
24             addNode(node);\r
25         }\r
26     }\r
27 \r
28     void addNode(AbstractInsnNode node){\r
29         OpcodeManager manager = OpcodeManager.getInstance();\r
30         Opcode opcode = manager.getOpcode(node);\r
31         if(opcode != null){\r
32             addNode(opcode);\r
33         }\r
34     }\r
35 \r
36     void addNode(Opcode opcode){\r
37         opcodes.add(opcode);\r
38     }\r
39 \r
40     public Opcode getOpcode(int index){\r
41         return opcodes.get(index);\r
42     }\r
43 \r
44     public int getSize(){\r
45         return opcodes.size();\r
46     }\r
47 \r
48     public Label[] getTargets(){\r
49         Set<Label> targets = new HashSet<Label>();\r
50         for(Opcode opcode: opcodes){\r
51             if(opcode.getCategory() != Opcode.Category.TARGETER){\r
52                 Label[] labels = opcode.getLabels();\r
53                 for(Label label: labels){\r
54                     targets.add(label);\r
55                 }\r
56             }\r
57         }\r
58 \r
59         return targets.toArray(new Label[targets.size()]);\r
60     }\r
61 \r
62     public boolean hasLabel(Label label){\r
63         boolean flag = false;\r
64         for(Opcode opcode: opcodes){\r
65             if(flag || opcode.hasLabel(label)){\r
66                 flag = true;\r
67             }\r
68         }\r
69         return flag;\r
70     }\r
71 \r
72     public boolean isEmpty(){\r
73         return opcodes.size() == 0;\r
74     }\r
75 \r
76     public Iterator<BasicBlock> nextIterator(){\r
77         return Collections.unmodifiableSet(nexts).iterator();\r
78     }\r
79 \r
80     public Iterator<BasicBlock> previousIterator(){\r
81         return Collections.unmodifiableSet(prevs).iterator();\r
82     }\r
83 \r
84     public void setNext(BasicBlock block){\r
85         block.prevs.add(this);\r
86         nexts.add(block);\r
87     }\r
88 \r
89     public void setPrev(BasicBlock block){\r
90         block.nexts.add(this);\r
91         prevs.add(block);\r
92     }\r
93 \r
94     /*\r
95     public String toString(){\r
96         StringBuilder sb = new StringBuilder("---- block ----");\r
97         String ln = System.getProperty("line.separator");\r
98         for(Opcode opcode: opcodes){\r
99             sb.append(ln).append(opcode);\r
100         }\r
101         Label[] targets = getTargets();\r
102         sb.append(ln).append("Targeter: ");\r
103         for(Label label: targets){\r
104             sb.append(label).append(", ");\r
105         }\r
106         return new String(sb);\r
107     }\r
108     */\r
109 }\r