1
2
3
4 package joeq.Compiler.BytecodeAnalysis;
5
6 import jwutil.util.Assert;
7
8 /***
9 * A basic block in terms of bytecode indices.
10 *
11 * @author John Whaley <jwhaley@alum.mit.edu>
12 * @version $Id: BasicBlock.java 2282 2005-05-28 11:14:27Z joewhaley $
13 */
14 public class BasicBlock {
15
16 /***
17 * ID number.
18 */
19 public final int id;
20
21 /***
22 * Start index of basic block.
23 */
24 final int start;
25
26 /***
27 * End index of basic block.
28 */
29 int end;
30
31 /***
32 * Predecessors of this basic block.
33 */
34 BasicBlock[] predecessors;
35
36 /***
37 * Successors of this basic block.
38 */
39 BasicBlock[] successors;
40
41 /***
42 * Set of exception handlers for this basic block.
43 */
44 ExceptionHandlerList exception_handler_set;
45
46 /***
47 * Starting stack depth of this basic block.
48 */
49 int startingStackDepth;
50
51 /***
52 * Whether this basic block ends in a ret.
53 */
54 boolean isSubroutineRet;
55
56 /***
57 * Construct a new basic block. Only to be called by ControlFlowGraph.
58 *
59 * @param id
60 * @param start
61 */
62 BasicBlock(int id, int start) {
63 this.id = id; this.start = start;
64 }
65
66 public int getStart() { return start; }
67 public int getEnd() { return end; }
68
69 public int getNumberOfPredecessors() { return predecessors.length; }
70 public int getNumberOfSuccessors() { return successors.length; }
71 public BasicBlock getPredecessor(int i) { return predecessors[i]; }
72 public BasicBlock getSuccessor(int i) { return successors[i]; }
73 public boolean isSubroutineRet() { return isSubroutineRet; }
74 void setSubroutineRet(ControlFlowGraph cfg, BasicBlock jsub_bb) {
75 isSubroutineRet = true;
76 Assert._assert(this.successors.length == 0);
77 this.successors = new BasicBlock[jsub_bb.predecessors.length];
78 for (int i=0; i<this.successors.length; ++i) {
79 int ret_target_index = jsub_bb.predecessors[i].id + 1;
80 Assert._assert(ret_target_index < cfg.getNumberOfBasicBlocks());
81 BasicBlock ret_target = cfg.getBasicBlock(ret_target_index);
82 this.successors[i] = ret_target;
83 BasicBlock[] new_pred = new BasicBlock[ret_target.predecessors.length+1];
84 if (ret_target.predecessors.length != 0) {
85 System.arraycopy(ret_target.predecessors, 0, new_pred, 0, ret_target.predecessors.length);
86 }
87 new_pred[ret_target.predecessors.length] = this;
88 ret_target.predecessors = new_pred;
89 }
90 }
91
92 public ExceptionHandlerIterator getExceptionHandlers() {
93 if (exception_handler_set == null) return ExceptionHandlerIterator.nullIterator();
94 return exception_handler_set.iterator();
95 }
96
97 void addExceptionHandler_first(ExceptionHandlerList eh) {
98 Assert._assert(eh.parent == null);
99 eh.parent = this.exception_handler_set;
100 this.exception_handler_set = eh;
101 }
102 ExceptionHandlerList addExceptionHandler(ExceptionHandlerList eh) {
103 if (eh.parent == this.exception_handler_set)
104 return this.exception_handler_set = eh;
105 else
106 return this.exception_handler_set = new ExceptionHandlerList(eh.getHandler(), this.exception_handler_set);
107 }
108
109 public String toString() { return "BB"+id+" ("+start+"-"+end+")"; }
110 }