use of org.candle.decompiler.intermediate.code.TryIntermediate in project candle-decompiler by bradsdavis.
the class IntermediateEdgeAttributeProvider method getComponentAttributes.
@Override
public Map<String, String> getComponentAttributes(IntermediateEdge edge) {
Map<String, String> attributes = new HashMap<String, String>();
AbstractIntermediate source = (AbstractIntermediate) edge.getSource();
AbstractIntermediate target = (AbstractIntermediate) edge.getTarget();
if (source instanceof TryIntermediate && (target instanceof CatchIntermediate || target instanceof FinallyIntermediate)) {
attributes.put("style", "dashed");
}
return attributes;
}
use of org.candle.decompiler.intermediate.code.TryIntermediate in project candle-decompiler by bradsdavis.
the class RetractDuplicateFinally method visitFinallyIntermediate.
@Override
public void visitFinallyIntermediate(FinallyIntermediate line) {
// TODO: Remove the highest finally statements first; won't fit this visitor
// pattern.
// get the bounds of the finally... associate the try.
// finally is part of the try if the try + catch bounds has:
// Try[0,13]
// Catch[19,50]
// Catch[56,65]
// Finally | Handler[56, 65]| Handler[0, 42] | | Range[66, 76]
// in the case above, finally should match because lower bound == finally lower handler bound.
// and upper bound of Catch matches upper bound of Finally Handler.
// first, match the Try block that applies...
// get lowest bound.
InstructionHandle min = getLowestBound(line.getCodeExceptions());
InstructionHandle max = getHighestBound(line.getCodeExceptions());
LOG.debug("Finally Range: " + min.getPosition() + " -> " + max.getPosition());
TryIntermediate matched = matchTryBlock(min, max);
if (matched != null) {
final Set<Integer> offsets = collectOffsets(line);
// ok, now we need to eliminate finally blocks from this try and all of the catches. thanks Java!
List<CatchIntermediate> catchClauses = igc.getCatchClauses(matched);
// for each catch clause...
for (CatchIntermediate catchClause : catchClauses) {
processCatch(catchClause, line, offsets);
}
processTry(matched, line, offsets);
}
// now, add the edge between end of FINALLY and the next statement.
InstructionHandle finallyEnd = line.getBlockRange().getEnd();
// get the next.. then search for next node in graph.
AbstractIntermediate finallyLast = igc.findNextNode(finallyEnd);
AbstractIntermediate afterFinally = igc.findNextNode(finallyEnd.getNext());
igc.redirectPredecessors(finallyLast, afterFinally);
igc.getGraph().removeVertex(finallyLast);
}
use of org.candle.decompiler.intermediate.code.TryIntermediate in project candle-decompiler by bradsdavis.
the class RetractDuplicateFinally method matchTryBlock.
protected TryIntermediate matchTryBlock(InstructionHandle min, InstructionHandle max) {
LinkedList<TryIntermediate> matches = new LinkedList<TryIntermediate>();
// find the try block...
for (AbstractIntermediate ai : igc.getGraph().vertexSet()) {
if (ai instanceof TryIntermediate) {
TryIntermediate tryIntermediate = ((TryIntermediate) ai);
LOG.debug("Finally: " + tryIntermediate + " , " + tryIntermediate.getInstruction().getPosition() + " , " + tryIntermediate.getBlockRange().getStart());
if (tryIntermediate.getBlockRange().getStart().getPosition() == min.getPosition()) {
// only add where max > try's max range...
if (tryIntermediate.getBlockRange().getEnd().getPosition() < max.getPosition()) {
matches.add(tryIntermediate);
}
}
}
}
// return the smaller range...
if (matches.size() > 0) {
Collections.sort(matches, new Comparator<TryIntermediate>() {
@Override
public int compare(TryIntermediate t1, TryIntermediate t2) {
if (t1.getBlockRange().getEnd().getPosition() > t2.getBlockRange().getEnd().getPosition()) {
return -1;
}
return 0;
}
});
LOG.debug("Match: " + matches.peekFirst() + " Range: " + matches.peekFirst().getBlockRange());
return matches.getFirst();
}
return null;
}
use of org.candle.decompiler.intermediate.code.TryIntermediate in project candle-decompiler by bradsdavis.
the class CatchUpperRangeVisitor method processLastCatch.
public void processLastCatch(CatchIntermediate line) {
TryIntermediate tryBlock = (TryIntermediate) igc.getSinglePredecessor(line);
if (igc.getFinallyClause(tryBlock) != null) {
return;
}
// now, we are going to look for the block jump.
InstructionHandle ih = tryBlock.getBlockRange().getEnd();
// see about a goto.
GoToIntermediate gotoHandle = (GoToIntermediate) igc.findNextNode(ih.getNext());
TreeSet<AbstractIntermediate> ordered = new TreeSet<AbstractIntermediate>(new IntermediateComparator());
// no finally clause...
ordered.addAll(igc.getCatchClauses(tryBlock));
AbstractIntermediate target = igc.getTarget(gotoHandle);
// now, look backwards and find the non-GOTO statement.
List<AbstractIntermediate> candidates = Graphs.predecessorListOf(igc.getGraph(), target);
Set<AbstractIntermediate> elements = new HashSet<AbstractIntermediate>();
for (AbstractIntermediate candidate : candidates) {
if (!(candidate instanceof GoToIntermediate)) {
elements.add(candidate);
}
}
for (AbstractIntermediate element : elements) {
LOG.debug("Element: " + element + " Position: " + element.getInstruction().getPosition());
}
if (elements.size() == 1) {
if (ordered.last() instanceof CatchIntermediate) {
CatchIntermediate ci = (CatchIntermediate) ordered.last();
ci.getBlockRange().setEnd(elements.iterator().next().getInstruction());
}
}
}
use of org.candle.decompiler.intermediate.code.TryIntermediate in project candle-decompiler by bradsdavis.
the class IntermediateTryCatch method process.
public void process() {
Set<BlockRange> tryBlock = new TreeSet<BlockRange>(new BlockRangeComparator());
Map<BlockRange, List<CodeExceptionGen>> tryRangeGen = new HashMap<BlockRange, List<CodeExceptionGen>>();
Map<InstructionHandle, List<CodeExceptionGen>> tryRangeFinally = new HashMap<InstructionHandle, List<CodeExceptionGen>>();
// create try statements...
for (CodeExceptionGen ceg : method.getExceptionHandlers()) {
InstructionHandle min = ceg.getStartPC();
InstructionHandle max = ceg.getEndPC();
BlockRange tryRange = new BlockRange();
tryRange.setStart(min);
tryRange.setEnd(max);
AbstractIntermediate handle = igc.findNextNode(ceg.getHandlerPC());
LOG.debug("RANGE: " + ceg);
LOG.debug("Range: " + tryRange + " , Target: " + handle.getInstruction().getPosition() + " , Handle: " + handle.getInstruction());
if (ceg.getCatchType() == null) {
if (!tryRangeFinally.containsKey(ceg.getHandlerPC())) {
tryRangeFinally.put(ceg.getHandlerPC(), new LinkedList<CodeExceptionGen>());
}
tryRangeFinally.get(ceg.getHandlerPC()).add(ceg);
continue;
}
tryBlock.add(tryRange);
if (!tryRangeGen.containsKey(tryRange)) {
tryRangeGen.put(tryRange, new LinkedList<CodeExceptionGen>());
}
tryRangeGen.get(tryRange).add(ceg);
}
for (BlockRange tryRange : tryBlock) {
// create try block... create each catch block... link the two together for graph sake.
// look up block...
InstructionHandle start = tryRange.getStart();
TryIntermediate tryIntermediate = new TryIntermediate(start);
tryIntermediate.getBlockRange().setStart(tryRange.getStart());
tryIntermediate.getBlockRange().setEnd(tryRange.getEnd());
igc.getGraph().addVertex(tryIntermediate);
// add line between try and node.
AbstractIntermediate tryFirst = igc.findNextNode(start);
igc.redirectPredecessors(tryFirst, tryIntermediate);
igc.getGraph().addEdge(tryIntermediate, tryFirst);
if (tryRangeGen.containsKey(tryRange)) {
// create catch statements...
for (CodeExceptionGen ceg : tryRangeGen.get(tryRange)) {
generateCatch(tryIntermediate, ceg);
}
}
}
// create a finally node for each handle of finally & link
for (InstructionHandle finallyTargetHandle : tryRangeFinally.keySet()) {
// get reference to target...
AbstractIntermediate finallyTargetNode = igc.findNextNode(finallyTargetHandle);
// change the instruction to a finally...
FinallyIntermediate finallyIntermediate = new FinallyIntermediate(finallyTargetNode.getInstruction(), new HashSet<CodeExceptionGen>(tryRangeFinally.get(finallyTargetHandle)));
igc.getGraph().addVertex(finallyIntermediate);
// now, we need to redirect from the existing throws to finally.
igc.redirectSuccessors(finallyTargetNode, finallyIntermediate);
// retract existing.
igc.getGraph().removeVertex(finallyTargetNode);
}
}
Aggregations