Search in sources :

Example 1 with IntermediateComparator

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

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

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

the class BlockVisitor method visitTryIntermediate.

@Override
public void visitTryIntermediate(TryIntermediate line) {
    if (seen.contains(line)) {
        //do nothing.
        return;
    } else {
        seen.add(line);
    }
    //set current block...
    TryBlock tryBlock = new TryBlock(line);
    //add it as a child of current..
    this.current.addChild(tryBlock);
    //set the current...
    this.current = tryBlock;
    //now, get the nested blocks...
    List<AbstractIntermediate> successors = getUnseenSuccessors(line);
    AbstractIntermediate inner = null;
    List<AbstractIntermediate> catchBlocks = new LinkedList<AbstractIntermediate>();
    AbstractIntermediate finallyIntermediate = null;
    //find the non-catch/finally...
    for (AbstractIntermediate successor : successors) {
        if (successor instanceof CatchIntermediate) {
            catchBlocks.add(successor);
        } else if (successor instanceof FinallyIntermediate) {
            finallyIntermediate = successor;
        } else {
            if (inner != null) {
                throw new IllegalStateException("Inner direction already set.");
            }
            inner = successor;
        }
    }
    Collections.sort(catchBlocks, new IntermediateComparator());
    if (inner == null) {
        throw new IllegalStateException("Inner is not set.");
    }
    inner.accept(this);
    //set the current up.
    moveUp();
    for (AbstractIntermediate catchBlock : catchBlocks) {
        current = tryBlock;
        catchBlock.accept(this);
    }
    if (finallyIntermediate != null) {
        current = tryBlock;
        finallyIntermediate.accept(this);
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) CatchIntermediate(org.candle.decompiler.intermediate.code.CatchIntermediate) FinallyIntermediate(org.candle.decompiler.intermediate.code.FinallyIntermediate) TryBlock(org.candle.decompiler.ast.tcf.TryBlock) IntermediateComparator(org.candle.decompiler.intermediate.code.IntermediateComparator) LinkedList(java.util.LinkedList)

Example 4 with IntermediateComparator

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

the class ConditionToWhileLoop method visitBooleanBranchIntermediate.

@Override
public void visitBooleanBranchIntermediate(BooleanBranchIntermediate line) {
    List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
    CycleDetector<AbstractIntermediate, IntermediateEdge> cycleDetector = new CycleDetector<AbstractIntermediate, IntermediateEdge>(igc.getGraph());
    if (!cycleDetector.detectCyclesContainingVertex(line)) {
        return;
    }
    //first, determine if the condition has two incoming lines.
    if (predecessors.size() >= 2) {
        //check to see that 1 predecessor is a GOTO.
        TreeSet<GoToIntermediate> incomingGotoNonNested = new TreeSet<GoToIntermediate>(new IntermediateComparator());
        TreeSet<GoToIntermediate> incomingGotoNested = new TreeSet<GoToIntermediate>(new IntermediateComparator());
        GoToIntermediate nestedLine = null;
        AbstractIntermediate otherLine = null;
        //classify.
        for (AbstractIntermediate predecessor : predecessors) {
            //check to see if 1 is GOTO.
            if (predecessor instanceof GoToIntermediate) {
                if (isNested(line, predecessor)) {
                    incomingGotoNested.add((GoToIntermediate) predecessor);
                } else {
                    incomingGotoNonNested.add((GoToIntermediate) predecessor);
                }
                continue;
            } else {
                otherLine = predecessor;
            }
        }
        //if there are more than one GOTO statements that are not-nested, return.
        if (incomingGotoNonNested.size() > 1) {
            return;
        }
        nestedLine = getCandidateGoto(incomingGotoNonNested, incomingGotoNested);
        //stop if both conditions aren't met.
        if (nestedLine == null || otherLine == null) {
            return;
        }
        //check to validate that the GOTO instruction is less than the other incoming...
        if (comparator.before(otherLine, line)) {
            //take the lower condition...
            BranchHandle refHandle = null;
            if (comparator.before(nestedLine, line)) {
                refHandle = (BranchHandle) nestedLine.getInstruction();
            } else {
                refHandle = (BranchHandle) line.getInstruction();
            }
            WhileIntermediate whileIntermediate = new WhileIntermediate(refHandle, line);
            //add this to the graph.
            this.igc.getGraph().addVertex(whileIntermediate);
            //get the incoming from the goto...
            igc.redirectPredecessors(nestedLine, whileIntermediate);
            igc.redirectSuccessors(line, whileIntermediate);
            //now, create line from other to while.
            this.igc.getGraph().addEdge(otherLine, whileIntermediate);
            //now, remove the GOTO and Conditional Vertex from graph.
            igc.getGraph().removeVertex(nestedLine);
            igc.getGraph().removeVertex(line);
            //now, the other GOTO lines coming in should all be CONTINUE statements...
            for (GoToIntermediate gotoIntermediate : incomingGotoNested) {
                Continue continueExpression = new Continue(gotoIntermediate.getInstruction());
                StatementIntermediate continueIntermediate = new StatementIntermediate(gotoIntermediate.getInstruction(), continueExpression);
                //add the node...
                igc.getGraph().addVertex(continueIntermediate);
                igc.redirectPredecessors(gotoIntermediate, continueIntermediate);
                //remove vertex.
                igc.getGraph().removeVertex(gotoIntermediate);
                //now, add line to the loop.
                igc.getGraph().addEdge(continueIntermediate, whileIntermediate);
            }
            updateEdges(whileIntermediate);
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) WhileIntermediate(org.candle.decompiler.intermediate.code.loop.WhileIntermediate) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) BranchHandle(org.apache.bcel.generic.BranchHandle) IntermediateComparator(org.candle.decompiler.intermediate.code.IntermediateComparator) Continue(org.candle.decompiler.intermediate.expression.Continue) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge) CycleDetector(org.jgrapht.alg.CycleDetector) TreeSet(java.util.TreeSet) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate)

Aggregations

AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)4 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)4 TreeSet (java.util.TreeSet)3 GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)3 CatchIntermediate (org.candle.decompiler.intermediate.code.CatchIntermediate)2 StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)2 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 BranchHandle (org.apache.bcel.generic.BranchHandle)1 InstructionHandle (org.apache.bcel.generic.InstructionHandle)1 TryBlock (org.candle.decompiler.ast.tcf.TryBlock)1 BooleanBranchIntermediate (org.candle.decompiler.intermediate.code.BooleanBranchIntermediate)1 FinallyIntermediate (org.candle.decompiler.intermediate.code.FinallyIntermediate)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 IntermediateEdge (org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)1 CycleDetector (org.jgrapht.alg.CycleDetector)1