1 2 3 package org.quilt.cl; 4 5 import java.util.HashMap ; 6 import java.util.HashSet ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 import java.util.Set ; 11 import java.util.Vector ; 12 13 import org.apache.bcel.classfile.*; 14 import org.apache.bcel.generic.*; 15 16 import org.quilt.graph.*; 17 18 29 30 public class BytecodeCollector implements org.quilt.graph.Visitor { 31 32 private ControlFlowGraph graph = null; 33 34 private Map startHandles = null; 35 private Map endHandles = null; 36 private Map gotoFixMeUps = null; 37 private InstructionList ilist = null; 38 39 40 public BytecodeCollector() { } 41 42 46 public void discoverGraph( Directed g ) { 47 graph = (ControlFlowGraph) g; 48 ilist = graph.getInstructionList(); 49 startHandles = graph.getStartHandles(); 50 endHandles = graph.getEndHandles(); 51 gotoFixMeUps = graph.getGotoFixMeUps(); 52 } 53 67 public void discoverVertex(Vertex vtx) { 68 if (vtx == null) { 69 throw new IllegalArgumentException ("null vertex"); 70 } 71 if (! (vtx instanceof Entry || vtx instanceof Exit) ) { 73 CodeVertex v = (CodeVertex) vtx; 74 InstructionList vIList = v.getInstructionList(); 75 InstructionHandle vStart = null; 76 77 if (vIList.size() == 0) { 78 vIList = new InstructionList ( new NOP() ); 79 } 80 vStart = ilist.append(vIList); if (vStart == null) { 82 System.out.println("discoverVertex INTERNAL ERROR: vertex " 83 + v + " has null position in bytecode\n"); 84 } 85 if (vStart == null) { 88 System.out.println(" ** vStart is null **"); 89 } 90 startHandles.put(v, vStart); 93 Instruction inst = v.getConnInst(); 94 if (inst != null) { 95 if (inst instanceof GotoInstruction) { 97 BranchHandle bh = ilist.append ((GotoInstruction)inst); 98 endHandles.put (v, bh); 99 } else if (inst instanceof IfInstruction) { 100 BranchHandle bh = ilist.append((IfInstruction) inst); 101 endHandles.put (v, bh); 102 } else if ( inst instanceof JsrInstruction ) { 103 BranchHandle bh = ilist.append((JsrInstruction) inst); 104 endHandles.put (v, bh); 105 } else if ( inst instanceof Select) { 106 BranchHandle bh = ilist.append((Select) inst); 107 endHandles.put (v, bh ); 108 } else if ( (inst instanceof ExceptionThrower) 109 || (inst instanceof ReturnInstruction) 110 || (inst instanceof RET) 111 || (inst instanceof InvokeInstruction) ) { 112 InstructionHandle ih = ilist.append(inst); 113 endHandles.put (v, ih ); 114 } else { 115 ilist.append(inst); 116 } 117 } 118 } 119 } 120 121 125 public void discoverEdge( Edge e ) { 126 } 127 128 133 public void finishEdge( Edge e ) { 134 } 135 136 146 private CodeVertex getEffectiveTarget (final Edge e) { 147 Vertex target = e.getTarget(); 148 while (target != null 153 && (target instanceof Entry || target instanceof Exit) ) { 154 158 target = target.getTarget(); 159 160 } 162 return (CodeVertex) target; 166 } 167 181 public void finishVertex( Vertex vtx ) { 182 if (vtx instanceof CodeVertex) { 183 CodeVertex v = (CodeVertex) vtx; 184 Instruction inst = v.getConnInst(); 185 if (inst != null) { 186 if ( inst instanceof GotoInstruction ) { 187 CodeVertex effTarget = getEffectiveTarget( 199 ((BinaryConnector)v.getConnector()).getOtherEdge()); 200 InstructionHandle target 201 = (InstructionHandle) startHandles.get(effTarget); 202 gotoFixMeUps.put (v, effTarget); 204 } else if ( inst instanceof IfInstruction ) { 205 Edge workingEdge 206 = ((BinaryConnector)v.getConnector()).getOtherEdge(); 207 InstructionHandle target 208 = (InstructionHandle) startHandles.get( 209 getEffectiveTarget(workingEdge)); 210 BranchHandle bh = (BranchHandle) endHandles.get(v); 211 bh.setTarget(target); 212 213 } else if ( inst instanceof JsrInstruction ) { 214 InstructionHandle target 215 = (InstructionHandle) startHandles.get( 216 getEffectiveTarget(v.getEdge())); 217 BranchHandle bh = (BranchHandle) endHandles.get(v); 218 bh.setTarget(target); 219 220 } else if (inst instanceof Select) { 221 InstructionHandle target 223 = (InstructionHandle) startHandles.get( 224 getEffectiveTarget(v.getEdge())); 225 BranchHandle bh = (BranchHandle) endHandles.get(v); 234 bh.setTarget(target); 235 236 ComplexConnector conn = (ComplexConnector)v.getConnector(); 238 int edgeCount = conn.size(); 239 InstructionHandle[] targets = new InstructionHandle[edgeCount]; 240 for (int i = 0; i < edgeCount; i++) { 241 target = (InstructionHandle) startHandles.get( 242 getEffectiveTarget(conn.getEdge(i))); 243 if (target == null) { 245 System.out.println( 246 "BytecodeCollector.finishVertex " 247 + v + " INTERNAL ERROR: \n" 248 + " " + inst + " has null target " + i); 249 } 250 ((Select)bh.getInstruction()).setTarget(i, target); 252 } 253 } 254 } 255 } 256 } 257 258 261 private void dumpIList(String where) { 262 System.out.println("BytecodeCollector." 263 + where + " instruction list:"); 264 int i = 0; 265 for (InstructionHandle ih = ilist.getStart(); ih != null; 266 ih = ih.getNext() ) { 267 System.out.println( " " + (i++) + " " + ih.getInstruction()); 268 } 269 } 270 275 public void finishGraph( Directed g ) { 276 277 } 278 279 286 public InstructionList getInstructionList() { 287 Iterator k = gotoFixMeUps.keySet().iterator(); 289 while (k.hasNext()) { 290 CodeVertex v = (CodeVertex) k.next(); 291 BranchHandle bh = (BranchHandle) endHandles.get(v); 293 InstructionHandle target 295 = (InstructionHandle) startHandles.get( 296 gotoFixMeUps.get (v)); 297 bh.setTarget(target); } 299 ilist.update(); 301 return ilist; 303 } 304 305 314 public CodeExceptionGen[] getCEGs ( CatchData[] cd) { 315 CodeExceptionGen [] ceg; 316 if (cd == null) { 317 ceg = new CodeExceptionGen[ 0 ]; 318 } else { 319 ceg = new CodeExceptionGen[ cd.length ]; 320 for (int i = 0; i < cd.length; i++) { 321 InstructionHandle start 322 = (InstructionHandle) startHandles.get(cd[i].tryStart); 323 InstructionHandle end 324 = (InstructionHandle) startHandles.get(cd[i].tryEnd); 325 InstructionHandle handler 326 = (InstructionHandle) startHandles.get(cd[i].handlerPC); 327 if ( start == null || end == null || handler == null) { 328 System.out.println ( 329 "BytecodeCollector.getCEGs: INTERNAL ERROR - null handler\n" 330 + " CatchData[" + i + "] start: " + cd[i].tryStart 331 + " end: " + cd[i].tryEnd + " handler at: " 332 + cd[i].handlerPC); 333 } 334 ceg[i] = new CodeExceptionGen( start, end, handler, 335 cd[i].exception ); 336 } 337 } 338 return ceg; 339 } 340 } 341 | Popular Tags |