use of org.candle.decompiler.intermediate.code.IntermediateComparator in project candle-decompiler by bradsdavis.
the class Else method visitAbstractIntermediate.
@Override
public void visitAbstractIntermediate(AbstractIntermediate line) {
//for all lines...
List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
if (predecessors.size() == 0) {
return;
}
TreeSet<GoToIntermediate> gotoIntermediates = new TreeSet<GoToIntermediate>(new IntermediateComparator());
for (AbstractIntermediate predecessor : predecessors) {
if (predecessor instanceof GoToIntermediate) {
gotoIntermediates.add((GoToIntermediate) predecessor);
}
}
if (gotoIntermediates.size() == 0) {
return;
}
//now, the largest should be...
GoToIntermediate maxGotoForBranch = gotoIntermediates.pollLast();
if (maxGotoForBranch.getInstruction().getPosition() > line.getInstruction().getPosition()) {
return;
}
//find the element directly after this one...
SortedSet<AbstractIntermediate> elseBranchElements = igc.getOrderedIntermediate().subSet(maxGotoForBranch, false, line, false);
AbstractIntermediate ai = igc.getSinglePredecessor(elseBranchElements.first());
if (!(ai instanceof IfIntermediate || ai instanceof ElseIfIntermediate)) {
return;
}
//get the first element...
if (elseBranchElements.size() > 0) {
AbstractIntermediate firstElseBlockElement = elseBranchElements.first();
if (firstElseBlockElement instanceof StatementIntermediate) {
//we should add the ELSE right away...
addElseBlock(firstElseBlockElement, maxGotoForBranch);
return;
}
if (firstElseBlockElement instanceof BooleanBranchIntermediate) {
//only add ELSE if the child of conditional doesn't go to the target.
BooleanBranchIntermediate ci = (BooleanBranchIntermediate) firstElseBlockElement;
if (igc.getFalseTarget(ci) == line || igc.getTrueTarget(ci) == line) {
//do nothing.
return;
}
//else if this is an ElseIf, probably should be an IF.
if (firstElseBlockElement instanceof ElseIfIntermediate) {
IfIntermediate ifIntermediate = new IfIntermediate(firstElseBlockElement.getInstruction(), ((BooleanBranchIntermediate) firstElseBlockElement).getExpression());
igc.getGraph().addVertex(ifIntermediate);
igc.redirectPredecessors(firstElseBlockElement, ifIntermediate);
igc.redirectSuccessors(firstElseBlockElement, ifIntermediate);
igc.getGraph().removeVertex(firstElseBlockElement);
//add the else between this conditional.
addElseBlock(ifIntermediate, maxGotoForBranch);
}
}
}
}
use of org.candle.decompiler.intermediate.code.IntermediateComparator in project candle-decompiler by bradsdavis.
the class CatchUpperRangeVisitor method processLastCatch.
public void processLastCatch(CatchIntermediate line) {
TryIntermediate tryBlock = (TryIntermediate) igc.getSinglePredecessor(line);
if (igc.getFinallyClause(tryBlock) != null) {
return;
}
//now, we are going to look for the block jump.
InstructionHandle ih = tryBlock.getBlockRange().getEnd();
//see about a goto.
GoToIntermediate gotoHandle = (GoToIntermediate) igc.findNextNode(ih.getNext());
TreeSet<AbstractIntermediate> ordered = new TreeSet<AbstractIntermediate>(new IntermediateComparator());
//no finally clause...
ordered.addAll(igc.getCatchClauses(tryBlock));
AbstractIntermediate target = igc.getTarget(gotoHandle);
//now, look backwards and find the non-GOTO statement.
List<AbstractIntermediate> candidates = Graphs.predecessorListOf(igc.getGraph(), target);
Set<AbstractIntermediate> elements = new HashSet<AbstractIntermediate>();
for (AbstractIntermediate candidate : candidates) {
if (!(candidate instanceof GoToIntermediate)) {
elements.add(candidate);
}
}
for (AbstractIntermediate element : elements) {
LOG.debug("Element: " + element + " Position: " + element.getInstruction().getPosition());
}
if (elements.size() == 1) {
if (ordered.last() instanceof CatchIntermediate) {
CatchIntermediate ci = (CatchIntermediate) ordered.last();
ci.getBlockRange().setEnd(elements.iterator().next().getInstruction());
}
}
}
use of org.candle.decompiler.intermediate.code.IntermediateComparator in project candle-decompiler by bradsdavis.
the class BlockVisitor method visitTryIntermediate.
@Override
public void visitTryIntermediate(TryIntermediate line) {
if (seen.contains(line)) {
//do nothing.
return;
} else {
seen.add(line);
}
//set current block...
TryBlock tryBlock = new TryBlock(line);
//add it as a child of current..
this.current.addChild(tryBlock);
//set the current...
this.current = tryBlock;
//now, get the nested blocks...
List<AbstractIntermediate> successors = getUnseenSuccessors(line);
AbstractIntermediate inner = null;
List<AbstractIntermediate> catchBlocks = new LinkedList<AbstractIntermediate>();
AbstractIntermediate finallyIntermediate = null;
//find the non-catch/finally...
for (AbstractIntermediate successor : successors) {
if (successor instanceof CatchIntermediate) {
catchBlocks.add(successor);
} else if (successor instanceof FinallyIntermediate) {
finallyIntermediate = successor;
} else {
if (inner != null) {
throw new IllegalStateException("Inner direction already set.");
}
inner = successor;
}
}
Collections.sort(catchBlocks, new IntermediateComparator());
if (inner == null) {
throw new IllegalStateException("Inner is not set.");
}
inner.accept(this);
//set the current up.
moveUp();
for (AbstractIntermediate catchBlock : catchBlocks) {
current = tryBlock;
catchBlock.accept(this);
}
if (finallyIntermediate != null) {
current = tryBlock;
finallyIntermediate.accept(this);
}
}
use of org.candle.decompiler.intermediate.code.IntermediateComparator 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