1 2 3 package org.quilt.cl; 4 5 import java.util.*; 6 import org.apache.bcel.generic.*; 7 8 import org.quilt.graph.*; 9 10 22 public class TryStacks { 23 24 private ControlFlowGraph graph = null; 25 private SortedBlocks blox = null; 26 27 private int handlerCount = 0; 28 29 private int index; private int tryStart[]; private int tryEnd[]; private int handlerPC[]; private ObjectType exception[]; 34 private boolean done []; 36 37 private Map tryEndNdx = new HashMap(); 38 39 45 private class CmpHandlers implements Comparator { 46 51 public int compare (Object o1, Object o2) { 52 CodeExceptionGen a = (CodeExceptionGen) o1; 53 CodeExceptionGen b = (CodeExceptionGen) o2; 54 55 int aStart = a.getStartPC().getPosition(); 57 int bStart = b.getStartPC().getPosition(); 58 if (aStart < bStart) { 60 return -1; 61 } else if (aStart > bStart) { 62 return 1; 63 } 64 int aEnd = a.getEndPC().getPosition(); 66 int bEnd = b.getEndPC().getPosition(); 67 if (aEnd < bEnd) { 68 return 1; 69 } else if (aEnd > bEnd) { 70 return -1; 71 } 72 int aHandler = a.getHandlerPC().getPosition(); 74 int bHandler = b.getHandlerPC().getPosition(); 75 if (aHandler < bHandler) { 76 return -1; 77 } else if (aHandler > bHandler) { 78 return 1; 79 } else { 80 return 0; 81 } 82 } 83 } 84 85 96 public TryStacks ( 97 final CodeExceptionGen[] handlers, 98 SortedBlocks blocks, 99 ControlFlowGraph g) { 100 if (handlers == null || blocks == null || g == null) { 101 throw new IllegalArgumentException ("null constructor argument"); 102 } 103 blox = blocks; 104 graph = g; 105 106 handlerCount = handlers.length; 107 if (handlerCount > 0) { 108 tryStart = new int[handlerCount]; 109 tryEnd = new int[handlerCount]; 110 handlerPC = new int[handlerCount]; 111 exception = new ObjectType[handlerCount]; 112 done = new boolean [handlerCount]; 113 114 SortedMap sm = new TreeMap(new CmpHandlers()); 118 for (int i=0; i<handlerCount; i++) { 119 sm.put ( handlers[i], new Integer (i) ); 120 } 121 Iterator it = sm.keySet().iterator(); 122 for (int j = 0; it.hasNext(); j++ ) { 123 Integer iInt = (Integer ) sm.get ( 124 (CodeExceptionGen) it.next() ); 125 int i = iInt.intValue(); 126 tryStart[j] = handlers[i].getStartPC().getPosition(); 127 tryEnd[j] = handlers[i].getEndPC().getPosition(); 128 handlerPC[j] = handlers[i].getHandlerPC().getPosition(); 129 exception[j] = handlers[i].getCatchType(); 130 131 done[j] = false; 132 } 133 Edge edge = graph.getEntry().getEdge(); 134 for (int i = 0; i < handlerCount && !done[i]; ) { 135 ControlFlowGraph sub = handleTry(graph, edge) ; 136 edge = sub.getExit().getEdge(); 137 } 138 } } 140 141 151 private ControlFlowGraph handleTry ( 152 final ControlFlowGraph g, final Edge parentEdge ) { 153 int start = tryStart[index]; 154 int end = tryEnd[index]; 155 if ( parentEdge == null) { 156 throw new IllegalArgumentException ("null edge"); 157 } 158 ControlFlowGraph subgraph = handleTryGroup (g, parentEdge); 160 Vertex subEntry = subgraph.getEntry(); 161 Edge currEdge = subEntry.getEdge(); 162 163 ControlFlowGraph subsub; 165 if ((index < handlerCount) && (tryStart[index] == start)) { 166 subsub = handleTry (subgraph, currEdge); 167 currEdge = subsub.getExit().getEdge(); 168 } else { 169 currEdge = blox.add (tryStart[index - 1], currEdge ).getEdge(); 174 } 175 int nested = 0; 177 while ((index < handlerCount) && (tryStart[index] < end)) { 178 subsub = handleTry (subgraph, currEdge); 179 currEdge = subsub.getExit().getEdge(); 180 } 181 tryEndNdx.put(subgraph, new Integer (start)); 183 return subgraph; 184 } 185 186 194 private ControlFlowGraph handleTryGroup (final ControlFlowGraph parent, 195 final Edge parentEdge) { 196 197 int k = 1; int pos = tryStart[index]; 199 int end = tryEnd[index]; 200 for (int j = index + 1; j < handlerCount 201 && tryStart[j] == pos && tryEnd[j] == end; 202 j++) { 203 k++; 205 } 206 ControlFlowGraph subgraph 208 = (ControlFlowGraph) parent.subgraph (parentEdge, k); 209 Edge currentEdge = subgraph.getExit().getEdge(); 210 211 ComplexConnector conn 213 = (ComplexConnector)subgraph.getEntry().getConnector(); 214 for (int j = 0; j < k; j++) { 215 done[index + j] = true; 216 Edge edge = conn.getEdge(j); 217 CodeVertex v = subgraph.insertCodeVertex (edge); 218 v.setPos (handlerPC[index + j] ); 219 blox.add (v); 221 } 222 index += k; 223 return subgraph; 224 } 225 232 public CatchData [] getCatchData() { 233 CatchData [] cd = new CatchData[tryStart.length]; 234 for (int i = 0; i < tryStart.length; i++) { 235 cd [i] = new CatchData (blox.get(tryStart[i]), blox.get(tryEnd[i]), 236 blox.get(handlerPC[i]), exception[i] ); 237 } 238 return cd; 239 } 240 245 public Comparator getComparator() { 246 return new CmpHandlers(); 247 } 248 255 int getEndTry (final ControlFlowGraph graph) { 256 if (tryEndNdx.containsKey(graph)) { 257 Integer i = (Integer )tryEndNdx.get(graph); 258 return i.intValue(); 259 } 260 return -1; 261 } 262 266 public String toString() { 267 String s = ""; 268 if (handlerCount > 0) { 269 s = " index start end handler pc\n"; 271 for (int i = 0; i < handlerCount; i++) { 272 s += " " + i + " [" + tryStart[i] 273 + ".." + tryEnd[i] 274 + "] --> " + handlerPC[i] + "\n"; 275 } 276 } 277 return s; 278 } 279 } 280 | Popular Tags |