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);
}
}
}
}
}
}
}
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());
}
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);
}
}
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;
}
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;
}
Aggregations