use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class IntermediateGraphTransformer method getIntermediateGraphContext.
public IntermediateGraphContext getIntermediateGraphContext() {
Map<InstructionHandle, AbstractIntermediate> nodeMapping = new HashMap<InstructionHandle, AbstractIntermediate>();
ListenableDirectedGraph<AbstractIntermediate, IntermediateEdge> intermediateGraph = new ListenableDirectedGraph<AbstractIntermediate, IntermediateEdge>(IntermediateEdge.class);
// walk the instruction graph and generate the intermediate graph. start by walking and adding all vertices. Then, add the connections between the vertices.
for (InstructionHandle ih : igc.getGraph().vertexSet()) {
if (igc.hasIntermediate(ih)) {
AbstractIntermediate vertex = igc.getIntermediateFromInstruction(ih);
intermediateGraph.addVertex(vertex);
nodeMapping.put(ih, vertex);
}
}
// now, add the links.
for (InstructionHandle ih : igc.getGraph().vertexSet()) {
AbstractIntermediate nodeIntermediate = nodeMapping.get(ih);
if (nodeIntermediate == null) {
LOG.warn("This shouldn't be...");
continue;
}
List<InstructionHandle> predecessors = igc.getPredecessors(ih);
List<InstructionHandle> successors = igc.getSuccessors(ih);
for (InstructionHandle predecessor : predecessors) {
// find it's AbstractIntermediate.
AbstractIntermediate predIntermediate = nodeMapping.get(predecessor);
if (predIntermediate == null) {
// then something is wrong.
LOG.warn("This shouldn't be...");
continue;
}
IntermediateEdge insEdge = igc.getGraph().getEdge(predecessor, ih);
// add an edge to the intermediate graph.
if (intermediateGraph.containsEdge(predIntermediate, nodeIntermediate)) {
continue;
}
intermediateGraph.addEdge(predIntermediate, nodeIntermediate, (IntermediateEdge) insEdge.clone());
}
for (InstructionHandle successor : successors) {
// find it's AbstractIntermediate.
AbstractIntermediate successorIntermediate = nodeMapping.get(successor);
if (successorIntermediate == null) {
LOG.warn("This shouldn't be...");
continue;
}
if (intermediateGraph.containsEdge(nodeIntermediate, successorIntermediate)) {
continue;
}
IntermediateEdge insEdge = igc.getGraph().getEdge(ih, successor);
// add an edge to the intermediate graph.
intermediateGraph.addEdge(nodeIntermediate, successorIntermediate, (IntermediateEdge) insEdge.clone());
}
}
return new IntermediateGraphContext(intermediateGraph);
}
use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class IntermediateTryCatch method process.
public void process() {
Set<BlockRange> tryBlock = new TreeSet<BlockRange>(new BlockRangeComparator());
Map<BlockRange, List<CodeExceptionGen>> tryRangeGen = new HashMap<BlockRange, List<CodeExceptionGen>>();
Map<InstructionHandle, List<CodeExceptionGen>> tryRangeFinally = new HashMap<InstructionHandle, List<CodeExceptionGen>>();
// create try statements...
for (CodeExceptionGen ceg : method.getExceptionHandlers()) {
InstructionHandle min = ceg.getStartPC();
InstructionHandle max = ceg.getEndPC();
BlockRange tryRange = new BlockRange();
tryRange.setStart(min);
tryRange.setEnd(max);
AbstractIntermediate handle = igc.findNextNode(ceg.getHandlerPC());
LOG.debug("RANGE: " + ceg);
LOG.debug("Range: " + tryRange + " , Target: " + handle.getInstruction().getPosition() + " , Handle: " + handle.getInstruction());
if (ceg.getCatchType() == null) {
if (!tryRangeFinally.containsKey(ceg.getHandlerPC())) {
tryRangeFinally.put(ceg.getHandlerPC(), new LinkedList<CodeExceptionGen>());
}
tryRangeFinally.get(ceg.getHandlerPC()).add(ceg);
continue;
}
tryBlock.add(tryRange);
if (!tryRangeGen.containsKey(tryRange)) {
tryRangeGen.put(tryRange, new LinkedList<CodeExceptionGen>());
}
tryRangeGen.get(tryRange).add(ceg);
}
for (BlockRange tryRange : tryBlock) {
// create try block... create each catch block... link the two together for graph sake.
// look up block...
InstructionHandle start = tryRange.getStart();
TryIntermediate tryIntermediate = new TryIntermediate(start);
tryIntermediate.getBlockRange().setStart(tryRange.getStart());
tryIntermediate.getBlockRange().setEnd(tryRange.getEnd());
igc.getGraph().addVertex(tryIntermediate);
// add line between try and node.
AbstractIntermediate tryFirst = igc.findNextNode(start);
igc.redirectPredecessors(tryFirst, tryIntermediate);
igc.getGraph().addEdge(tryIntermediate, tryFirst);
if (tryRangeGen.containsKey(tryRange)) {
// create catch statements...
for (CodeExceptionGen ceg : tryRangeGen.get(tryRange)) {
generateCatch(tryIntermediate, ceg);
}
}
}
// create a finally node for each handle of finally & link
for (InstructionHandle finallyTargetHandle : tryRangeFinally.keySet()) {
// get reference to target...
AbstractIntermediate finallyTargetNode = igc.findNextNode(finallyTargetHandle);
// change the instruction to a finally...
FinallyIntermediate finallyIntermediate = new FinallyIntermediate(finallyTargetNode.getInstruction(), new HashSet<CodeExceptionGen>(tryRangeFinally.get(finallyTargetHandle)));
igc.getGraph().addVertex(finallyIntermediate);
// now, we need to redirect from the existing throws to finally.
igc.redirectSuccessors(finallyTargetNode, finallyIntermediate);
// retract existing.
igc.getGraph().removeVertex(finallyTargetNode);
}
}
use of org.apache.bcel.generic.InstructionHandle 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;
}
use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class InstructionTryCatch method process.
public void process() {
Map<InstructionRange, List<CodeExceptionGen>> tryRangeGen = new HashMap<InstructionRange, List<CodeExceptionGen>>();
// create try statements...
for (CodeExceptionGen ceg : exceptions) {
InstructionHandle min = (ceg.getStartPC());
InstructionHandle max = (ceg.getEndPC());
InstructionRange tryRange = new InstructionRange();
tryRange.setStart(min);
tryRange.setEnd(max);
// SKIP THE FINALLY
if (ceg.getCatchType() == null) {
continue;
}
if (!tryRangeGen.containsKey(tryRange)) {
tryRangeGen.put(tryRange, new LinkedList<CodeExceptionGen>());
}
tryRangeGen.get(tryRange).add(ceg);
}
}
use of org.apache.bcel.generic.InstructionHandle in project candle-decompiler by bradsdavis.
the class ExceptionEdgeEnhancer method process.
@Override
public void process() {
Set<Integer> positions = new HashSet<Integer>();
for (CodeExceptionGen ceg : exceptions) {
int t1 = ceg.getStartPC().getPosition();
int t2 = ceg.getHandlerPC().getPosition();
positions.add(t1);
positions.add(t2);
}
Map<Integer, InstructionHandle> ivc = new HashMap<Integer, InstructionHandle>();
for (InstructionHandle iv : igc.getGraph().vertexSet()) {
if (positions.contains(iv.getPosition())) {
ivc.put(iv.getPosition(), iv);
}
}
// now, we will map the CEG.
for (CodeExceptionGen ceg : exceptions) {
int t1 = ceg.getStartPC().getPosition();
int t2 = ceg.getHandlerPC().getPosition();
InstructionHandle source = ivc.get(t1);
InstructionHandle target = ivc.get(t2);
IntermediateEdge ie = new IntermediateEdge();
addExceptionHandle(ie, ceg);
ie.setType(EdgeType.EXCEPTION);
igc.getGraph().addEdge(source, target, ie);
}
}
Aggregations