Search in sources :

Example 16 with StatementIntermediate

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

the class MethodIntermediateVisitor method visitIINC.

public void visitIINC(IINC instruction) {
    // increment variable.
    int index = instruction.getIndex();
    IntermediateVariable iv = context.getVariableResolver().getLocalVariable(index, context.getCurrentInstruction().getPosition());
    Variable variable = null;
    if (iv == null) {
        // generate IV.
        iv = context.getVariableResolver().addLocalVariable(index, context.getCurrentInstruction(), instruction.getType(context.getMethodGen().getConstantPool()));
        variable = new GeneratedVariable(context.getCurrentInstruction(), iv.getType(), iv.getName());
    } else {
        variable = new Variable(context.getCurrentInstruction(), iv.getType(), iv.getName());
    }
    // now, how much does it increment by?
    int incrementBy = instruction.getIncrement();
    StringBuilder incrementerBuilder = new StringBuilder(iv.getName());
    if (incrementBy == 1) {
        incrementerBuilder.append("++");
    } else if (incrementBy == -1) {
        incrementerBuilder.append("--");
    } else if (incrementBy < 1) {
        incrementerBuilder.append(" -= ").append((-1 * incrementBy));
    } else {
        incrementerBuilder.append(" += ").append(incrementBy);
    }
    Expression exp = new Increment(context.getCurrentInstruction(), variable, Type.INT, incrementerBuilder.toString());
    context.pushIntermediateToInstruction(new StatementIntermediate(context.getCurrentInstruction(), exp));
}
Also used : IntermediateVariable(org.candle.decompiler.intermediate.IntermediateVariable) GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) Variable(org.candle.decompiler.intermediate.expression.Variable) IntermediateVariable(org.candle.decompiler.intermediate.IntermediateVariable) GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) TypedExpression(org.candle.decompiler.intermediate.expression.TypedExpression) Expression(org.candle.decompiler.intermediate.expression.Expression) Increment(org.candle.decompiler.intermediate.expression.Increment) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate)

Example 17 with StatementIntermediate

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

the class MethodIntermediateVisitor method visitStoreInstruction.

public void visitStoreInstruction(StoreInstruction instruction) {
    Expression right = this.context.getExpressions().pop();
    Type type = instruction.getType(context.getMethodGen().getConstantPool());
    // first, check to see whether the variable currently has been declared.
    // this would be the case if we don't get null when looking up the local variable.
    int pc = context.getCurrentInstruction().getPosition();
    int lvtIndex = instruction.getIndex();
    IntermediateVariable iv = context.getVariableResolver().getLocalVariable(lvtIndex, pc);
    // if the variable is not null, it is declared.
    boolean declared = (iv != null);
    Variable variable = null;
    if (!declared) {
        // look it up from the next phase code.
        pc = this.context.getCurrentInstruction().getNext().getPosition();
        iv = context.getVariableResolver().getLocalVariable(lvtIndex, pc);
        if (iv == null) {
            // probably need to create a variable for enhanced loops...
            LOG.debug("Adding index: " + instruction.getIndex() + " as: " + type);
            // try and resolve the type for the variable from the right hand side.
            if (type == Type.OBJECT) {
                if (right instanceof TypedExpression) {
                    type = ((TypedExpression) right).getType();
                }
            }
            // generate variable name...
            iv = context.getVariableResolver().addLocalVariable(instruction.getIndex(), context.getCurrentInstruction(), type);
            variable = new GeneratedVariable(context.getCurrentInstruction(), iv.getType(), iv.getName());
        }
    }
    // create the variable.
    if (variable == null) {
        variable = new Variable(context.getCurrentInstruction(), iv.getType(), iv.getName());
    }
    // create the assignment.
    Assignment assignment = new Assignment(context.getCurrentInstruction(), variable, right);
    Expression left = null;
    if (declared) {
        left = assignment;
    } else {
        // if it is currently not declared... create the declaration.
        left = new Declaration(context.getCurrentInstruction(), variable, assignment);
    }
    StatementIntermediate cl = new StatementIntermediate(context.getCurrentInstruction(), left);
    context.pushIntermediateToInstruction(cl);
    LOG.debug("Stored.");
}
Also used : Assignment(org.candle.decompiler.intermediate.expression.Assignment) OperationType(org.candle.decompiler.intermediate.expression.OperationType) ArithmeticType(org.candle.decompiler.intermediate.expression.ArithmeticType) IntermediateVariable(org.candle.decompiler.intermediate.IntermediateVariable) GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) Variable(org.candle.decompiler.intermediate.expression.Variable) IntermediateVariable(org.candle.decompiler.intermediate.IntermediateVariable) GeneratedVariable(org.candle.decompiler.intermediate.expression.GeneratedVariable) TypedExpression(org.candle.decompiler.intermediate.expression.TypedExpression) Expression(org.candle.decompiler.intermediate.expression.Expression) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate) Declaration(org.candle.decompiler.intermediate.expression.Declaration) TypedExpression(org.candle.decompiler.intermediate.expression.TypedExpression)

Example 18 with StatementIntermediate

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

the class MethodIntermediateVisitor method processArrayStore.

protected void processArrayStore() {
    Expression value = context.getExpressions().pop();
    Expression arrayPosition = context.getExpressions().pop();
    Expression arrayReference = context.getExpressions().pop();
    ArrayAccess arrayPositionReference = new ArrayAccess(context.getCurrentInstruction(), arrayReference, arrayPosition);
    Assignment assignment = new Assignment(context.getCurrentInstruction(), arrayPositionReference, value);
    StatementIntermediate si = new StatementIntermediate(context.getCurrentInstruction(), assignment);
    // add it to the intermediate lines.
    context.pushIntermediateToInstruction(si);
}
Also used : Assignment(org.candle.decompiler.intermediate.expression.Assignment) ArrayAccess(org.candle.decompiler.intermediate.expression.ArrayAccess) TypedExpression(org.candle.decompiler.intermediate.expression.TypedExpression) Expression(org.candle.decompiler.intermediate.expression.Expression) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate)

Example 19 with StatementIntermediate

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

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

StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)24 AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)11 Expression (org.candle.decompiler.intermediate.expression.Expression)10 TypedExpression (org.candle.decompiler.intermediate.expression.TypedExpression)9 Declaration (org.candle.decompiler.intermediate.expression.Declaration)7 ArithmeticType (org.candle.decompiler.intermediate.expression.ArithmeticType)5 Assignment (org.candle.decompiler.intermediate.expression.Assignment)5 OperationType (org.candle.decompiler.intermediate.expression.OperationType)5 GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)4 GeneratedVariable (org.candle.decompiler.intermediate.expression.GeneratedVariable)4 MethodInvocation (org.candle.decompiler.intermediate.expression.MethodInvocation)4 Variable (org.candle.decompiler.intermediate.expression.Variable)4 ArrayList (java.util.ArrayList)3 IntermediateVariable (org.candle.decompiler.intermediate.IntermediateVariable)3 Throw (org.candle.decompiler.intermediate.expression.Throw)3 TreeSet (java.util.TreeSet)2 BooleanBranchIntermediate (org.candle.decompiler.intermediate.code.BooleanBranchIntermediate)2 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)2 EnhancedForIntermediate (org.candle.decompiler.intermediate.code.loop.EnhancedForIntermediate)2 ArrayAccess (org.candle.decompiler.intermediate.expression.ArrayAccess)2