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