use of org.candle.decompiler.intermediate.code.StatementIntermediate 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.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class FinallyRangeVisitor method visitFinallyIntermediate.
@Override
public void visitFinallyIntermediate(FinallyIntermediate line) {
NonGotoIterator iter = new NonGotoIterator(igc.getGraph(), line);
// walk until we find a THROW.
AbstractIntermediate throwsStatement = null;
while (iter.hasNext()) {
AbstractIntermediate i = iter.next();
if (i instanceof StatementIntermediate) {
StatementIntermediate s = (StatementIntermediate) i;
if (s.getExpression() instanceof Throw) {
throwsStatement = s;
break;
}
}
}
if (throwsStatement != null) {
line.getBlockRange().setEnd(throwsStatement.getInstruction());
}
}
use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class MethodIntermediateVisitor method processInvoke.
public void processInvoke(InvokeInstruction instruction, int nparams) {
// collect all parameters from the stack.
final List<Expression> parameters = new ArrayList<Expression>(nparams);
for (int i = 0; i < nparams; i++) {
Expression param = context.getExpressions().pop();
LOG.debug("Parameter: " + param);
parameters.add(param);
}
// now, get the target that we are calling the method on.
Expression target = context.getExpressions().pop();
// collect the method name we are calling.
String methodName = instruction.getMethodName(context.getMethodGen().getConstantPool());
// create the expression..
MethodInvocation methodInvocation = new MethodInvocation(context.getCurrentInstruction(), target, methodName, parameters);
Type returned = instruction.getReturnType(context.getMethodGen().getConstantPool());
if (returned == BasicType.VOID) {
StatementIntermediate completeLine = new StatementIntermediate(context.getCurrentInstruction(), methodInvocation);
context.pushIntermediateToInstruction(completeLine);
LOG.debug("Pushed complete line: " + completeLine.toString());
} else {
context.getExpressions().push(methodInvocation);
LOG.debug("Pushed expression: " + methodInvocation);
}
}
use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class IntermediateTryCatch method generateCatch.
private void generateCatch(TryIntermediate tryIntermediate, CodeExceptionGen ceg) {
LOG.debug("CEG: " + ceg);
// convert the node to catch blocks...
AbstractIntermediate catchDeclaration = igc.getOrderedIntermediate().ceiling(new NullIntermediate(ceg.getHandlerPC()));
LOG.debug("Catch Declaration:" + catchDeclaration);
if (catchDeclaration instanceof StatementIntermediate) {
StatementIntermediate declarationStatement = (StatementIntermediate) catchDeclaration;
if (declarationStatement.getExpression() instanceof Declaration) {
Declaration declaration = (Declaration) declarationStatement.getExpression();
// now, we can convert this into a catch block.
CatchIntermediate catchIntermediate = new CatchIntermediate(declarationStatement.getInstruction(), ceg, declaration.getVariable());
igc.getGraph().addVertex(catchIntermediate);
// redirect statement to catch.
igc.redirectPredecessors(declarationStatement, catchIntermediate);
igc.redirectSuccessors(declarationStatement, catchIntermediate);
// now, we just need to remove the statement.
igc.getGraph().removeVertex(declarationStatement);
// populate the bounds..
// add the link between try and catch.
igc.getGraph().addEdge(tryIntermediate, catchIntermediate);
}
}
}
use of org.candle.decompiler.intermediate.code.StatementIntermediate in project candle-decompiler by bradsdavis.
the class Else method visitAbstractIntermediate.
@Override
public void visitAbstractIntermediate(AbstractIntermediate line) {
// for all lines...
List<AbstractIntermediate> predecessors = Graphs.predecessorListOf(igc.getGraph(), line);
if (predecessors.size() == 0) {
return;
}
TreeSet<GoToIntermediate> gotoIntermediates = new TreeSet<GoToIntermediate>(new IntermediateComparator());
for (AbstractIntermediate predecessor : predecessors) {
if (predecessor instanceof GoToIntermediate) {
gotoIntermediates.add((GoToIntermediate) predecessor);
}
}
if (gotoIntermediates.size() == 0) {
return;
}
// now, the largest should be...
GoToIntermediate maxGotoForBranch = gotoIntermediates.pollLast();
if (maxGotoForBranch.getInstruction().getPosition() > line.getInstruction().getPosition()) {
return;
}
// find the element directly after this one...
SortedSet<AbstractIntermediate> elseBranchElements = igc.getOrderedIntermediate().subSet(maxGotoForBranch, false, line, false);
AbstractIntermediate ai = igc.getSinglePredecessor(elseBranchElements.first());
if (!(ai instanceof IfIntermediate || ai instanceof ElseIfIntermediate)) {
return;
}
// get the first element...
if (elseBranchElements.size() > 0) {
AbstractIntermediate firstElseBlockElement = elseBranchElements.first();
if (firstElseBlockElement instanceof StatementIntermediate) {
// we should add the ELSE right away...
addElseBlock(firstElseBlockElement, maxGotoForBranch);
return;
}
if (firstElseBlockElement instanceof BooleanBranchIntermediate) {
// only add ELSE if the child of conditional doesn't go to the target.
BooleanBranchIntermediate ci = (BooleanBranchIntermediate) firstElseBlockElement;
if (igc.getFalseTarget(ci) == line || igc.getTrueTarget(ci) == line) {
// do nothing.
return;
}
// else if this is an ElseIf, probably should be an IF.
if (firstElseBlockElement instanceof ElseIfIntermediate) {
IfIntermediate ifIntermediate = new IfIntermediate(firstElseBlockElement.getInstruction(), ((BooleanBranchIntermediate) firstElseBlockElement).getExpression());
igc.getGraph().addVertex(ifIntermediate);
igc.redirectPredecessors(firstElseBlockElement, ifIntermediate);
igc.redirectSuccessors(firstElseBlockElement, ifIntermediate);
igc.getGraph().removeVertex(firstElseBlockElement);
// add the else between this conditional.
addElseBlock(ifIntermediate, maxGotoForBranch);
}
}
}
}
Aggregations