use of org.apache.bcel.generic.InstructionHandle 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.apache.bcel.generic.InstructionHandle 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.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class NonIntermediateEliminator method process.
@Override
public void process(InstructionHandle ih) {
if (igc.hasIntermediate(ih)) {
// don't process if there is an intermediate.
return;
}
List<InstructionHandle> successors = igc.getSuccessors(ih);
if (successors.size() == 1) {
// now check to see whether there is an intermediate on the objects...
InstructionHandle target = successors.get(0);
if (LOG.isDebugEnabled()) {
LOG.debug("Remove vertex:" + ih);
}
igc.redirectPredecessors(ih, target);
igc.getGraph().removeVertex(ih);
} else {
List<InstructionHandle> predecessors = igc.getPredecessors(ih);
if (predecessors.size() == 1) {
// compress backwards...
igc.redirectSuccessors(ih, predecessors.get(0));
igc.getGraph().removeVertex(ih);
}
}
}
use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class SplitInstructionEnhancer method visitPopInstruction.
@Override
public void visitPopInstruction(PopInstruction obj) {
// check instruction in map.
List<InstructionHandle> ivs = this.igc.getPredecessors(this.current);
if (ivs.size() > 1) {
// check to see if the predecessors pushed.
int count = 0;
for (InstructionHandle iv : ivs) {
InstructionHandle jvmiv = (InstructionHandle) iv;
jvmiv = findSource(jvmiv);
if (jvmiv.getInstruction() instanceof PushInstruction) {
count++;
}
}
if (count > 1) {
LOG.debug("Split vertex.");
splitVertex(this.current);
}
}
}
use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class InstructionTransversalListener method vertexTraversed.
@Override
public void vertexTraversed(VertexTraversalEvent<InstructionHandle> e) {
cpl.setup(e.getVertex());
// process instruction handle.
InstructionHandle jvm = e.getVertex();
intermediateContext.setCurrentInstruction(jvm);
jvm.getInstruction().accept(miv);
// finish.
cpl.finish(e);
super.vertexFinished(e);
}
Aggregations