use of org.candle.decompiler.intermediate.code.FinallyIntermediate in project candle-decompiler by bradsdavis.
the class IntermediateEdgeAttributeProvider method getComponentAttributes.
@Override
public Map<String, String> getComponentAttributes(IntermediateEdge edge) {
Map<String, String> attributes = new HashMap<String, String>();
AbstractIntermediate source = (AbstractIntermediate) edge.getSource();
AbstractIntermediate target = (AbstractIntermediate) edge.getTarget();
if (source instanceof TryIntermediate && (target instanceof CatchIntermediate || target instanceof FinallyIntermediate)) {
attributes.put("style", "dashed");
}
return attributes;
}
use of org.candle.decompiler.intermediate.code.FinallyIntermediate in project candle-decompiler by bradsdavis.
the class BlockVisitor method visitTryIntermediate.
@Override
public void visitTryIntermediate(TryIntermediate line) {
if (seen.contains(line)) {
//do nothing.
return;
} else {
seen.add(line);
}
//set current block...
TryBlock tryBlock = new TryBlock(line);
//add it as a child of current..
this.current.addChild(tryBlock);
//set the current...
this.current = tryBlock;
//now, get the nested blocks...
List<AbstractIntermediate> successors = getUnseenSuccessors(line);
AbstractIntermediate inner = null;
List<AbstractIntermediate> catchBlocks = new LinkedList<AbstractIntermediate>();
AbstractIntermediate finallyIntermediate = null;
//find the non-catch/finally...
for (AbstractIntermediate successor : successors) {
if (successor instanceof CatchIntermediate) {
catchBlocks.add(successor);
} else if (successor instanceof FinallyIntermediate) {
finallyIntermediate = successor;
} else {
if (inner != null) {
throw new IllegalStateException("Inner direction already set.");
}
inner = successor;
}
}
Collections.sort(catchBlocks, new IntermediateComparator());
if (inner == null) {
throw new IllegalStateException("Inner is not set.");
}
inner.accept(this);
//set the current up.
moveUp();
for (AbstractIntermediate catchBlock : catchBlocks) {
current = tryBlock;
catchBlock.accept(this);
}
if (finallyIntermediate != null) {
current = tryBlock;
finallyIntermediate.accept(this);
}
}
use of org.candle.decompiler.intermediate.code.FinallyIntermediate 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);
}
}
Aggregations