Search in sources :

Example 1 with ASTForLoopNode

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

the class EliminateConditions method change.

public boolean change(Boolean returned, ASTNode temp) {
    if (bodyContainingNode != null && returned != null && temp != null) {
        int index = bodyContainingNode.indexOf(temp);
        if (DEBUG)
            System.out.println("in change");
        if (temp instanceof ASTIfNode) {
            bodyContainingNode.remove(temp);
            if (returned.booleanValue()) {
                // if statement and value was true put the body of if into
                // the code
                // if its a labeled stmt we need a labeled block instead
                // notice that its okkay to put a labeled block since other
                // transformations might remove it
                String label = ((ASTLabeledNode) temp).get_Label().toString();
                if (label != null) {
                    ASTLabeledBlockNode labeledNode = new ASTLabeledBlockNode(((ASTLabeledNode) temp).get_Label(), (List<Object>) temp.get_SubBodies().get(0));
                    bodyContainingNode.add(index, labeledNode);
                } else {
                    bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(0));
                }
            }
            if (DEBUG)
                System.out.println("Removed if" + temp);
            return true;
        } else if (temp instanceof ASTIfElseNode) {
            bodyContainingNode.remove(temp);
            if (returned.booleanValue()) {
                // true so the if branch's body has to be added
                // if its a labeled stmt we need a labeled block instead
                // notice that its okkay to put a labeled block since other
                // transformations might remove it
                String label = ((ASTLabeledNode) temp).get_Label().toString();
                if (label != null) {
                    ASTLabeledBlockNode labeledNode = new ASTLabeledBlockNode(((ASTLabeledNode) temp).get_Label(), (List<Object>) temp.get_SubBodies().get(0));
                    bodyContainingNode.add(index, labeledNode);
                } else {
                    bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(0));
                }
            } else {
                // if its a labeled stmt we need a labeled block instead
                // notice that its okkay to put a labeled block since other
                // transformations might remove it
                String label = ((ASTLabeledNode) temp).get_Label().toString();
                if (label != null) {
                    ASTLabeledBlockNode labeledNode = new ASTLabeledBlockNode(((ASTLabeledNode) temp).get_Label(), (List<Object>) temp.get_SubBodies().get(1));
                    bodyContainingNode.add(index, labeledNode);
                } else {
                    bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(1));
                }
            }
            return true;
        } else if (temp instanceof ASTWhileNode && returned.booleanValue() == false) {
            // notice we only remove if ASTWhileNode has false condition
            bodyContainingNode.remove(temp);
            return true;
        } else if (temp instanceof ASTDoWhileNode && returned.booleanValue() == false) {
            // System.out.println("in try dowhile false");
            // remove the loop copy the body out since it gets executed once
            bodyContainingNode.remove(temp);
            bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(0));
            return true;
        } else if (temp instanceof ASTForLoopNode && returned.booleanValue() == false) {
            bodyContainingNode.remove(temp);
            ASTStatementSequenceNode newNode = new ASTStatementSequenceNode(((ASTForLoopNode) temp).getInit());
            bodyContainingNode.add(index, newNode);
            return true;
        }
    }
    return false;
}
Also used : ASTIfNode(soot.dava.internal.AST.ASTIfNode) ASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ASTWhileNode(soot.dava.internal.AST.ASTWhileNode) List(java.util.List) ASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ASTLabeledNode(soot.dava.internal.AST.ASTLabeledNode) ASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) ASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode)

Example 2 with ASTForLoopNode

use of soot.dava.internal.AST.ASTForLoopNode 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 3 with ASTForLoopNode

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

the class ReachingDefs method getReachingDefs.

public List<DefinitionStmt> getReachingDefs(Local local, Object node) {
    ArrayList<DefinitionStmt> toReturn = new ArrayList<DefinitionStmt>();
    // get the reaching defs of this node
    DavaFlowSet<Stmt> beforeSet = null;
    /*
		 * If this object is some sort of loop while, for dowhile, unconditional
		 * then return after set
		 */
    if (node instanceof ASTWhileNode || node instanceof ASTDoWhileNode || node instanceof ASTUnconditionalLoopNode || node instanceof ASTForLoopNode)
        beforeSet = getAfterSet(node);
    else
        beforeSet = getBeforeSet(node);
    if (beforeSet == null) {
        throw new RuntimeException("Could not get reaching defs of node");
    }
    // find all reachingdefs matching this local
    for (Object temp : beforeSet) {
        // checking each def to see if it is a def of local
        if (!(temp instanceof DefinitionStmt))
            throw new RuntimeException("Not an instanceof DefinitionStmt" + temp);
        DefinitionStmt stmt = (DefinitionStmt) temp;
        Value leftOp = stmt.getLeftOp();
        if (leftOp.toString().compareTo(local.toString()) == 0) {
            toReturn.add(stmt);
        }
    }
    return toReturn;
}
Also used : ASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ArrayList(java.util.ArrayList) Value(soot.Value) ASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) DefinitionStmt(soot.jimple.DefinitionStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 4 with ASTForLoopNode

use of soot.dava.internal.AST.ASTForLoopNode 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

ASTDoWhileNode (soot.dava.internal.AST.ASTDoWhileNode)4 ASTForLoopNode (soot.dava.internal.AST.ASTForLoopNode)4 ASTWhileNode (soot.dava.internal.AST.ASTWhileNode)4 ASTUnconditionalLoopNode (soot.dava.internal.AST.ASTUnconditionalLoopNode)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 ASTIfElseNode (soot.dava.internal.AST.ASTIfElseNode)2 ASTIfNode (soot.dava.internal.AST.ASTIfNode)2 ASTLabeledBlockNode (soot.dava.internal.AST.ASTLabeledBlockNode)2 ASTLabeledNode (soot.dava.internal.AST.ASTLabeledNode)2 ASTNode (soot.dava.internal.AST.ASTNode)2 ASTSwitchNode (soot.dava.internal.AST.ASTSwitchNode)2 Stmt (soot.jimple.Stmt)2 Iterator (java.util.Iterator)1 Value (soot.Value)1 DecompilationException (soot.dava.DecompilationException)1 ASTMethodNode (soot.dava.internal.AST.ASTMethodNode)1 ASTStatementSequenceNode (soot.dava.internal.AST.ASTStatementSequenceNode)1 ASTSynchronizedBlockNode (soot.dava.internal.AST.ASTSynchronizedBlockNode)1 ASTTryNode (soot.dava.internal.AST.ASTTryNode)1