Search in sources :

Example 1 with BranchHandle

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);
        }
    }
}
Also used : InstructionComparator(org.candle.decompiler.instruction.graph.vertex.InstructionComparator) TreeSet(java.util.TreeSet) BranchHandle(org.apache.bcel.generic.BranchHandle) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConditionEdge(org.candle.decompiler.intermediate.graph.edge.ConditionEdge)

Example 2 with BranchHandle

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());
}
Also used : GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) BranchHandle(org.apache.bcel.generic.BranchHandle) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 3 with BranchHandle

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);
        }
    }
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) WhileIntermediate(org.candle.decompiler.intermediate.code.loop.WhileIntermediate) GoToIntermediate(org.candle.decompiler.intermediate.code.GoToIntermediate) BranchHandle(org.apache.bcel.generic.BranchHandle) IntermediateComparator(org.candle.decompiler.intermediate.code.IntermediateComparator) Continue(org.candle.decompiler.intermediate.expression.Continue) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge) CycleDetector(org.jgrapht.alg.CycleDetector) TreeSet(java.util.TreeSet) StatementIntermediate(org.candle.decompiler.intermediate.code.StatementIntermediate)

Example 4 with BranchHandle

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);*/
}
Also used : AbstractIntermediate(org.candle.decompiler.intermediate.code.AbstractIntermediate) BranchHandle(org.apache.bcel.generic.BranchHandle) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 5 with BranchHandle

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;
}
Also used : UnconditionalBranch(org.apache.bcel.generic.UnconditionalBranch) Select(org.apache.bcel.generic.Select) BranchHandle(org.apache.bcel.generic.BranchHandle) ListenableDirectedGraph(org.jgrapht.graph.ListenableDirectedGraph) IntermediateEdge(org.candle.decompiler.intermediate.graph.edge.IntermediateEdge) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Aggregations

BranchHandle (org.apache.bcel.generic.BranchHandle)5 InstructionHandle (org.apache.bcel.generic.InstructionHandle)4 IntermediateEdge (org.candle.decompiler.intermediate.graph.edge.IntermediateEdge)3 TreeSet (java.util.TreeSet)2 AbstractIntermediate (org.candle.decompiler.intermediate.code.AbstractIntermediate)2 GoToIntermediate (org.candle.decompiler.intermediate.code.GoToIntermediate)2 Select (org.apache.bcel.generic.Select)1 UnconditionalBranch (org.apache.bcel.generic.UnconditionalBranch)1 InstructionComparator (org.candle.decompiler.instruction.graph.vertex.InstructionComparator)1 IntermediateComparator (org.candle.decompiler.intermediate.code.IntermediateComparator)1 StatementIntermediate (org.candle.decompiler.intermediate.code.StatementIntermediate)1 WhileIntermediate (org.candle.decompiler.intermediate.code.loop.WhileIntermediate)1 Continue (org.candle.decompiler.intermediate.expression.Continue)1 ConditionEdge (org.candle.decompiler.intermediate.graph.edge.ConditionEdge)1 CycleDetector (org.jgrapht.alg.CycleDetector)1 ListenableDirectedGraph (org.jgrapht.graph.ListenableDirectedGraph)1