View Javadoc
1 /* CodeVertex.java */ 2 package org.quilt.cl; 3 4 import org.quilt.graph.*; 5 import org.apache.bcel.generic.GotoInstruction; 6 import org.apache.bcel.generic.Instruction; 7 import org.apache.bcel.generic.InstructionHandle; 8 import org.apache.bcel.generic.InstructionList; 9 10 /*** 11 * A Vertex extended to carry the initial bytecode offset, line 12 * number, and an instruction list. 13 * 14 * @author <a href="mailto:jddixon@users.sourceforge.net">Jim Dixon</a> 15 */ 16 public class CodeVertex extends Vertex { 17 /*** initial offset of first instruction in bytecode */ 18 protected int pos = -1; 19 20 /*** the bytecode iteself */ 21 protected InstructionList ilist = new InstructionList(); 22 23 /*** 24 * Line number in source code corresponding to first instruction, 25 * or if there is no such instruction, of the connecting instruction. 26 */ 27 protected int startLine_ = -1; 28 29 /*** 30 * Line number in source code corresponding to the connecting 31 * instruction, or if there is no such instruction, to the last 32 * instruction in the block 33 */ 34 protected int endLine_ = -1; 35 36 /*** Instruction connecting this vertex to other(s). */ 37 protected Instruction connInst_ = null; 38 39 /*** 40 * Create a code vertex with default bytecode offset, line number, 41 * empty instruction list, and no label. 42 * 43 * @param g Graph which the vertex belongs to. 44 */ 45 public CodeVertex (ControlFlowGraph g) { 46 super(g); 47 } 48 /*** Create a code vertex, specifying a non-negative bytecode offset. 49 * 50 * @param g Graph which the vertex belongs to. 51 * @param position Offset of the first instruction in the bytecode. 52 */ 53 public CodeVertex (ControlFlowGraph g, int position) { 54 super(g); 55 if (position < 0) { 56 throw new IllegalArgumentException( 57 "position cannot be negative"); 58 } 59 pos = position; 60 } 61 /*** 62 * Create a code vertex, specifying a label 63 * 64 * @param g Graph which the vertex belongs to. 65 * @param l The String label applied to the vertex. 66 */ 67 public CodeVertex (ControlFlowGraph g, String l) { 68 super(g); 69 pos = -1; 70 label_ = l; 71 } 72 // GET/SET METHODS ////////////////////////////////////////////// 73 /*** Get connecting instruction. */ 74 public Instruction getConnInst() { 75 return connInst_; 76 } 77 /*** Set the connecting instruction for this vertex. */ 78 public void setConnInst (Instruction i) { 79 if (i == null) { 80 throw new IllegalArgumentException ("null instruction"); 81 } 82 connInst_ = i; 83 } 84 // /*** Set the connecting instruction to null. */ 85 // public void clearConnInst () { 86 // connInst_ = null; 87 // } 88 /*** 89 * Get a reference to the InstructionList carried by the vertex. 90 * This is a doubly indirect reference to the first instruction 91 * in the list. 92 * 93 * @return Instruction list. 94 */ 95 public InstructionList getInstructionList() { 96 return ilist; 97 } 98 /*** 99 * Get the source code line number of the first instruction in a 100 * code vertex. 101 * 102 * @return Non-negative integer or -1, meaning no line number assigned. 103 */ 104 public int getStartLine () { 105 return startLine_; 106 } 107 /*** 108 * Set the source code line number. 109 * @param n Source code line number. 110 */ 111 public void setStartLine(int n) { 112 startLine_ = n; 113 } 114 /*** 115 * Get the line number in source code corresponding to the 116 * connecting instruction or last instruction in the block. 117 */ 118 public int getEndLine() { 119 return endLine_; 120 } 121 /*** 122 * Set the source line number of the connecting instruction, or of 123 * the last line number in the block if there is no connecting 124 * instruction. 125 * 126 * @param n Source code end line number. 127 */ 128 public void setEndLine(int n) { 129 endLine_ = n; 130 } 131 /*** 132 * Get the bytecode offset of the first instruction. 133 * 134 * @return The initial bytecode offset of the first instruction 135 * carried by the vertex (excluding any connection instruction. 136 */ 137 public int getPosition () { 138 return pos; 139 } 140 /*** 141 * Set the bytecode offset for the first instruction. 142 * 143 * XXX Should rename this to <code>setPosition</code> to match the 144 * <code>get</code> method. 145 * 146 * @param position A non-negative integer representing the bytecode 147 * position of the first instruction. 148 */ 149 public void setPos (int position) { 150 if (position < 0) { 151 throw new IllegalArgumentException( 152 "position cannot be negative"); 153 } 154 pos = position; 155 } 156 // OTHER METHODS //////////////////////////////////////////////// 157 /*** 158 * Move this code vertex's Goto to another code vertex. The 159 * second vertex will be the target on the otherEdge from this 160 * vertex. This vertex has a BinaryConnector. The second vertex 161 * has a UnaryConnector. 162 * 163 * The goto instruction does NOT point to the target. The target 164 * is some sort of instrumentation being inserted into the graph. 165 */ 166 public void moveGoto (final CodeVertex target) { 167 if (target == null) { 168 throw new IllegalArgumentException("null target vertex"); 169 } 170 // this vertex's binary connector 171 BinaryConnector biConnector = (BinaryConnector)getConnector(); 172 Edge flowEdge = biConnector.getEdge(); 173 Edge otherEdge = biConnector.getOtherEdge(); // used by goto 174 175 if (otherEdge.getTarget() != target) { 176 throw new IllegalArgumentException("not target of otherEdge"); 177 } 178 if (! (connInst_ instanceof GotoInstruction) ) { 179 throw new IllegalArgumentException( 180 "connecting instruction not goto"); 181 } 182 // the target vertex's unary connector 183 UnaryConnector uConnector = (UnaryConnector)target.getConnector(); 184 Edge uEdge = uConnector.getEdge(); 185 Vertex tgtTarget = uEdge.getTarget(); 186 187 // // DEBUG 188 // System.out.println("CodeVertex.moveGoto:" 189 // + "\n source: " + toString() 190 // + "\n edge: " + flowEdge 191 // + "\n other edge: " + otherEdge 192 // + "\n target: " + target 193 // + "\n edge: " + uEdge 194 // ); 195 // // END 196 197 // change the unary connector and move it to this vertex 198 uEdge.setSource(this); 199 uEdge.setTarget(target); 200 setConnector(uConnector); 201 202 // change the binary connector and attach it to the target 203 flowEdge.setSource(target); 204 // flow target is unchanged 205 otherEdge.setSource(target); 206 otherEdge.setTarget(tgtTarget); 207 target.setConnector(biConnector); 208 209 // move the connecting instruction, a goto 210 target.setConnInst (connInst_); // move it to the target 211 connInst_ = null; // erase from this vertex 212 213 // // DEBUG 214 // System.out.println("CodeVertex.moveGoto:" 215 // + "\n source: " + toString() 216 // + "\n edge " + getEdge() 217 // + "\n target: " + target 218 // + "\n edge " + flowEdge 219 // + "\n other edge " + otherEdge ); 220 // // END 221 } 222 /*** 223 * Less verbose <code>toString.</code> 224 * 225 * @return Graph index and Vertex index in a neatly formatted String, 226 * *not* newline-terminated. 227 */ 228 public String toString () { 229 StringBuffer sb = new StringBuffer().append("Code ") 230 .append(super.toString()).append(" pos ") .append(pos); 231 232 // may look a bit strange if there is an end line but no start line 233 if (startLine_ > -1) { 234 sb.append(" line ").append(startLine_); 235 } 236 if (endLine_ > -1) { 237 sb.append("/").append(endLine_); 238 } 239 return sb.toString(); 240 } 241 /*** 242 * Optionally more verbose method. 243 * 244 * @param b If true, add label (if any) and instruction list. 245 * @return A neatly formatted String. 246 */ 247 public String toString (boolean b) { 248 249 StringBuffer sb = new StringBuffer().append(toString()); 250 if (b) { 251 if (label_ != null) { 252 sb.append ("\n label ") .append(label_); 253 } 254 sb.append("\n ilist: "); 255 InstructionHandle ih = ilist.getStart(); 256 while ( ih != null) { 257 sb.append(ih.getInstruction()); 258 } 259 } 260 return sb.toString(); 261 } 262 }

This page was automatically generated by Maven