1 package jp.sourceforge.stigmata.birthmarks;
\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
10 import org.objectweb.asm.Label;
\r
11 import org.objectweb.asm.Opcodes;
\r
12 import org.objectweb.asm.tree.AbstractInsnNode;
\r
13 import org.objectweb.asm.tree.InsnNode;
\r
20 public class BasicBlock {
\r
21 private Set<BasicBlock> nexts = new HashSet<BasicBlock>();
\r
22 private List<Opcode> opcodes = new ArrayList<Opcode>();
\r
23 private Set<BasicBlock> prevs = new HashSet<BasicBlock>();
\r
24 Set<Label> exceptionFlows = new HashSet<Label>();
\r
29 public BasicBlock(InsnNode[] nodeArray){
\r
30 for(InsnNode node: nodeArray){
\r
35 void addNode(AbstractInsnNode node){
\r
36 OpcodeManager manager = OpcodeManager.getInstance();
\r
37 Opcode opcode = manager.getOpcode(node);
\r
43 void addNode(Opcode opcode){
\r
44 opcodes.add(opcode);
\r
47 public Opcode getOpcode(int index){
\r
48 return opcodes.get(index);
\r
51 public int getSize(){
\r
52 return opcodes.size();
\r
55 public Label[] getTargets(){
\r
56 Set<Label> targets = new HashSet<Label>();
\r
57 for(Opcode opcode: opcodes){
\r
58 if(opcode.getCategory() != Opcode.Category.TARGETER){
\r
59 Label[] labels = opcode.getLabels();
\r
60 for(Label label: labels){
\r
65 for(Label label: exceptionFlows){
\r
69 return targets.toArray(new Label[targets.size()]);
\r
72 public boolean hasLabel(Label label){
\r
73 boolean flag = false;
\r
74 for(Opcode opcode: opcodes){
\r
75 if(flag || opcode.hasLabel(label)){
\r
82 public boolean isEmpty(){
\r
83 return opcodes.size() == 0;
\r
86 public Iterator<BasicBlock> nextIterator(){
\r
87 return Collections.unmodifiableSet(nexts).iterator();
\r
90 public Iterator<BasicBlock> previousIterator(){
\r
91 return Collections.unmodifiableSet(prevs).iterator();
\r
94 public void setNext(BasicBlock block){
\r
95 block.prevs.add(this);
\r
99 public void setPrev(BasicBlock block){
\r
100 block.nexts.add(this);
\r
104 public String toString(){
\r
105 StringBuilder sb = new StringBuilder("---- block ----");
\r
106 String ln = System.getProperty("line.separator");
\r
107 for(Opcode opcode: opcodes){
\r
108 sb.append(ln).append(opcode);
\r
110 sb.append(ln).append("Targeter: ");
\r
111 for(Label label: getTargets()){
\r
112 sb.append(label).append(", ");
\r
114 return new String(sb);
\r
117 public boolean isFlowNext(){
\r
118 Opcode opcode = getOpcode(getSize() - 1);
\r
119 int op = opcode.getOpcode();
\r
121 return op != Opcodes.GOTO && op != Opcodes.RETURN
\r
122 && op != Opcodes.RET && op != Opcodes.ATHROW;
\r