Search in sources :

Example 6 with Declaration

use of org.candle.decompiler.intermediate.expression.Declaration in project candle-decompiler by bradsdavis.

the class WhileToForLoopIncrement method visitWhileIntermediate.

@Override
public void visitWhileIntermediate(WhileIntermediate line) {
    List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
    // look at the predecessor lines;  validate there are only 2 predecessors.
    if (predecessors.size() == 2) {
        StatementIntermediate declaration = null;
        StatementIntermediate iteration = null;
        for (AbstractIntermediate predecessor : predecessors) {
            if (comparator.before(predecessor, line)) {
                if (predecessor instanceof StatementIntermediate) {
                    declaration = (StatementIntermediate) predecessor;
                    continue;
                } else {
                    // a for loop.
                    return;
                }
            }
            // if the
            if (comparator.after(predecessor, line)) {
                if (predecessor instanceof StatementIntermediate) {
                    iteration = (StatementIntermediate) predecessor;
                } else {
                    return;
                }
            }
        }
        // at this point, both should be set.
        if (declaration != null && iteration != null) {
            if (declaration.getExpression() instanceof Declaration) {
                Declaration declarationExpression = (Declaration) declaration.getExpression();
                if (iteration.getExpression() instanceof Increment) {
                    Increment incrementExpression = (Increment) iteration.getExpression();
                    if (incrementExpression.getVariable().getType().equals(declarationExpression.getVariable().getType())) {
                        // now check names.
                        if (incrementExpression.getVariable().getName().equals(declarationExpression.getVariable().getName())) {
                            // we can actually convert this to a for loop.
                            ForIntermediate forIntermediate = new ForIntermediate(line, declarationExpression, incrementExpression);
                            // forIntermediate.setTrueBranch(line.getTrueBranch());
                            // forIntermediate.setFalseBranch(line.getFalseBranch());
                            igc.getGraph().addVertex(forIntermediate);
                            igc.redirectSuccessors(line, forIntermediate);
                            igc.redirectPredecessors(iteration, forIntermediate);
                            igc.redirectPredecessors(declaration, forIntermediate);
                            // remove the while loop, increment, and declaration.
                            igc.getGraph().removeVertex(line);
                            igc.getGraph().removeVertex(declaration);
                            igc.getGraph().removeVertex(iteration);
                        }
                    }
                }
            }
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) Increment(org.candle.decompiler.intermediate.expression.Increment) Declaration(org.candle.decompiler.intermediate.expression.Declaration) ForIntermediate(org.candle.decompiler.intermediate.code.loop.ForIntermediate)

Example 7 with Declaration

use of org.candle.decompiler.intermediate.expression.Declaration in project candle-decompiler by bradsdavis.

the class ConstantArrayCompressor method visitStatementIntermediate.

@Override
public void visitStatementIntermediate(StatementIntermediate line) {
    // first, look for the
    Assignment assignment = extractConstantArrayAssignment(line.getExpression());
    if (assignment == null) {
        return;
    }
    // at this point, we know both the statement is an assignment, and that the left assignment is to a constant array value.
    // find the one that is right before the array assignment.
    Declaration declaration = extractNextDeclaration(line);
    // if we didn't find the declaration, this must not be the constant array assignment proceeding the declaration.
    if (declaration == null) {
        return;
    }
    // check the right hand of the declaration...
    if (!(declaration.getAssignment().getRightHandSide() instanceof NewConstantArrayInstance)) {
        return;
    }
    NewConstantArrayInstance ncai = (NewConstantArrayInstance) declaration.getAssignment().getRightHandSide();
    Expression countExpression = ncai.getCount();
    AbstractIntermediate current = line;
    Map<Integer, Expression> values = new HashMap<Integer, Expression>();
    collectConstantAssignments(current, values);
    // create a new array...
    Integer count = toInteger(countExpression);
    List<Expression> expressions = new ArrayList<Expression>(count);
    for (int i = 0, j = count; i < j; i++) {
        Expression exp = null;
        if (values.containsKey(i)) {
            exp = values.get(i);
        } else {
            exp = new Resolved(ncai.getInstructionHandle(), Type.NULL, "null");
        }
        expressions.add(i, exp);
    }
    // ok, we have the stack... now we need to just create a new expression.
    // create the contant...
    ConstantArray constantArray = new ConstantArray(declaration.getAssignment().getRightHandSide().getInstructionHandle(), expressions);
    declaration.getAssignment().setRightHandSide(constantArray);
    // excellent.  we have reordered the statements into the appropriate ContantArray assignment.  Now, we need to remove the dead nodes and heal the graph.
    AbstractIntermediate next = Graphs.successorListOf(igc.getGraph(), line).get(0);
    // loop through the dead elements...
    // we know the number of dead items is equal to the number of values we found.
    healGraph(line, next, values.size());
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) ConstantArray(org.candle.decompiler.intermediate.expression.ConstantArray) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) NewConstantArrayInstance(org.candle.decompiler.intermediate.expression.NewConstantArrayInstance) Assignment(org.candle.decompiler.intermediate.expression.Assignment) Expression(org.candle.decompiler.intermediate.expression.Expression) Resolved(org.candle.decompiler.intermediate.expression.Resolved) Declaration(org.candle.decompiler.intermediate.expression.Declaration)

Example 8 with Declaration

use of org.candle.decompiler.intermediate.expression.Declaration 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 9 with Declaration

use of org.candle.decompiler.intermediate.expression.Declaration in project candle-decompiler by bradsdavis.

the class ArrayForToEnhancedFor method extractGeneratedVariableDeclaration.

private GeneratedVariable extractGeneratedVariableDeclaration(Expression expression) {
    if (expression instanceof Declaration) {
        Declaration dec = (Declaration) expression;
        Variable var = dec.getVariable();
        if (var instanceof GeneratedVariable) {
            return (GeneratedVariable) var;
        }
    }
    return null;
}
Also used : GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) Variable(org.candle.decompiler.intermediate.expression.Variable) GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) Declaration(org.candle.decompiler.intermediate.expression.Declaration)

Example 10 with Declaration

use of org.candle.decompiler.intermediate.expression.Declaration in project candle-decompiler by bradsdavis.

the class ArrayForToEnhancedFor method extractExpressionFromGeneratedArrayAssignment.

private Expression extractExpressionFromGeneratedArrayAssignment(AbstractIntermediate declaration) {
    if (declaration instanceof StatementIntermediate) {
        StatementIntermediate si = (StatementIntermediate) declaration;
        Declaration dec = (Declaration) si.getExpression();
        return dec.getAssignment().getRightHandSide();
    }
    return null;
}
Also used : StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) Declaration(org.candle.decompiler.intermediate.expression.Declaration)

Aggregations

Declaration (org.candle.decompiler.intermediate.expression.Declaration)10 StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)7 AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)6 GeneratedVariable (org.candle.decompiler.intermediate.expression.GeneratedVariable)4 Variable (org.candle.decompiler.intermediate.expression.Variable)4 Expression (org.candle.decompiler.intermediate.expression.Expression)3 EnhancedForIntermediate (org.candle.decompiler.intermediate.code.loop.EnhancedForIntermediate)2 Assignment (org.candle.decompiler.intermediate.expression.Assignment)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ArrayType (org.apache.bcel.generic.ArrayType)1 IntermediateVariable (org.candle.decompiler.intermediate.IntermediateVariable)1 CatchIntermediate (org.candle.decompiler.intermediate.code.CatchIntermediate)1 ForIntermediate (org.candle.decompiler.intermediate.code.loop.ForIntermediate)1 ArithmeticType (org.candle.decompiler.intermediate.expression.ArithmeticType)1 ArrayAccess (org.candle.decompiler.intermediate.expression.ArrayAccess)1 ConstantArray (org.candle.decompiler.intermediate.expression.ConstantArray)1 Increment (org.candle.decompiler.intermediate.expression.Increment)1 MethodInvocation (org.candle.decompiler.intermediate.expression.MethodInvocation)1 NewConstantArrayInstance (org.candle.decompiler.intermediate.expression.NewConstantArrayInstance)1