public void transfer(BasicBlock basicBlock, InstructionHandle end, BlockType start, BlockType result) throws DataflowAnalysisException { result.copyFrom(start); if (start.isValid()) { if (basicBlock.isExceptionHandler()) { CodeExceptionGen exceptionGen = basicBlock.getExceptionGen(); ObjectType catchType = exceptionGen.getCatchType(); if (catchType == null) { // Probably a finally block, or a synchronized block // exception-compensation catch block. result.pushFinally(); } else { // Catch type was explicitly specified: // this is probably a programmer-written catch block result.pushCatch(); } } } }
SpawnTableEntry(SpawnTableEntry orig, MethodGen mg, MethodGen origM) { isLocalUsed = new boolean[origM.getMaxLocals()]; hasInlet = orig.hasInlet; if (hasInlet) { /* copy and rewite exception table */ CodeExceptionGen origE[] = origM.getExceptionHandlers(); CodeExceptionGen newE[] = mg.getExceptionHandlers(); catchBlocks = new ArrayList<CodeExceptionGen>(); for (int i = 0; i < orig.catchBlocks.size(); i++) { CodeExceptionGen origCatch = orig.catchBlocks.get(i); for (int j = 0; j < origE.length; j++) { if (origCatch == origE[j]) { catchBlocks.add(newE[j]); break; } } } } }
CodeExceptionGen getExceptionHandler(MethodGen m, InstructionHandle self) { CodeExceptionGen exc[] = m.getExceptionHandlers(); for (int j = 0; j < exc.length; j++) { InstructionHandle h = exc[j].getStartPC(); InstructionHandle h2 = exc[j].getEndPC(); do { if (h == self) { return exc[j]; } h = h.getNext(); } while (h != h2); if (h == self) { return exc[j]; } } return null; }
private ArrayList<CodeExceptionGen> getExceptionHandlers(InstructionHandle ih, MethodGen spawnSignature) { CodeExceptionGen[] codeExceptions = getExceptionHandlers(); ArrayList<CodeExceptionGen> result = new ArrayList<CodeExceptionGen>(); for (CodeExceptionGen codeException : codeExceptions) { // codeException.containsTarget has a BUG???? /* if (codeException.containsTarget(ih) && hasRightType(codeException, spawnSignature)) { result.add(codeException); } */ if (Util.containsTarget(codeException, ih) && hasRightType(codeException, spawnSignature)) { result.add(codeException); } } return result; }
private SpawnableCall getSpawnableCallWithException(InstructionHandle invokeInstruction, ArrayList<CodeExceptionGen> exceptionHandlers) { ArrayList<LocalVariableGen> resultIndices = new ArrayList<LocalVariableGen>(); for (CodeExceptionGen exceptionHandler : exceptionHandlers) { InstructionHandle start = exceptionHandler.getHandlerPC(); InstructionHandle end = getEndExceptionHandler(exceptionHandler); getIndicesStores(start, end, resultIndices); } LocalVariableGen[] dummy = new LocalVariableGen[resultIndices.size()]; return new SpawnableCall(invokeInstruction, getObjectReferenceLoadInstruction(invokeInstruction), resultIndices.toArray(dummy)); }
/** Returns the end of an exception handler. * * @param codeException The codeException which end is returned. * @return The instructionHandle that is the end of the exception handler. */ public InstructionHandle getEndExceptionHandler(CodeExceptionGen codeException) { LocalVariableGen[] localVars = getLocalVariables(); InstructionHandle startHandler = codeException.getHandlerPC(); for (LocalVariableGen localVar : localVars) { InstructionHandle startScope = localVar.getStart(); InstructionHandle endScope = localVar.getEnd(); if (startScope == startHandler || startScope == startHandler.getNext() || startScope == startHandler.getNext().getNext() && localVar.getType().equals(codeException.getCatchType())) return endScope.getPrev(); } throw new Error("no end exceptionhandler..."); }
/** * Get the basic block in the subroutine for the given instruction. If * the block doesn't exist yet, it is created, and a work list item is * added which will populate it. Note that if start is an exception * thrower, the block returned will be its ETB. * * @param start * the start instruction for the block * @return the basic block for the instruction */ public BasicBlock getBlock(InstructionHandle start) { BasicBlock block = blockMap.get(start); if (block == null) { block = allocateBasicBlock(); blockMap.put(start, block); // Block is an exception handler? CodeExceptionGen exceptionGen = exceptionHandlerMap.getHandlerForStartInstruction(start); if (exceptionGen != null) block.setExceptionGen(exceptionGen); addItem(new WorkListItem(start, block)); } return block; }
public void transfer(BasicBlock basicBlock, @CheckForNull InstructionHandle end, BlockType start, BlockType result) throws DataflowAnalysisException { result.copyFrom(start); if (start.isValid()) { if (basicBlock.isExceptionHandler()) { CodeExceptionGen exceptionGen = basicBlock.getExceptionGen(); ObjectType catchType = exceptionGen.getCatchType(); if (catchType == null) { // Probably a finally block, or a synchronized block // exception-compensation catch block. result.pushFinally(); } else { // Catch type was explicitly specified: // this is probably a programmer-written catch block result.pushCatch(); } } } }
public static CodeExceptionGen merge(@CheckForNull TypeMerger m, CodeExceptionGen e1, CodeExceptionGen e2) { if (e1 == null) return e2; if (e2 == null) return e1; if (m == null) return e1; if ( ! e1.getHandlerPC().equals( e2.getHandlerPC() ) ){ // log error return e1; } try { Type t = m.mergeTypes(e1.getCatchType(), e2.getCatchType()); return new CodeExceptionGen(e1.getStartPC(), e1.getEndPC(), e1.getHandlerPC(), (ObjectType) t); } catch (DataflowAnalysisException e) { // TODO Auto-generated catch block e.printStackTrace(); return e1; } }
/** * Get the basic block in the subroutine for the given instruction. If * the block doesn't exist yet, it is created, and a work list item is * added which will populate it. Note that if start is an exception * thrower, the block returned will be its ETB. * * @param start * the start instruction for the block * @return the basic block for the instruction */ public BasicBlock getBlock(InstructionHandle start) { BasicBlock block = blockMap.get(start); if (block == null) { block = allocateBasicBlock(); blockMap.put(start, block); // Block is an exception handler? CodeExceptionGen exceptionGen = exceptionHandlerMap.getHandlerForStartInstruction(start); if (exceptionGen != null) block.setExceptionGen(null, exceptionGen); addItem(new WorkListItem(start, block)); } return block; }
/** * Constructor. Creates a new ExceptionHandlers instance. */ public ExceptionHandlers(MethodGen mg){ exceptionhandlers = new Hashtable(); CodeExceptionGen[] cegs = mg.getExceptionHandlers(); for (int i=0; i<cegs.length; i++){ ExceptionHandler eh = new ExceptionHandler(cegs[i].getCatchType(), cegs[i].getHandlerPC()); for (InstructionHandle ih=cegs[i].getStartPC(); ih != cegs[i].getEndPC().getNext(); ih=ih.getNext()){ Set hs; hs = (Set) exceptionhandlers.get(ih); if (hs == null){ hs = new HashSet(); exceptionhandlers.put(ih, hs); } hs.add(eh); } } }
/** * Constructor. Creates a new ExceptionHandlers instance. * @param mg */ public ExceptionHandlers(MethodGen mg) { exceptionhandlers = new Hashtable<InstructionHandle, HashSet>(); CodeExceptionGen[] cegs = mg.getExceptionHandlers(); for (CodeExceptionGen ceg : cegs) { ExceptionHandler eh = new ExceptionHandler(ceg.getCatchType(), ceg.getHandlerPC()); for (InstructionHandle ih = ceg.getStartPC(); ih != ceg.getEndPC().getNext(); ih = ih.getNext()) { HashSet<ExceptionHandler> hs; hs = exceptionhandlers.get(ih); if (hs == null) { hs = new HashSet<ExceptionHandler>(); exceptionhandlers.put(ih, hs); } hs.add(eh); } } }
public void print(PrintStream out) { Iterator<BasicBlock> i = cfg.blockIterator(); while (i.hasNext()) { BasicBlock bb = i.next(); out.println(); out.println("BASIC BLOCK: " + bb.getId() + (bb.isExceptionThrower() ? " [EXCEPTION THROWER]" : "") + blockStartAnnotate(bb)); if (bb.isExceptionThrower()) { out.println(" Exception thrower: " + bb.getExceptionThrower()); } CodeExceptionGen exceptionGen = bb.getExceptionGen(); if (exceptionGen != null) { System.out.println(" CATCHES " + exceptionGen.getCatchType()); } Iterator<InstructionHandle> j = instructionIterator(bb); while (j.hasNext()) { InstructionHandle handle = j.next(); out.println(handle + instructionAnnotate(handle, bb)); } out.println("END" + blockAnnotate(bb)); Iterator<Edge> edgeIter = isForwards ? cfg.outgoingEdgeIterator(bb) : cfg.incomingEdgeIterator(bb); while (edgeIter.hasNext()) { Edge edge = edgeIter.next(); out.println(" " + edge.formatAsString(!isForwards) + " " + edgeAnnotate(edge)); } } }
private void addHandler(InstructionHandle handle, CodeExceptionGen exceptionHandler) { List<CodeExceptionGen> handlerList = codeToHandlerMap.get(handle); if (handlerList == null) { handlerList = new LinkedList<CodeExceptionGen>(); codeToHandlerMap.put(handle, handlerList); } handlerList.add(exceptionHandler); }
public void meetInto(BetterTypeFrame fact, Edge edge, BetterTypeFrame result) throws DataflowAnalysisException { // TODO: implement ACCURATE_EXCEPTIONS if (fact.isValid() && edge.getTarget().isExceptionHandler()) { BetterTypeFrame tmpFact = null; // Exception handler. // Clear stack and push exception handler catch type. tmpFact = modifyFrame(fact, tmpFact); tmpFact.clearStack(); CodeExceptionGen exceptionGen = edge.getTarget().getExceptionGen(); org.apache.bcel.generic.ObjectType catchType = exceptionGen.getCatchType(); if (catchType == null) { tmpFact.pushValue(typeRepository.classTypeFromSignature(JAVA_LANG_THROWABLE_SIGNATURE)); } else { tmpFact.pushValue(typeRepository.classTypeFromDottedClassName(catchType.getClassName())); } fact = tmpFact; } mergeInto(fact, result); }
static InstructionHandle getEndOfCatchBlock(MethodGen m, CodeExceptionGen catchBlock) { if (catchBlock.getCatchType() == null) { // finally clause, no local variable! return null; } LocalVariableGen[] lt = m.getLocalVariables(); InstructionHandle handler = catchBlock.getHandlerPC(); for (int i = 0; i < lt.length; i++) { InstructionHandle start = lt[i].getStart(); InstructionHandle end = lt[i].getEnd(); // dangerous, javac is one instruction further... if ((start == handler || start == handler.getNext() || start == handler .getNext().getNext()) && lt[i].getType().equals(catchBlock.getCatchType())) { // System.out.println("found range of catch block: " // + handler + " - " + end); return end.getPrev(); } } System.err .println("Could not find end of catch block, did you compile " + "with the '-g' option?"); System.exit(1); return null; }
InstructionHandle insertTypecheckCode(MethodGen m, InstructionList il, InstructionHandle pos, int spawnId, int exceptionPos) { ArrayList<CodeExceptionGen> catches = mtab.getCatchTypes(m, spawnId); InstructionHandle[] jumpTargets = new InstructionHandle[catches.size() + 1]; BranchHandle[] jumps = new BranchHandle[catches.size()]; for (int i = 0; i < catches.size(); i++) { CodeExceptionGen e = catches.get(i); ObjectType type = e.getCatchType(); InstructionHandle catchTarget = e.getHandlerPC(); jumpTargets[i] = il.insert(pos, new ALOAD(exceptionPos)); il.insert(pos, new INSTANCEOF(cpg.addClass(type))); il.insert(pos, new BIPUSH((byte) 1)); jumps[i] = il.insert(pos, new IF_ICMPNE(null)); il.insert(pos, new ALOAD(exceptionPos)); il.insert(pos, ins_f.createCheckCast(type)); il.insert(pos, new GOTO(catchTarget)); } InstructionHandle t = il.insert(pos, new ALOAD(exceptionPos)); il.insert(pos, new ATHROW()); jumpTargets[catches.size()] = t; for (int i = 0; i < catches.size(); i++) { jumps[i].setTarget(jumpTargets[i + 1]); } return pos; }
private boolean hasRightType(CodeExceptionGen codeException, MethodGen method) { ObjectType catchType = codeException.getCatchType(); if (catchType == null) return false; String[] exceptionTypeNames = method.getExceptions(); ObjectType[] exceptionTypes = new ObjectType[exceptionTypeNames.length]; for (int i = 0; i < exceptionTypeNames.length; i++) { exceptionTypes[i] = new ObjectType(exceptionTypeNames[i]); } return containsType(catchType, exceptionTypes); }
private SpawnableCall getSpawnableCallWithException(InstructionHandle invokeInstruction, MethodGen spawnSignatureGen) { ArrayList<CodeExceptionGen> exceptionHandlers = getExceptionHandlers(invokeInstruction, spawnSignatureGen); if (exceptionHandlers.size() == 0) { return new SpawnableCall(invokeInstruction, getObjectReferenceLoadInstruction(invokeInstruction), SpawnableCall.Type.EXCEPTIONS_NOT_HANDLED); } else { return getSpawnableCallWithException(invokeInstruction, exceptionHandlers); } }
private CodeExceptionGen find_ceg(CodeExceptionGen[] cegs, int pos) { CodeExceptionGen ret = null; for (CodeExceptionGen ceg : cegs) { int start = ceg.getStartPC().getPosition(); int end = ceg.getEndPC().getPosition(); if (start <= pos && pos <= end) { ret = ceg; break; } } return ret; }
public void print(PrintStream out) { Iterator<BasicBlock> i = cfg.blockIterator(); while (i.hasNext()) { BasicBlock bb = i.next(); out.println(); out.println("BASIC BLOCK: " + bb.getLabel() + (bb.isExceptionThrower() ? " [EXCEPTION THROWER]" : "") + blockStartAnnotate(bb)); if (bb.isExceptionThrower()) { out.println(" Exception thrower: " + bb.getExceptionThrower()); } CodeExceptionGen exceptionGen = bb.getExceptionGen(); if (exceptionGen != null) { out.println("\tCATCHES " + exceptionGen.getCatchType()); } Iterator<InstructionHandle> j = instructionIterator(bb); while (j.hasNext()) { InstructionHandle handle = j.next(); out.println(handle + instructionAnnotate(handle, bb)); } out.println("END" + blockAnnotate(bb)); Iterator<Edge> edgeIter = isForwards ? cfg.outgoingEdgeIterator(bb) : cfg.incomingEdgeIterator(bb); while (edgeIter.hasNext()) { Edge edge = edgeIter.next(); out.println(" " + edge.formatAsString(!isForwards) + " " + edgeAnnotate(edge)); } } }
/** * Add exception edges for given instruction. * * @param subroutine * the subroutine containing the instruction * @param pei * the instruction which throws an exception * @param etb * the exception thrower block (ETB) for the instruction */ private void handleExceptions(Subroutine subroutine, InstructionHandle pei, BasicBlock etb) { etb.setExceptionThrower(pei); // Remember whether or not a universal exception handler // is reachable. If so, then we know that exceptions raised // at this instruction cannot propagate out of the method. boolean sawUniversalExceptionHandler = false; List<CodeExceptionGen> exceptionHandlerList = exceptionHandlerMap.getHandlerList(pei); if (exceptionHandlerList != null) { for (CodeExceptionGen exceptionHandler : exceptionHandlerList) { InstructionHandle handlerStart = exceptionHandler.getHandlerPC(); subroutine.addEdgeAndExplore(etb, handlerStart, HANDLED_EXCEPTION_EDGE); if (Hierarchy.isUniversalExceptionHandler(exceptionHandler.getCatchType())) sawUniversalExceptionHandler = true; } } // If required, mark this block as throwing an unhandled exception. // For now, we assume that if there is no reachable handler that handles // ANY exception type, then the exception can be thrown out of the // method. if (!sawUniversalExceptionHandler) { if (DEBUG) System.out.println("Adding unhandled exception edge from " + pei); subroutine.setUnhandledExceptionBlock(etb); } }
/** * Constructor. * * @param methodGen * the method to build the map for */ public ExceptionHandlerMap( MethodGen methodGen, TypeMerger merger) { codeToHandlerMap = new IdentityHashMap<InstructionHandle, List<CodeExceptionGen>>(); startInstructionToHandlerMap = new IdentityHashMap<InstructionHandle, CodeExceptionGen>(); this.merger = merger; build(methodGen); }
private void addExceptionHandler(CodeExceptionGen exceptionHandler) { InstructionHandle handlerPC = exceptionHandler.getHandlerPC(); CodeExceptionGen existing = startInstructionToHandlerMap.get(handlerPC); if (existing != null) { exceptionHandler = merge (this.merger, existing, exceptionHandler); } startInstructionToHandlerMap.put(handlerPC, exceptionHandler); }
/** * Set the CodeExceptionGen object. Marks this basic block as the entry * point of an exception handler. * * @param exceptionGen * the CodeExceptionGen object for the block */ public void setExceptionGen(TypeMerger m, CodeExceptionGen exceptionGen) { if (this.exceptionGen != null) { AnalysisContext.logError("Multiple exception handlers"); } this.exceptionGen = exceptionGen; }
private void updateExceptionHandlers() { CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); for (int i = 0; i < handlers.length; i++) { CodeExceptionGen h = handlers[i]; String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h .getCatchType()); _out.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_" + h.getHandlerPC().getPosition() + ", " + type + ");"); } }
/** * Constructor. * * @param methodGen the method to build the map for */ public ExceptionHandlerMap(MethodGen methodGen) { codeToHandlerMap = new IdentityHashMap<InstructionHandle, List<CodeExceptionGen>>(); startInstructionToHandlerMap = new IdentityHashMap<InstructionHandle, CodeExceptionGen>(); build(methodGen); }
private void analyzeSpawn(MethodTableEntry me, InstructionHandle spawnIns, int spawnId) { SpawnTableEntry se = me.spawnTable[spawnId] = new SpawnTableEntry(); se.isLocalUsed = new boolean[me.mg.getMaxLocals()]; CodeExceptionGen[] exceptions = me.mg.getExceptionHandlers(); // We have a spawn. Is it in a try block? for (int j = 0; j < exceptions.length; j++) { CodeExceptionGen e = exceptions[j]; int startPC = e.getStartPC().getPosition(); int endPC = e.getEndPC().getPosition(); int PC = spawnIns.getPosition(); if (verbose) { System.err.println("startPC = " + startPC + ", endPC = " + endPC + ", PC = " + PC); } if (PC >= startPC && PC <= endPC) { /* ok, we have an inlet, add try-catch block info to table */ me.containsInlet = true; se.hasInlet = true; if (se.catchBlocks == null) { se.catchBlocks = new ArrayList<CodeExceptionGen>(); } se.catchBlocks.add(e); if (verbose) { System.out.println("spawn " + spawnId + " with inlet " + e); } boolean[] used = se.analyseUsedLocals(me.mg, e, verbose); for (int k = 0; k < used.length; k++) { if (used[k]) { se.isLocalUsed[k] = true; } } } } if (verbose) { System.out.println(me.m + ": unused locals in all inlets: "); for (int k = 0; k < se.isLocalUsed.length; k++) { if (!se.isLocalUsed[k]) { System.out.println("local " + k + " is unused"); } else { System.out.println("local " + k + " is used"); } } } }
ArrayList<CodeExceptionGen> getCatchTypes(MethodGen m, int spawnId) { MethodTableEntry e = findMethod(m); return e.spawnTable[spawnId].catchBlocks; }
public void meetInto(TypeFrame fact, Edge edge, TypeFrame result) throws DataflowAnalysisException { BasicBlock basicBlock = edge.getTarget(); if (fact.isValid()) { TypeFrame tmpFact = null; // Handling an exception? if (basicBlock.isExceptionHandler()) { tmpFact = modifyFrame(fact, tmpFact); // Special case: when merging predecessor facts for entry to // an exception handler, we clear the stack and push a // single entry for the exception object. That way, the locals // can still be merged. CodeExceptionGen exceptionGen = basicBlock.getExceptionGen(); tmpFact.clearStack(); // Determine the type of exception(s) caught. Type catchType = null; if (FORCE_ACCURATE_EXCEPTIONS || AnalysisContext.currentAnalysisContext().getBoolProperty(AnalysisFeatures.ACCURATE_EXCEPTIONS)) { try { // Ideally, the exceptions that can be propagated // on this edge has already been computed. CachedExceptionSet cachedExceptionSet = getCachedExceptionSet(edge.getSource()); ExceptionSet edgeExceptionSet = cachedExceptionSet.getEdgeExceptionSet(edge); if (!edgeExceptionSet.isEmpty()) { // System.out.println("Using computed edge exception set!"); catchType = ExceptionObjectType.fromExceptionSet(edgeExceptionSet); } } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); } } if (catchType == null) { // No information about propagated exceptions, so // pick a type conservatively using the handler catch type. catchType = exceptionGen.getCatchType(); if (catchType == null) catchType = Type.THROWABLE; // handle catches anything // throwable } tmpFact.pushValue(catchType); } // See if we can make some types more precise due to // a successful instanceof check in the source block. if (valueNumberDataflow != null) { tmpFact = handleInstanceOfBranch(fact, tmpFact, edge); } if (tmpFact != null) { fact = tmpFact; } } mergeInto(fact, result); }
/** * Based on the set of exceptions that can be thrown from the source basic * block, compute the set of exceptions that can propagate along given * exception edge. This method should be called for each outgoing exception * edge in sequence, so the caught exceptions can be removed from the thrown * exception set as needed. * * @param edge * the exception edge * @param thrownExceptionSet * current set of exceptions that can be thrown, taking earlier * (higher priority) exception edges into account * @return the set of exceptions that can propagate along this edge */ private ExceptionSet computeEdgeExceptionSet(Edge edge, ExceptionSet thrownExceptionSet) { if (thrownExceptionSet.isEmpty()) return thrownExceptionSet; ExceptionSet result = exceptionSetFactory.createExceptionSet(); if (edge.getType() == UNHANDLED_EXCEPTION_EDGE) { // The unhandled exception edge always comes // after all of the handled exception edges. result.addAll(thrownExceptionSet); thrownExceptionSet.clear(); return result; } BasicBlock handlerBlock = edge.getTarget(); CodeExceptionGen handler = handlerBlock.getExceptionGen(); ObjectType catchType = handler.getCatchType(); if (Hierarchy.isUniversalExceptionHandler(catchType)) { result.addAll(thrownExceptionSet); thrownExceptionSet.clear(); } else { // Go through the set of thrown exceptions. // Any that will DEFINITELY be caught be this handler, remove. // Any that MIGHT be caught, but won't definitely be caught, // remain. for (ExceptionSet.ThrownExceptionIterator i = thrownExceptionSet.iterator(); i.hasNext();) { // ThrownException thrownException = i.next(); ObjectType thrownType = i.next(); boolean explicit = i.isExplicit(); if (DEBUG) System.out.println("\texception type " + thrownType + ", catch type " + catchType); try { if (Hierarchy.isSubtype(thrownType, catchType)) { // Exception can be thrown along this edge result.add(thrownType, explicit); // And it will definitely be caught i.remove(); if (DEBUG) System.out.println("\tException is subtype of catch type: " + "will definitely catch"); } else if (Hierarchy.isSubtype(catchType, thrownType)) { // Exception possibly thrown along this edge result.add(thrownType, explicit); if (DEBUG) System.out.println("\tException is supertype of catch type: " + "might catch"); } } catch (ClassNotFoundException e) { // As a special case, if a class hierarchy lookup // fails, then we will conservatively assume that the // exception in question CAN, but WON'T NECESSARILY // be caught by the handler. AnalysisContext.reportMissingClass(e); result.add(thrownType, explicit); } } } return result; }
public void visitCode(Code code) { MethodGen mg = new MethodGen(_method, clazzname, cp); InstructionList il = mg.getInstructionList(); InstructionHandle[] ihs = il.getInstructionHandles(); LocalVariableGen[] lvs = mg.getLocalVariables(); CodeExceptionGen[] ehs = mg.getExceptionHandlers(); for (int i = 0; i < lvs.length; i++) { LocalVariableGen l = lvs[i]; out.println(" // local variable " + l.getIndex() + " is \"" + l.getName() + "\" " + l.getType() + " from " + l.getStart().getPosition() + " to " + l.getEnd().getPosition()); } out.print("\n"); for (int i = 0; i < ihs.length; i++) { InstructionHandle ih = ihs[i]; Instruction inst = ih.getInstruction(); out.print(" " + ih.getPosition()); if (inst instanceof BranchInstruction) { if (inst instanceof Select) { // Special cases LOOKUPSWITCH and // TABLESWITCH Select s = (Select) inst; int[] matchs = s.getMatchs(); InstructionHandle[] targets = s.getTargets(); if (s instanceof TABLESWITCH) { out.println(" tableswitch " + matchs[0] + " " + matchs[matchs.length - 1]); for (int j = 0; j < targets.length; j++) out.println(" " + targets[j].getPosition()); } else { // LOOKUPSWITCH out.println(" lookupswitch "); for (int j = 0; j < targets.length; j++) out.println(" " + matchs[j] + " : " + targets[j].getPosition()); } out.println(" default: " + s.getTarget()); // Applies // for // both } else { BranchInstruction bi = (BranchInstruction) inst; ih = bi.getTarget(); //str = get(ih); out.println(" " + Constants.OPCODE_NAMES[bi.getOpcode()] + " " + ih); } } else out.println(" " + inst.toString(cp.getConstantPool())); } out.print("\n"); for (int i = 0; i < ehs.length; i++) { CodeExceptionGen c = ehs[i]; ObjectType caught = c.getCatchType(); String class_name = (caught == null) ? // catch any exception, used // when compiling finally "all" : caught.getClassName().replace('.', '/'); out.println(" catch " + class_name + " from " + c.getStartPC().getPosition() + " to " + c.getEndPC().getPosition() + " using " + c.getHandlerPC().getPosition()); } }