Search in sources :

Example 1 with GoToIntermediate

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

the class IntermediateLineContext method getNext.

public AbstractIntermediate getNext(AbstractIntermediate ai) {
    if (ai instanceof GoToIntermediate) {
        BranchHandle bh = (BranchHandle) ai.getInstruction();
        Integer position = bh.getTarget().getPosition();
        return getNext(position);
    }
    //otherwise, get it from the next position.
    InstructionHandle next = ai.getInstruction().getNext();
    //return either null, if next is null (last next).  Otherwise, send next position.
    return next == null ? null : getNext(next.getPosition());
}
Also used : GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) BranchHandle(org.apache.bcel.generic.BranchHandle) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 2 with GoToIntermediate

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

the class RetractDuplicateFinally method processTry.

protected void processTry(TryIntermediate tryIntermediate, FinallyIntermediate finallyIntermediate, Set<Integer> offsets) {
    //ok, now let's handle the try...
    InstructionHandle end = tryIntermediate.getBlockRange().getEnd();
    //next should be GOTO.
    AbstractIntermediate tryEndNode = igc.findNextNode(end);
    AbstractIntermediate gotoIntermediate = null;
    //check to see if this is loop...
    if (tryEndNode instanceof StatementIntermediate) {
        LOG.debug("Position: " + tryEndNode.getInstruction().getPosition() + " Value: " + tryEndNode);
        gotoIntermediate = igc.getSingleSuccessor(tryEndNode);
    } else if (tryEndNode instanceof BooleanBranchIntermediate) {
        BooleanBranchIntermediate bbi = (BooleanBranchIntermediate) tryEndNode;
        //find higher target...
        AbstractIntermediate trueTarget = igc.getTrueTarget(bbi);
        AbstractIntermediate falseTarget = igc.getFalseTarget(bbi);
        int trueTargetPosition = trueTarget.getInstruction().getPosition();
        int falseTargetPosition = falseTarget.getInstruction().getPosition();
        gotoIntermediate = (trueTargetPosition > falseTargetPosition) ? trueTarget : falseTarget;
    }
    //validate it is a GOTO.
    if (!(gotoIntermediate instanceof GoToIntermediate)) {
        LOG.warn("Expected GOTO.  But this isn't: " + gotoIntermediate);
    } else {
        AbstractIntermediate tryFinallyFirst = igc.getSingleSuccessor(gotoIntermediate);
        eliminateNode(tryFinallyFirst, offsets);
        //now, eliminate the GOTO.
        igc.getGraph().removeVertex(gotoIntermediate);
        igc.getGraph().addEdge(tryIntermediate, finallyIntermediate);
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) BooleanBranchIntermediate(org.candle.decompiler.intermediate.code.BooleanBranchIntermediate) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 3 with GoToIntermediate

use of org.candle.decompiler.intermediate.code.GoToIntermediate 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) TreeSet(java.util.TreeSet) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) 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 4 with GoToIntermediate

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

the class LoopGotoToBreak method processLoop.

public void processLoop(WhileIntermediate loop) {
    //get the target... then look for GOTO statements going into the target that are within the range 
    //of the loop.
    TreeSet<AbstractIntermediate> loopElements = (TreeSet<AbstractIntermediate>) igc.getOrderedIntermediate().subSet(igc.getTrueTarget(loop), true, igc.getFalseTarget(loop), false);
    List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), igc.getFalseTarget(loop));
    Set<GoToIntermediate> gotoToBreak = new HashSet<GoToIntermediate>();
    for (AbstractIntermediate predecessor : predecessors) {
        if (predecessor instanceof GoToIntermediate) {
            if (loopElements.contains(predecessor)) {
                gotoToBreak.add((GoToIntermediate) predecessor);
            }
        }
    }
    //now, we create new statements.
    for (GoToIntermediate gotoToBreakStatement : gotoToBreak) {
        transformGotoToBreak(gotoToBreakStatement);
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) TreeSet(java.util.TreeSet) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) HashSet(java.util.HashSet)

Example 5 with GoToIntermediate

use of org.candle.decompiler.intermediate.code.GoToIntermediate 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)

Aggregations

GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)10 AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)8 TreeSet (java.util.TreeSet)6 StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)4 InstructionHandle (org.apache.bcel.generic.InstructionHandle)3 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)3 HashSet (java.util.HashSet)2 BranchHandle (org.apache.bcel.generic.BranchHandle)2 BooleanBranchIntermediate (org.candle.decompiler.intermediate.code.BooleanBranchIntermediate)2 IntermediateEdge (org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)2 CatchIntermediate (org.candle.decompiler.intermediate.code.CatchIntermediate)1 TryIntermediate (org.candle.decompiler.intermediate.code.TryIntermediate)1 ElseIfIntermediate (org.candle.decompiler.intermediate.code.conditional.ElseIfIntermediate)1 IfIntermediate (org.candle.decompiler.intermediate.code.conditional.IfIntermediate)1 WhileIntermediate (org.candle.decompiler.intermediate.code.loop.WhileIntermediate)1 Continue (org.candle.decompiler.intermediate.expression.Continue)1 Return (org.candle.decompiler.intermediate.expression.Return)1 Throw (org.candle.decompiler.intermediate.expression.Throw)1 CycleDetector (org.jgrapht.alg.CycleDetector)1 BreadthFirstIterator (org.jgrapht.traverse.BreadthFirstIterator)1