private GenLocation advance() { if(locIterator.hasNext()) { return new RegularLocation(ta, vna, locIterator.next()); } while(blockIterator.hasNext()) { BasicBlock block = blockIterator.next(); if(block.isExceptionThrower() && cfg.getOutgoingEdgeWithType(block, EdgeTypes.FALL_THROUGH_EDGE) == null) { return new ExceptionLocation(ta, vna, block); } } return null; }
@Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("[basicBlock="); buf.append(getBasicBlock().getLabel()); if (next != null) { buf.append(", next=" + next); } else if (getBasicBlock().isExceptionThrower()) { buf.append(", check for" + getBasicBlock().getExceptionThrower()); } else { buf.append(", end"); } buf.append(']'); return buf.toString(); } }
/** * Return whether or not this block is a null check. */ public boolean isNullCheck() { // Null check blocks must be exception throwers, // and are always empty. (The only kind of non-empty // exception throwing block is one terminated by an ATHROW). if (!isExceptionThrower() || getFirstInstruction() != null) { return false; } short opcode = exceptionThrower.getInstruction().getOpcode(); return nullCheckInstructionSet.get(opcode); }
@Override public InstructionHandle next() { if (!hasNext()) { throw new NoSuchElementException(); } InstructionHandle result = next; if(result == block.getFirstInstruction()) { do { Iterator<Edge> edgeIterator = cfg.incomingEdgeIterator(block); if(!edgeIterator.hasNext()) { break; } Edge edge = edgeIterator.next(); if(!edgeIterator.hasNext() && edge.getType() == EdgeTypes.FALL_THROUGH_EDGE) { block = edge.getSource(); } else { break; } } while(block.isExceptionThrower()); } next = (block.isExceptionThrower() || result == block.getFirstInstruction()) ? null : next.getPrev(); return result; }
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)); } } }
InstructionHandle targetInstruction = target.getFirstInstruction(); String exInfo = " -> "; if (targetInstruction == null && target.isExceptionThrower()) { targetInstruction = target.getExceptionThrower(); exInfo = " => "; buf.append(targetInstruction.getPosition()); buf.append(']'); } else if (source.isExceptionThrower()) { if (type == FALL_THROUGH_EDGE) { buf.append(" [successful check]");
@Override public void visitEdge(Edge edge) { if (REPORT_PATH_DEBUG) { System.out.println("Edge of type " + Edge.edgeTypeToString(edge.getType()) + " to " + edge.getTarget().getLabel()); if (edge.getTarget().getFirstInstruction() != null) { System.out.println(" First instruction in target: " + edge.getTarget().getFirstInstruction()); } if (edge.getTarget().isExceptionThrower()) { System.out.println(" exception thrower for " + edge.getTarget().getExceptionThrower()); } if (edge.isExceptionEdge()) { System.out.println(" exceptions thrown: " + typeDataflow.getEdgeExceptionSet(edge)); } } } };
if (!basicBlock.isExceptionThrower()) { continue;
private Location getEdgeTargetLocation(CFG cfg, Edge edge) { BasicBlock targetBlock = edge.getTarget(); // Target block is nonempty? if (targetBlock.getFirstInstruction() != null) { return new Location(targetBlock.getFirstInstruction(), targetBlock); } // Target block is an ETB? if (targetBlock.isExceptionThrower()) { BasicBlock fallThroughSuccessor = cfg.getSuccessorWithEdgeType(targetBlock, EdgeTypes.FALL_THROUGH_EDGE); if (fallThroughSuccessor == null) { // Fall through edge might have been pruned for (Iterator<Edge> i = cfg.removedEdgeIterator(); i.hasNext();) { Edge removedEdge = i.next(); if (removedEdge.getSource() == targetBlock && removedEdge.getType() == EdgeTypes.FALL_THROUGH_EDGE) { fallThroughSuccessor = removedEdge.getTarget(); break; } } } if (fallThroughSuccessor != null && fallThroughSuccessor.getFirstInstruction() != null) { return new Location(fallThroughSuccessor.getFirstInstruction(), fallThroughSuccessor); } } return null; }
if (!basicBlock.isExceptionThrower()) { return;
@Override public void transfer(BasicBlock basicBlock, InstructionHandle end, ValueNumberFrame start, ValueNumberFrame result) throws DataflowAnalysisException { if(basicBlock.isExceptionThrower() && isFactValid(start)) { /* If exceptionThrower is invoke instruction then it's possible that * it was partially executed before an exception occurred * So we have to kill available loads when control is transferred to the catch block */ InstructionHandle handle = basicBlock.getExceptionThrower(); Instruction inst = handle.getInstruction(); if(inst instanceof InvokeInstruction || inst instanceof INVOKEDYNAMIC) { copy(start, result); visitor.setFrameAndLocation(result, new Location(handle, basicBlock)); visitor.setHandle(handle); visitor.visitInvokeOnException(inst); return; } } super.transfer(basicBlock, end, start, result); }
b2 = cfg.getPredecessorWithEdgeType(b, EdgeTypes.FALL_THROUGH_EDGE); if(b2 != null && b2.isExceptionThrower()) { for (Iterator<Edge> i = cfg.incomingEdgeIterator(b2); i.hasNext();) { Edge e = i.next();
if (!basicBlock.isExceptionThrower()) { continue;
+ (target.isExceptionThrower() ? " exception thrower" : " not exception thrower")); boolean empty = !target.isExceptionThrower() && (target.isEmpty() || isGoto(target.getFirstInstruction().getInstruction())); if (!empty) {
if (subBlock.isExceptionThrower()) { resultBlock.setExceptionThrower(subBlock.getExceptionThrower());
private GenLocation advance() { if(locIterator.hasNext()) { return new RegularLocation(ta, vna, locIterator.next()); } while(blockIterator.hasNext()) { BasicBlock block = blockIterator.next(); if(block.isExceptionThrower() && cfg.getOutgoingEdgeWithType(block, EdgeTypes.FALL_THROUGH_EDGE) == null) { return new ExceptionLocation(ta, vna, block); } } return null; }
@Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("[basicBlock="); buf.append(getBasicBlock().getLabel()); if (next != null) { buf.append(", next=" + next); } else if (getBasicBlock().isExceptionThrower()) { buf.append(", check for" + getBasicBlock().getExceptionThrower()); } else { buf.append(", end"); } buf.append(']'); return buf.toString(); } }
/** * Return whether or not this block is a null check. */ public boolean isNullCheck() { // Null check blocks must be exception throwers, // and are always empty. (The only kind of non-empty // exception throwing block is one terminated by an ATHROW). if (!isExceptionThrower() || getFirstInstruction() != null) { return false; } short opcode = exceptionThrower.getInstruction().getOpcode(); return nullCheckInstructionSet.get(opcode); }
@Override public void visitEdge(Edge edge) { if (REPORT_PATH_DEBUG) { System.out.println("Edge of type " + Edge.edgeTypeToString(edge.getType()) + " to " + edge.getTarget().getLabel()); if (edge.getTarget().getFirstInstruction() != null) { System.out.println(" First instruction in target: " + edge.getTarget().getFirstInstruction()); } if (edge.getTarget().isExceptionThrower()) { System.out.println(" exception thrower for " + edge.getTarget().getExceptionThrower()); } if (edge.isExceptionEdge()) { System.out.println(" exceptions thrown: " + typeDataflow.getEdgeExceptionSet(edge)); } } } };
@Override public void transfer(BasicBlock basicBlock, InstructionHandle end, ValueNumberFrame start, ValueNumberFrame result) throws DataflowAnalysisException { if(basicBlock.isExceptionThrower() && isFactValid(start)) { /* If exceptionThrower is invoke instruction then it's possible that * it was partially executed before an exception occurred * So we have to kill available loads when control is transferred to the catch block */ InstructionHandle handle = basicBlock.getExceptionThrower(); Instruction inst = handle.getInstruction(); if(inst instanceof InvokeInstruction || inst instanceof INVOKEDYNAMIC) { copy(start, result); visitor.setFrameAndLocation(result, new Location(handle, basicBlock)); visitor.setHandle(handle); visitor.visitInvokeOnException(inst); return; } } super.transfer(basicBlock, end, start, result); }