use of org.candle.decompiler.intermediate.code.AbstractIntermediate 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.AbstractIntermediate in project candle-decompiler by bradsdavis.
the class IntermediateGraphWriter method process.
@Override
public void process() {
if (directory == null) {
return;
}
File a = new File(directory.getAbsolutePath() + File.separator + name);
LOG.debug("Instruction Graph: " + a.getAbsolutePath());
Writer x;
try {
x = new FileWriter(a);
DOTExporter<AbstractIntermediate, IntermediateEdge> dot = new DOTExporter<AbstractIntermediate, IntermediateEdge>(new IntegerNameProvider<AbstractIntermediate>(), new IntermediateLabelProvider(), new IntermediateEdgeProvider(), new IntermediateVertexAttributeProvider(), new InstructionEdgeAttributeProvider());
dot.export(x, igc.getGraph());
} catch (IOException e) {
e.printStackTrace();
}
LOG.debug("End Instruction Graph ======");
}
use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.
the class RetractDuplicateFinally method eliminateNode.
protected void eliminateNode(AbstractIntermediate first, Set<Integer> offsets) {
InstructionHandle ih = first.getInstruction();
int position = first.getInstruction().getPosition();
for (Integer offset : offsets) {
int target = position + offset;
ih = igc.getInstructionHandle(target);
if (ih == null) {
LOG.warn("Not found expected InstructionHandle: " + (position + offset));
continue;
}
// loop through...
AbstractIntermediate ai = igc.findNextNode(ih);
if (ai.getInstruction().getPosition() == target) {
igc.getGraph().removeVertex(ai);
} else {
LOG.warn("Did not find vertex: " + target);
}
}
}
use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.
the class RetractDuplicateFinally method visitFinallyIntermediate.
@Override
public void visitFinallyIntermediate(FinallyIntermediate line) {
// TODO: Remove the highest finally statements first; won't fit this visitor
// pattern.
// get the bounds of the finally... associate the try.
// finally is part of the try if the try + catch bounds has:
// Try[0,13]
// Catch[19,50]
// Catch[56,65]
// Finally | Handler[56, 65]| Handler[0, 42] | | Range[66, 76]
// in the case above, finally should match because lower bound == finally lower handler bound.
// and upper bound of Catch matches upper bound of Finally Handler.
// first, match the Try block that applies...
// get lowest bound.
InstructionHandle min = getLowestBound(line.getCodeExceptions());
InstructionHandle max = getHighestBound(line.getCodeExceptions());
LOG.debug("Finally Range: " + min.getPosition() + " -> " + max.getPosition());
TryIntermediate matched = matchTryBlock(min, max);
if (matched != null) {
final Set<Integer> offsets = collectOffsets(line);
// ok, now we need to eliminate finally blocks from this try and all of the catches. thanks Java!
List<CatchIntermediate> catchClauses = igc.getCatchClauses(matched);
// for each catch clause...
for (CatchIntermediate catchClause : catchClauses) {
processCatch(catchClause, line, offsets);
}
processTry(matched, line, offsets);
}
// now, add the edge between end of FINALLY and the next statement.
InstructionHandle finallyEnd = line.getBlockRange().getEnd();
// get the next.. then search for next node in graph.
AbstractIntermediate finallyLast = igc.findNextNode(finallyEnd);
AbstractIntermediate afterFinally = igc.findNextNode(finallyEnd.getNext());
igc.redirectPredecessors(finallyLast, afterFinally);
igc.getGraph().removeVertex(finallyLast);
}
use of org.candle.decompiler.intermediate.code.AbstractIntermediate in project candle-decompiler by bradsdavis.
the class RetractDuplicateFinally method collectOffsets.
protected Set<Integer> collectOffsets(AbstractIntermediate line) {
// this is the finally template.
AbstractIntermediate first = igc.getSingleSuccessor(line);
// now, store the instruction position.
int position = first.getInstruction().getPosition();
BreadthFirstIterator<AbstractIntermediate, IntermediateEdge> bfi = new BreadthFirstIterator<AbstractIntermediate, IntermediateEdge>(igc.getGraph(), first);
Set<Integer> offsets = new TreeSet<Integer>();
while (bfi.hasNext()) {
AbstractIntermediate next = bfi.next();
int nextPosition = next.getInstruction().getPosition();
int offset = nextPosition - position;
LOG.debug("Offset: " + offset);
offsets.add(offset);
}
return offsets;
}
Aggregations