Search in sources :

Example 1 with AbstractIntermediate

use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.

the class Else method visitAbstractIntermediate.

@Override
public void visitAbstractIntermediate(AbstractIntermediate line) {
    // for all lines...
    List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
    if (predecessors.size() == 0) {
        return;
    }
    TreeSet<GoToIntermediate> gotoIntermediates = new TreeSet<GoToIntermediate>(new IntermediateComparator());
    for (AbstractIntermediate predecessor : predecessors) {
        if (predecessor instanceof GoToIntermediate) {
            gotoIntermediates.add((GoToIntermediate) predecessor);
        }
    }
    if (gotoIntermediates.size() == 0) {
        return;
    }
    // now, the largest should be...
    GoToIntermediate maxGotoForBranch = gotoIntermediates.pollLast();
    if (maxGotoForBranch.getInstruction().getPosition() > line.getInstruction().getPosition()) {
        return;
    }
    // find the element directly after this one...
    SortedSet<AbstractIntermediate> elseBranchElements = igc.getOrderedIntermediate().subSet(maxGotoForBranch, false, line, false);
    AbstractIntermediate ai = igc.getSinglePredecessor(elseBranchElements.first());
    if (!(ai instanceof IfIntermediate || ai instanceof ElseIfIntermediate)) {
        return;
    }
    // get the first element...
    if (elseBranchElements.size() > 0) {
        AbstractIntermediate firstElseBlockElement = elseBranchElements.first();
        if (firstElseBlockElement instanceof StatementIntermediate) {
            // we should add the ELSE right away...
            addElseBlock(firstElseBlockElement, maxGotoForBranch);
            return;
        }
        if (firstElseBlockElement instanceof BooleanBranchIntermediate) {
            // only add ELSE if the child of conditional doesn't go to the target.
            BooleanBranchIntermediate ci = (BooleanBranchIntermediate) firstElseBlockElement;
            if (igc.getFalseTarget(ci) == line || igc.getTrueTarget(ci) == line) {
                // do nothing.
                return;
            }
            // else if this is an ElseIf, probably should be an IF.
            if (firstElseBlockElement instanceof ElseIfIntermediate) {
                IfIntermediate ifIntermediate = new IfIntermediate(firstElseBlockElement.getInstruction(), ((BooleanBranchIntermediate) firstElseBlockElement).getExpression());
                igc.getGraph().addVertex(ifIntermediate);
                igc.redirectPredecessors(firstElseBlockElement, ifIntermediate);
                igc.redirectSuccessors(firstElseBlockElement, ifIntermediate);
                igc.getGraph().removeVertex(firstElseBlockElement);
                // add the else between this conditional.
                addElseBlock(ifIntermediate, maxGotoForBranch);
            }
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) TreeSet(java.util.TreeSet) IfIntermediate(org.candle.decompiler.intermediate.code.conditional.IfIntermediate) ElseIfIntermediate(org.candle.decompiler.intermediate.code.conditional.ElseIfIntermediate) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) IntermediateComparator(org.candle.decompiler.intermediate.code.IntermediateComparator) BooleanBranchIntermediate(org.candle.decompiler.intermediate.code.BooleanBranchIntermediate) ElseIfIntermediate(org.candle.decompiler.intermediate.code.conditional.ElseIfIntermediate)

Example 2 with AbstractIntermediate

use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.

the class IntermediateGraphWriter method process.

@Override
public void process() {
    if (directory == null) {
        return;
    }
    File a = new File(directory.getAbsolutePath() + File.separator + name);
    LOG.debug("Instruction Graph: " + a.getAbsolutePath());
    Writer x;
    try {
        x = new FileWriter(a);
        DOTExporter<AbstractIntermediate, IntermediateEdge> dot = new DOTExporter<AbstractIntermediate, IntermediateEdge>(new IntegerNameProvider<AbstractIntermediate>(), new IntermediateLabelProvider(), new IntermediateEdgeProvider(), new IntermediateVertexAttributeProvider(), new InstructionEdgeAttributeProvider());
        dot.export(x, igc.getGraph());
    } catch (IOException e) {
        e.printStackTrace();
    }
    LOG.debug("End Instruction Graph ======");
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) DOTExporter(org.jgrapht.ext.DOTExporter) IntermediateEdgeProvider(org.candle.decompiler.intermediate.graph.edge.IntermediateEdgeProvider) FileWriter(java.io.FileWriter) IOException(java.io.IOException) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge) IntermediateVertexAttributeProvider(org.candle.decompiler.intermediate.graph.IntermediateVertexAttributeProvider) IntermediateLabelProvider(org.candle.decompiler.intermediate.graph.IntermediateLabelProvider) InstructionEdgeAttributeProvider(org.candle.decompiler.instruction.graph.edge.InstructionEdgeAttributeProvider) File(java.io.File) FileWriter(java.io.FileWriter) Writer(java.io.Writer)

Example 3 with AbstractIntermediate

use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.

the class RetractDuplicateFinally method eliminateNode.

protected void eliminateNode(AbstractIntermediate first, Set<Integer> offsets) {
    InstructionHandle ih = first.getInstruction();
    int position = first.getInstruction().getPosition();
    for (Integer offset : offsets) {
        int target = position + offset;
        ih = igc.getInstructionHandle(target);
        if (ih == null) {
            LOG.warn("Not found expected InstructionHandle: " + (position + offset));
            continue;
        }
        // loop through...
        AbstractIntermediate ai = igc.findNextNode(ih);
        if (ai.getInstruction().getPosition() == target) {
            igc.getGraph().removeVertex(ai);
        } else {
            LOG.warn("Did not find vertex: " + target);
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 4 with AbstractIntermediate

use of org.candle.decompiler.intermediate.code.AbstractIntermediate 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 5 with AbstractIntermediate

use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.

the class RetractDuplicateFinally method collectOffsets.

protected Set<Integer> collectOffsets(AbstractIntermediate line) {
    // this is the finally template.
    AbstractIntermediate first = igc.getSingleSuccessor(line);
    // now, store the instruction position.
    int position = first.getInstruction().getPosition();
    BreadthFirstIterator<AbstractIntermediate, IntermediateEdge> bfi = new BreadthFirstIterator<AbstractIntermediate, IntermediateEdge>(igc.getGraph(), first);
    Set<Integer> offsets = new TreeSet<Integer>();
    while (bfi.hasNext()) {
        AbstractIntermediate next = bfi.next();
        int nextPosition = next.getInstruction().getPosition();
        int offset = nextPosition - position;
        LOG.debug("Offset: " + offset);
        offsets.add(offset);
    }
    return offsets;
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) BreadthFirstIterator(org.jgrapht.traverse.BreadthFirstIterator) TreeSet(java.util.TreeSet) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)

Aggregations

AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)50 StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)11 InstructionHandle (org.apache.bcel.generic.InstructionHandle)9 TreeSet (java.util.TreeSet)8 GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)8 HashSet (java.util.HashSet)6 CatchIntermediate (org.candle.decompiler.intermediate.code.CatchIntermediate)6 Declaration (org.candle.decompiler.intermediate.expression.Declaration)6 IntermediateEdge (org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)6 TryIntermediate (org.candle.decompiler.intermediate.code.TryIntermediate)5 HashMap (java.util.HashMap)4 LinkedList (java.util.LinkedList)4 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)4 BooleanBranchIntermediate (org.candle.decompiler.intermediate.code.BooleanBranchIntermediate)3 FinallyIntermediate (org.candle.decompiler.intermediate.code.FinallyIntermediate)3 ArrayList (java.util.ArrayList)2 BranchHandle (org.apache.bcel.generic.BranchHandle)2 CodeExceptionGen (org.apache.bcel.generic.CodeExceptionGen)2 ElseIfBlock (org.candle.decompiler.ast.conditional.ElseIfBlock)2 CaseIntermediate (org.candle.decompiler.intermediate.code.CaseIntermediate)2