View Javadoc

1   // BasicBlock.java, created Fri Jan 11 16:49:00 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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 }