use of org.apache.bcel.generic.BranchHandle in project candle-decompiler by bradsdavis.
the class ConditionEdgeEnhancer method process.
@Override
public void process(InstructionHandle ih) {
if (ih instanceof BranchHandle) {
// ok, now we need to replace existing successor edges appropriately.
BranchHandle bh = (BranchHandle) ih;
List<InstructionHandle> successors = igc.getSuccessors(ih);
TreeSet<InstructionHandle> orderedSuccessors = new TreeSet<InstructionHandle>(new InstructionComparator());
orderedSuccessors.addAll(successors);
if (successors.size() == 2) {
// lowest will be true condition....
IntermediateEdge truePath = igc.getGraph().getEdge(ih, orderedSuccessors.first());
ConditionEdge trueCondition = createConditionalEdge(truePath, true);
igc.getGraph().removeEdge(truePath);
igc.getGraph().addEdge(ih, orderedSuccessors.first(), trueCondition);
// highest will be false condition....
IntermediateEdge falsePath = igc.getGraph().getEdge(ih, orderedSuccessors.last());
ConditionEdge falseCondition = createConditionalEdge(falsePath, false);
igc.getGraph().removeEdge(falsePath);
igc.getGraph().addEdge(ih, orderedSuccessors.last(), falseCondition);
}
}
}
use of org.apache.bcel.generic.BranchHandle 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.BranchHandle 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);
}
}
}
use of org.apache.bcel.generic.BranchHandle in project candle-decompiler by bradsdavis.
the class IntermediateGraphFactory method visitBooleanBranchIntermediate.
@Override
public void visitBooleanBranchIntermediate(BooleanBranchIntermediate line) {
InstructionHandle next = line.getInstruction().getNext();
// find how that actually maps to the abstract line..
AbstractIntermediate nextIntermediate = ilc.getNext(next.getPosition());
igc.getGraph().addVertex(nextIntermediate);
BranchHandle bi = ((BranchHandle) line.getInstruction());
AbstractIntermediate targetIntermediate = ilc.getNext(bi.getTarget().getPosition());
igc.getGraph().addVertex(targetIntermediate);
AbstractIntermediate lowest = targetIntermediate.getInstruction().getPosition() < nextIntermediate.getInstruction().getPosition() ? targetIntermediate : nextIntermediate;
AbstractIntermediate highest = targetIntermediate.getInstruction().getPosition() > nextIntermediate.getInstruction().getPosition() ? targetIntermediate : nextIntermediate;
/*
//add true path... (Conditional) -> (True) -> (Node A)
BooleanBranchOutcome trueOutcome = new BooleanBranchOutcome(line.getInstruction(), line, Boolean.TRUE);
//line.setTrueBranch(trueOutcome);
igc.getGraph().addVertex(trueOutcome);
igc.getGraph().addEdge(line, trueOutcome);
igc.getGraph().addEdge(trueOutcome, lowest);
//add false path... (Conditional) -> (False) -> (Node A)
BooleanBranchOutcome falseOutcome = new BooleanBranchOutcome(line.getInstruction(), line, Boolean.FALSE);
//line.setFalseBranch(falseOutcome);
igc.getGraph().addVertex(falseOutcome);
igc.getGraph().addEdge(line, falseOutcome);
igc.getGraph().addEdge(falseOutcome, highest);*/
}
use of org.apache.bcel.generic.BranchHandle in project candle-decompiler by bradsdavis.
the class InstructionGraphFactory method process.
public InstructionGraphContext process() {
ListenableDirectedGraph<InstructionHandle, IntermediateEdge> instructionHandleGraph = new ListenableDirectedGraph<InstructionHandle, IntermediateEdge>(IntermediateEdge.class);
InstructionGraphContext igc = new InstructionGraphContext(instructionHandleGraph);
for (InstructionHandle instructionHandle : instructionList.getInstructionHandles()) {
InstructionHandle iv = instructionHandle;
instructionHandleGraph.addVertex(iv);
}
Iterator<InstructionHandle> iter = instructionList.iterator();
while (iter.hasNext()) {
InstructionHandle ih = iter.next();
InstructionHandle sourceVertex = igc.getPositionMap().get(ih.getPosition());
if (ih.getInstruction() instanceof Select) {
for (InstructionHandle targetVertex : ((Select) ih.getInstruction()).getTargets()) {
instructionHandleGraph.addEdge(sourceVertex, targetVertex);
}
InstructionHandle targetVertex = ((Select) ih.getInstruction()).getTarget();
if (targetVertex != null) {
instructionHandleGraph.addEdge(sourceVertex, targetVertex);
}
} else if (ih instanceof BranchHandle) {
// if this is an unconditional branch, only add the branch between the instruction and it's target.
InstructionHandle targetVertex = igc.getPositionMap().get(((BranchHandle) ih).getTarget().getPosition());
instructionHandleGraph.addEdge(sourceVertex, targetVertex);
}
if (!(ih.getInstruction() instanceof UnconditionalBranch)) {
if (ih.getNext() != null) {
InstructionHandle targetVertex = igc.getPositionMap().get((ih).getNext().getPosition());
instructionHandleGraph.addEdge(sourceVertex, targetVertex);
}
}
}
/*
//HAPPY PATH
Set<InstructionHandle> happy = new HashSet<InstructionHandle>();
InstructionHandle root = createVertex(instructionList.getStart());
BreadthFirstIterator<InstructionHandle, IntermediateEdge> bfi = new BreadthFirstIterator<InstructionHandle, IntermediateEdge>(instructionHandleGraph, root);
while(bfi.hasNext()) {
happy.add(bfi.next());
}
InstructionTryCatch itc = new InstructionTryCatch(igc, this.exceptions);
NamedDirectedSubgraph happyPath = new NamedDirectedSubgraph("Main", instructionHandleGraph, happy, null);
for(CodeExceptionGen ceg : exceptions) {
Set<InstructionHandle> cegG = new HashSet<InstructionHandle>();
System.out.println("X"+ceg.getStartPC() + " -> "+ceg.getEndPC()+ ", "+ceg.getHandlerPC());
for(InstructionHandle iv : instructionHandleGraph.vertexSet()) {
if(iv.getPosition() <= ceg.getEndPC().getPosition() && iv.getPosition() >= ceg.getStartPC().getPosition()) {
System.out.println("Position : "+iv.getPosition() );
cegG.add(iv);
}
}
subs.add(new NamedDirectedSubgraph("ExceptionHandler"+ceg.getCatchType().toString(), instructionHandleGraph, cegG, null));
}
*/
return igc;
}
Aggregations