Search in sources :

Example 1 with ASTSwitchNode

use of soot.dava.internal.AST.ASTSwitchNode in project soot by Sable.

the class EliminateConditions method normalRetrieving.

public void normalRetrieving(ASTNode node) {
    modified = false;
    if (node instanceof ASTSwitchNode) {
        do {
            modified = false;
            dealWithSwitchNode((ASTSwitchNode) node);
        } while (modified);
        return;
    }
    // from the Node get the subBodes
    Iterator<Object> sbit = node.get_SubBodies().iterator();
    while (sbit.hasNext()) {
        List subBody = (List) sbit.next();
        Iterator it = subBody.iterator();
        ASTNode temp = null;
        Boolean returned = null;
        while (it.hasNext()) {
            temp = (ASTNode) it.next();
            // only check condition if this is a control flow node
            if (temp instanceof ASTControlFlowNode) {
                bodyContainingNode = null;
                returned = eliminate(temp);
                if (returned != null && canChange(returned, temp)) {
                    break;
                } else {
                    if (DEBUG)
                        System.out.println("returned is null" + temp.getClass());
                    bodyContainingNode = null;
                }
            }
            temp.apply(this);
        }
        // end while going through nodes in subBody
        boolean changed = change(returned, temp);
        if (changed)
            modified = true;
    }
    if (modified) {
        // repeat the whole thing
        normalRetrieving(node);
    }
}
Also used : ASTControlFlowNode(soot.dava.internal.AST.ASTControlFlowNode) Iterator(java.util.Iterator) ASTNode(soot.dava.internal.AST.ASTNode) List(java.util.List) ASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode)

Example 2 with ASTSwitchNode

use of soot.dava.internal.AST.ASTSwitchNode in project soot by Sable.

the class UnreachableCodeEliminator method normalRetrieving.

public void normalRetrieving(ASTNode node) {
    if (node instanceof ASTSwitchNode) {
        dealWithSwitchNode((ASTSwitchNode) node);
        return;
    }
    // from the Node get the subBodes
    List<ASTNode> toReturn = new ArrayList<ASTNode>();
    Iterator<Object> sbit = node.get_SubBodies().iterator();
    while (sbit.hasNext()) {
        Object subBody = sbit.next();
        Iterator<ASTNode> it = ((List<ASTNode>) subBody).iterator();
        // go over the ASTNodes in this subBody and apply
        while (it.hasNext()) {
            ASTNode temp = it.next();
            if (!codeFinder.isConstructReachable(temp)) {
                // System.out.println("-------------------------A child of node of type "+node.getClass()+" whose type is "+temp.getClass()+" is unreachable");
                toReturn.add(temp);
            } else {
                // only apply on reachable nodes
                temp.apply(this);
            }
        }
        it = toReturn.iterator();
        while (it.hasNext()) {
            // System.out.println("Removed");
            ((List) subBody).remove(it.next());
        }
    }
// end of going over subBodies
}
Also used : ASTNode(soot.dava.internal.AST.ASTNode) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode)

Example 3 with ASTSwitchNode

use of soot.dava.internal.AST.ASTSwitchNode in project soot by Sable.

the class MethodCallFinder method replaceSubBody.

public boolean replaceSubBody(InvokeStmt s, List<ASTStatementSequenceNode> newChangedBodyPart, ASTParentNodeFinder finder) {
    // get the stmt seq node of invoke stmt
    Object stmtSeqNode = finder.getParentOf(s);
    // find the parent node of the stmt seq node
    Object ParentOfStmtSeq = finder.getParentOf(stmtSeqNode);
    if (ParentOfStmtSeq == null) {
        throw new RuntimeException("MethodCall FInder: parent of stmt seq node not found");
    }
    ASTNode node = (ASTNode) ParentOfStmtSeq;
    if (node instanceof ASTMethodNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTMethodNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTSynchronizedBlockNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTSynchronizedBlockNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTLabeledBlockNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTLabeledBlockNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTUnconditionalLoopNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTUnconditionalLoopNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTIfNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTIfNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTWhileNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTWhileNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTDoWhileNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTDoWhileNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTForLoopNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTForLoopNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTIfElseNode) {
        List<Object> subBodies = node.get_SubBodies();
        if (subBodies.size() != 2)
            throw new RuntimeException("Found an ifelse ASTNode which does not have two bodies");
        List<Object> ifBody = (List<Object>) subBodies.get(0);
        List<Object> elseBody = (List<Object>) subBodies.get(1);
        // find out which of these bodies has the stmt seq node with the
        // invoke stmt
        int subBodyNumber = -1;
        Iterator<Object> it = ifBody.iterator();
        while (it.hasNext()) {
            Object temp = it.next();
            if (temp == stmtSeqNode) {
                subBodyNumber = 0;
                break;
            }
        }
        if (subBodyNumber != 0) {
            it = elseBody.iterator();
            while (it.hasNext()) {
                Object temp = it.next();
                if (temp == stmtSeqNode) {
                    subBodyNumber = 1;
                    break;
                }
            }
        }
        List<Object> subBodyToReplace = null;
        if (subBodyNumber == 0)
            subBodyToReplace = ifBody;
        else if (subBodyNumber == 1)
            subBodyToReplace = elseBody;
        else
            throw new RuntimeException("Could not find the related ASTNode in the method");
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        if (subBodyNumber == 0) {
            ((ASTIfElseNode) node).replaceBody(newBody, elseBody);
            return true;
        } else if (subBodyNumber == 1) {
            ((ASTIfElseNode) node).replaceBody(ifBody, newBody);
            return true;
        }
    } else if (node instanceof ASTTryNode) {
        // NOTE THAT method INLINING Is currently only done in the tryBody
        // and not the catchBody
        // THe only reason for this being that mostly method calls are made
        // in the try and not the catch
        // get try body
        List<Object> tryBody = ((ASTTryNode) node).get_TryBody();
        Iterator<Object> it = tryBody.iterator();
        // find whether stmtSeqNode is in the tryBody
        boolean inTryBody = false;
        while (it.hasNext()) {
            ASTNode temp = (ASTNode) it.next();
            if (temp == stmtSeqNode) {
                inTryBody = true;
                break;
            }
        }
        if (!inTryBody) {
            // return without making any changes
            return false;
        }
        List<Object> newBody = createNewSubBody(tryBody, newChangedBodyPart, stmtSeqNode);
        ((ASTTryNode) node).replaceTryBody(newBody);
        return true;
    } else if (node instanceof ASTSwitchNode) {
        List<Object> indexList = ((ASTSwitchNode) node).getIndexList();
        Map<Object, List<Object>> index2BodyList = ((ASTSwitchNode) node).getIndex2BodyList();
        Iterator<Object> it = indexList.iterator();
        while (it.hasNext()) {
            // going through all the cases of the switch
            // statement
            Object currentIndex = it.next();
            List<Object> body = index2BodyList.get(currentIndex);
            if (body != null) {
                // this body is a list of ASTNodes
                // see if it contains stmtSeqNode
                boolean found = false;
                Iterator<Object> itBody = body.iterator();
                while (itBody.hasNext()) {
                    ASTNode temp = (ASTNode) itBody.next();
                    if (temp == stmtSeqNode) {
                        found = true;
                        break;
                    }
                }
                if (found) {
                    // this is the body which has the stmt seq node
                    List<Object> newBody = createNewSubBody(body, newChangedBodyPart, stmtSeqNode);
                    // put this body in the Map
                    index2BodyList.put(currentIndex, newBody);
                    // replace in actual switchNode
                    ((ASTSwitchNode) node).replaceIndex2BodyList(index2BodyList);
                    return true;
                }
            }
        // if body not null
        }
    // going through all cases
    }
    return false;
}
Also used : ASTSynchronizedBlockNode(soot.dava.internal.AST.ASTSynchronizedBlockNode) ASTIfNode(soot.dava.internal.AST.ASTIfNode) ASTTryNode(soot.dava.internal.AST.ASTTryNode) ASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ASTNode(soot.dava.internal.AST.ASTNode) Iterator(java.util.Iterator) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ArrayList(java.util.ArrayList) List(java.util.List) ASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode) ASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode)

Example 4 with ASTSwitchNode

use of soot.dava.internal.AST.ASTSwitchNode in project soot by Sable.

the class UselessAbruptStmtRemover method caseASTStatementSequenceNode.

public void caseASTStatementSequenceNode(ASTStatementSequenceNode node) {
    Iterator<AugmentedStmt> it = node.getStatements().iterator();
    AugmentedStmt remove = null;
    ASTLabeledNode target = null;
    while (it.hasNext()) {
        AugmentedStmt as = it.next();
        Stmt s = as.get_Stmt();
        // we only care about break and continue stmts
        if (!(s instanceof DAbruptStmt)) {
            continue;
        }
        DAbruptStmt abrupt = (DAbruptStmt) s;
        String label = abrupt.getLabel().toString();
        if (label == null) {
            // analysis with implicit abrupt flow but not needed currently
            continue;
        }
        if (it.hasNext()) {
            // afterwards...that is for sure dead code
            throw new DecompilationException("Dead code detected. Report to developer");
        }
        // get the target node
        Object temp = mapper.getTarget(label);
        if (temp == null) {
            continue;
        // throw new DecompilationException("Could not find target for abrupt stmt"+abrupt.toString());
        }
        target = (ASTLabeledNode) temp;
        // will need to find parents of ancestors see if we need to initialize the finder
        if (finder == null) {
            finder = new ASTParentNodeFinder();
            methodNode.apply(finder);
        }
        if (DEBUG)
            System.out.println("Starting useless check for abrupt stmt: " + abrupt);
        // start condition is that ancestor is the stmt seq node
        ASTNode ancestor = node;
        while (ancestor != target) {
            Object tempParent = finder.getParentOf(ancestor);
            if (tempParent == null)
                throw new DecompilationException("Parent found was null!!. Report to Developer");
            ASTNode ancestorsParent = (ASTNode) tempParent;
            if (DEBUG)
                System.out.println("\tCurrent ancestorsParent has type" + ancestorsParent.getClass());
            // ancestor should be last child of ancestorsParent
            if (!checkChildLastInParent(ancestor, ancestorsParent)) {
                if (DEBUG)
                    System.out.println("\t\tCurrent ancestorParent has more children after this ancestor");
                // return from the method since this is the last stmt and we cant do anything
                return;
            }
            // ancestorsParent should not be a loop of any kind OR A SWITCH
            if (ancestorsParent instanceof ASTWhileNode || ancestorsParent instanceof ASTDoWhileNode || ancestorsParent instanceof ASTUnconditionalLoopNode || ancestorsParent instanceof ASTForLoopNode || ancestorsParent instanceof ASTSwitchNode) {
                if (DEBUG)
                    System.out.println("\t\tAncestorsParent is a loop shouldnt remove abrupt stmt");
                return;
            }
            ancestor = ancestorsParent;
        }
        if (DEBUG)
            System.out.println("\tGot to target without returning means we can remove stmt");
        remove = as;
    }
    if (remove != null) {
        List<AugmentedStmt> stmts = node.getStatements();
        stmts.remove(remove);
        if (DEBUG)
            System.out.println("\tRemoved abrupt stmt");
        if (target != null) {
            if (DEBUG)
                System.out.println("Invoking findAndKill on the target");
            UselessLabelFinder.v().findAndKill(target);
        }
        // TODO what if we just emptied a stmt seq block??
        // not doing this for the moment
        // set modified flag make finder null
        G.v().ASTTransformations_modified = true;
        finder = null;
    }
}
Also used : ASTParentNodeFinder(soot.dava.toolkits.base.AST.traversals.ASTParentNodeFinder) DecompilationException(soot.dava.DecompilationException) ASTLabeledNode(soot.dava.internal.AST.ASTLabeledNode) DAbruptStmt(soot.dava.internal.javaRep.DAbruptStmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) DAbruptStmt(soot.dava.internal.javaRep.DAbruptStmt) Stmt(soot.jimple.Stmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) ASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ASTNode(soot.dava.internal.AST.ASTNode) ASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode)

Aggregations

ASTNode (soot.dava.internal.AST.ASTNode)4 ASTSwitchNode (soot.dava.internal.AST.ASTSwitchNode)4 List (java.util.List)3 ArrayList (java.util.ArrayList)2 Iterator (java.util.Iterator)2 ASTDoWhileNode (soot.dava.internal.AST.ASTDoWhileNode)2 ASTForLoopNode (soot.dava.internal.AST.ASTForLoopNode)2 ASTUnconditionalLoopNode (soot.dava.internal.AST.ASTUnconditionalLoopNode)2 ASTWhileNode (soot.dava.internal.AST.ASTWhileNode)2 DecompilationException (soot.dava.DecompilationException)1 ASTControlFlowNode (soot.dava.internal.AST.ASTControlFlowNode)1 ASTIfElseNode (soot.dava.internal.AST.ASTIfElseNode)1 ASTIfNode (soot.dava.internal.AST.ASTIfNode)1 ASTLabeledBlockNode (soot.dava.internal.AST.ASTLabeledBlockNode)1 ASTLabeledNode (soot.dava.internal.AST.ASTLabeledNode)1 ASTMethodNode (soot.dava.internal.AST.ASTMethodNode)1 ASTSynchronizedBlockNode (soot.dava.internal.AST.ASTSynchronizedBlockNode)1 ASTTryNode (soot.dava.internal.AST.ASTTryNode)1 AugmentedStmt (soot.dava.internal.asg.AugmentedStmt)1 DAbruptStmt (soot.dava.internal.javaRep.DAbruptStmt)1