Search in sources :

Example 41 with AbstractIntermediate

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

the class ConstantArrayCompressor method healGraph.

public void healGraph(AbstractIntermediate current, AbstractIntermediate next, int deadElements) {
    for (int i = 0, j = deadElements; i < j; i++) {
        // if this is the last element, redirect it's predecessors to the next node.
        if (i + 1 == j) {
            igc.redirectPredecessors(current, next);
        }
        AbstractIntermediate temp = null;
        // move back..
        List<AbstractIntermediate> predecessor = Graphs.predecessorListOf(igc.getGraph(), current);
        if (predecessor.size() > 0) {
            temp = predecessor.get(0);
        }
        // retract current..
        igc.getGraph().removeVertex(current);
        // set next...
        current = temp;
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate)

Example 42 with AbstractIntermediate

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

the class ElseIf method visitIfIntermediate.

@Override
public void visitIfIntermediate(IfIntermediate line) {
    // check to see if the predecessor is an if block.
    List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
    if (predecessors.size() != 1) {
        return;
    }
    // otherwise, see if it is another IF.
    if (predecessors.get(0) instanceof BooleanBranchIntermediate) {
        // check to see whether it is on the ELSE side.
        BooleanBranchIntermediate parent = (BooleanBranchIntermediate) predecessors.get(0);
        LOG.debug(parent.getClass());
        if (!(parent instanceof IfIntermediate)) {
            return;
        }
        if (igc.getFalseTarget(parent) == line) {
            // then this could be an IF block.
            ElseIfIntermediate eii = new ElseIfIntermediate(line.getInstruction(), line.getExpression());
            igc.getGraph().addVertex(eii);
            igc.redirectPredecessors(line, eii);
            igc.redirectSuccessors(line, eii);
            igc.getGraph().removeVertex(line);
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) IfIntermediate(org.candle.decompiler.intermediate.code.conditional.IfIntermediate) ElseIfIntermediate(org.candle.decompiler.intermediate.code.conditional.ElseIfIntermediate) BooleanBranchIntermediate(org.candle.decompiler.intermediate.code.BooleanBranchIntermediate) ElseIfIntermediate(org.candle.decompiler.intermediate.code.conditional.ElseIfIntermediate)

Example 43 with AbstractIntermediate

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

the class ArrayForToEnhancedFor method visitForIntermediate.

@Override
public void visitForIntermediate(ForIntermediate line) {
    // we need to look at the previous 2 statements and the first statement child.
    AbstractIntermediate arrayLenthCandidate = getForExteriorPredecessor(line);
    // check that the array length candidate's declared length variable is used in the for's condition.
    AbstractIntermediate tempArrayCandidate = null;
    AbstractIntermediate firstChild = igc.getTrueTarget(line);
    if (arrayLenthCandidate != null) {
        tempArrayCandidate = getSinglePredecessor(arrayLenthCandidate);
    }
    // if either of these are null, then this doesn't match.
    if (arrayLenthCandidate == null || tempArrayCandidate == null) {
        return;
    }
    GeneratedVariable generatedArrayLength = extractGeneratedVariableDeclaration(arrayLenthCandidate);
    GeneratedVariable generatedArrayReference = extractGeneratedVariableDeclaration(tempArrayCandidate);
    GeneratedVariable arrayIteratorValue = extractGeneratedVariableDeclaration(line.getInit());
    if (generatedArrayLength == null || generatedArrayReference == null || arrayIteratorValue == null) {
        return;
    }
    if (generatedArrayLength.getType() != Type.INT) {
        if (!(generatedArrayReference.getType() instanceof ArrayType)) {
            return;
        }
        if (arrayIteratorValue.getType() != Type.INT) {
            return;
        }
    }
    // great; at this point we know the pattern matches.  check the next statement to see if the transformation is possible.
    // format should be: 40 : GENERATED_ARRAY_REFERENCE_TYPE i = GENERATED_ARRAY_REFERENCE[ARRAY_ITERATOR_VALUE] |
    StatementIntermediate childDeclarationStatement = ((StatementIntermediate) firstChild);
    Declaration childDeclaration = (Declaration) childDeclarationStatement.getExpression();
    if (firstMatchesGeneratedVariables(childDeclarationStatement, generatedArrayReference, arrayIteratorValue)) {
        LOG.debug("Likely a enhanced for loop for array: " + generatedArrayLength + " , " + generatedArrayReference);
        // we are good to go here.  Now we just need to reorganize the graph.  Start by creating the new enhanced for loop.
        EnhancedForIntermediate efl = new EnhancedForIntermediate(line.getInstruction(), line.getConditionalIntermediate(), childDeclaration.getVariable(), extractExpressionFromGeneratedArrayAssignment(tempArrayCandidate));
        // efl.setTrueBranch(line.getTrueBranch());
        // efl.setFalseBranch(line.getFalseBranch());
        // add the new node...
        this.igc.getGraph().addVertex(efl);
        // now, we just need to redirect.
        igc.redirectPredecessors(tempArrayCandidate, efl);
        igc.redirectPredecessors(line, efl);
        igc.redirectSuccessors(line, efl);
        AbstractIntermediate nextChild = getSingleSuccessor(firstChild);
        igc.redirectPredecessors(firstChild, nextChild);
        // remove line.
        igc.getGraph().removeVertex(line);
        igc.getGraph().removeVertex(tempArrayCandidate);
        igc.getGraph().removeVertex(firstChild);
        igc.getGraph().removeVertex(arrayLenthCandidate);
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) ArrayType(org.apache.bcel.generic.ArrayType) GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) EnhancedForIntermediate(org.candle.decompiler.intermediate.code.loop.EnhancedForIntermediate) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) Declaration(org.candle.decompiler.intermediate.expression.Declaration)

Example 44 with AbstractIntermediate

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

Example 45 with AbstractIntermediate

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

the class IntermediateGraphFactory method visitGoToIntermediate.

@Override
public void visitGoToIntermediate(GoToIntermediate line) {
    // find how that actually maps to the abstract line..
    AbstractIntermediate intermediate = ilc.getNext(line);
    igc.getGraph().addVertex(intermediate);
    // line.setTarget(intermediate);
    // now, we just add this into the graph.
    igc.getGraph().addEdge(line, intermediate);
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate)

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