use of org.candle.decompiler.intermediate.code.GoToIntermediate in project candle-decompiler by bradsdavis.
the class IntermediateLineContext method getNext.
public AbstractIntermediate getNext(AbstractIntermediate ai) {
if (ai instanceof GoToIntermediate) {
BranchHandle bh = (BranchHandle) ai.getInstruction();
Integer position = bh.getTarget().getPosition();
return getNext(position);
}
//otherwise, get it from the next position.
InstructionHandle next = ai.getInstruction().getNext();
//return either null, if next is null (last next). Otherwise, send next position.
return next == null ? null : getNext(next.getPosition());
}
use of org.candle.decompiler.intermediate.code.GoToIntermediate in project candle-decompiler by bradsdavis.
the class RetractDuplicateFinally method processTry.
protected void processTry(TryIntermediate tryIntermediate, FinallyIntermediate finallyIntermediate, Set<Integer> offsets) {
//ok, now let's handle the try...
InstructionHandle end = tryIntermediate.getBlockRange().getEnd();
//next should be GOTO.
AbstractIntermediate tryEndNode = igc.findNextNode(end);
AbstractIntermediate gotoIntermediate = null;
//check to see if this is loop...
if (tryEndNode instanceof StatementIntermediate) {
LOG.debug("Position: " + tryEndNode.getInstruction().getPosition() + " Value: " + tryEndNode);
gotoIntermediate = igc.getSingleSuccessor(tryEndNode);
} else if (tryEndNode instanceof BooleanBranchIntermediate) {
BooleanBranchIntermediate bbi = (BooleanBranchIntermediate) tryEndNode;
//find higher target...
AbstractIntermediate trueTarget = igc.getTrueTarget(bbi);
AbstractIntermediate falseTarget = igc.getFalseTarget(bbi);
int trueTargetPosition = trueTarget.getInstruction().getPosition();
int falseTargetPosition = falseTarget.getInstruction().getPosition();
gotoIntermediate = (trueTargetPosition > falseTargetPosition) ? trueTarget : falseTarget;
}
//validate it is a GOTO.
if (!(gotoIntermediate instanceof GoToIntermediate)) {
LOG.warn("Expected GOTO. But this isn't: " + gotoIntermediate);
} else {
AbstractIntermediate tryFinallyFirst = igc.getSingleSuccessor(gotoIntermediate);
eliminateNode(tryFinallyFirst, offsets);
//now, eliminate the GOTO.
igc.getGraph().removeVertex(gotoIntermediate);
igc.getGraph().addEdge(tryIntermediate, finallyIntermediate);
}
}
use of org.candle.decompiler.intermediate.code.GoToIntermediate 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.GoToIntermediate in project candle-decompiler by bradsdavis.
the class LoopGotoToBreak method processLoop.
public void processLoop(WhileIntermediate loop) {
//get the target... then look for GOTO statements going into the target that are within the range
//of the loop.
TreeSet<AbstractIntermediate> loopElements = (TreeSet<AbstractIntermediate>) igc.getOrderedIntermediate().subSet(igc.getTrueTarget(loop), true, igc.getFalseTarget(loop), false);
List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), igc.getFalseTarget(loop));
Set<GoToIntermediate> gotoToBreak = new HashSet<GoToIntermediate>();
for (AbstractIntermediate predecessor : predecessors) {
if (predecessor instanceof GoToIntermediate) {
if (loopElements.contains(predecessor)) {
gotoToBreak.add((GoToIntermediate) predecessor);
}
}
}
//now, we create new statements.
for (GoToIntermediate gotoToBreakStatement : gotoToBreak) {
transformGotoToBreak(gotoToBreakStatement);
}
}
use of org.candle.decompiler.intermediate.code.GoToIntermediate 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());
}
}
}
Aggregations