Search in sources :

Example 1 with TryIntermediate

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;
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) HashMap(java.util.HashMap) CatchIntermediate(org.candle.decompiler.intermediate.code.CatchIntermediate) FinallyIntermediate(org.candle.decompiler.intermediate.code.FinallyIntermediate) TryIntermediate(org.candle.decompiler.intermediate.code.TryIntermediate)

Example 2 with TryIntermediate

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);
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) CatchIntermediate(org.candle.decompiler.intermediate.code.CatchIntermediate) TryIntermediate(org.candle.decompiler.intermediate.code.TryIntermediate) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 3 with TryIntermediate

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;
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) TryIntermediate(org.candle.decompiler.intermediate.code.TryIntermediate) LinkedList(java.util.LinkedList)

Example 4 with TryIntermediate

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());
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) TreeSet(java.util.TreeSet) CatchIntermediate(org.candle.decompiler.intermediate.code.CatchIntermediate) TryIntermediate(org.candle.decompiler.intermediate.code.TryIntermediate) IntermediateComparator(org.candle.decompiler.intermediate.code.IntermediateComparator) InstructionHandle(org.apache.bcel.generic.InstructionHandle) HashSet(java.util.HashSet)

Example 5 with TryIntermediate

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);
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) HashMap(java.util.HashMap) BlockRangeComparator(org.candle.decompiler.intermediate.code.BlockRangeComparator) TryIntermediate(org.candle.decompiler.intermediate.code.TryIntermediate) InstructionHandle(org.apache.bcel.generic.InstructionHandle) BlockRange(org.candle.decompiler.intermediate.code.BlockRange) TreeSet(java.util.TreeSet) FinallyIntermediate(org.candle.decompiler.intermediate.code.FinallyIntermediate) List(java.util.List) LinkedList(java.util.LinkedList) CodeExceptionGen(org.apache.bcel.generic.CodeExceptionGen)

Aggregations

TryIntermediate (org.candle.decompiler.intermediate.code.TryIntermediate)6 AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)5 InstructionHandle (org.apache.bcel.generic.InstructionHandle)3 CatchIntermediate (org.candle.decompiler.intermediate.code.CatchIntermediate)3 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 TreeSet (java.util.TreeSet)2 FinallyIntermediate (org.candle.decompiler.intermediate.code.FinallyIntermediate)2 List (java.util.List)1 CodeExceptionGen (org.apache.bcel.generic.CodeExceptionGen)1 BlockRange (org.candle.decompiler.intermediate.code.BlockRange)1 BlockRangeComparator (org.candle.decompiler.intermediate.code.BlockRangeComparator)1 GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)1 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)1 IntermediateEdge (org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)1