use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class IntermediateGraphFactory method visitMultiBranchIntermediate.
@Override
public void visitMultiBranchIntermediate(MultiBranchIntermediate line) {
Select select = (Select) line.getInstruction().getInstruction();
Set<Case> cases = new HashSet<Case>();
InstructionHandle[] handles = select.getTargets();
int[] matches = select.getMatchs();
for (int i = 0, j = handles.length; i < j; i++) {
InstructionHandle ih = handles[i];
int match = matches[i];
Resolved resolved = new Resolved(line.getInstruction(), BasicType.INT, "" + match);
Case caseEntry = new Case(line.getInstruction(), ih, resolved);
cases.add(caseEntry);
}
if (select.getTarget() != null) {
DefaultCase defaultCase = new DefaultCase(line.getInstruction(), select.getTarget());
line.setDefaultCase(defaultCase);
}
//now, create the graph.
line.setCases(cases);
//now, create the graph.
igc.getGraph().addVertex(line);
if (line.getDefaultCase() != null) {
CaseIntermediate si = new CaseIntermediate(line.getInstruction(), line.getDefaultCase());
igc.getGraph().addVertex(si);
//add an edge.
igc.getGraph().addEdge(line, si);
//add edge from outcome to edge.
LOG.debug(si);
AbstractIntermediate target = ilc.getNext(line.getDefaultCase().getTarget().getPosition());
LOG.debug("TargeT:" + target);
igc.getGraph().addVertex(target);
igc.getGraph().addEdge(si, target);
}
for (Case caseVal : line.getCases()) {
CaseIntermediate si = new CaseIntermediate(line.getInstruction(), caseVal);
igc.getGraph().addVertex(si);
//add an edge.
igc.getGraph().addEdge(line, si);
//add edge from outcome to edge.
AbstractIntermediate target = ilc.getNext(caseVal.getTarget().getPosition());
igc.getGraph().addVertex(target);
igc.getGraph().addEdge(si, target);
}
}
use of org.apache.bcel.generic.InstructionHandle 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.apache.bcel.generic.InstructionHandle 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.apache.bcel.generic.InstructionHandle 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.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);
}
Aggregations