Search in sources :

Example 26 with ASTNode

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

the class SuperFirstStmtHandler method createNewASTPreInitMethod.

/*
	 * January 23rd New Algorithm Leave originalASTMethod unchanged Clone
	 * everything and copy only those which are needed in the
	 * newASTPreInitMethod
	 */
private void createNewASTPreInitMethod(ASTStatementSequenceNode initNode) {
    List<Object> newPreinitBody = new ArrayList<Object>();
    // start adding ASTNodes into newPreinitBody from the
    // originalASTMethod's body until we reach initNode
    List<Object> originalASTMethodSubBodies = originalASTMethod.get_SubBodies();
    if (originalASTMethodSubBodies.size() != 1)
        throw new CorruptASTException("size of ASTMethodNode subBody not 1");
    List<Object> oldASTBody = (List<Object>) originalASTMethodSubBodies.get(0);
    Iterator<Object> it = oldASTBody.iterator();
    boolean sanity = false;
    while (it.hasNext()) {
        // going through originalASTMethodNode's ASTNodes
        ASTNode tempNode = (ASTNode) it.next();
        // enter only if its not the initNode
        if (tempNode instanceof ASTStatementSequenceNode) {
            if ((((ASTStatementSequenceNode) tempNode).getStatements()).equals(initNode.getStatements())) {
                sanity = true;
                break;
            } else {
                // this was not the initNode so we add
                newPreinitBody.add(tempNode);
            }
        } else {
            // not a stmtseq so simply add it
            newPreinitBody.add(tempNode);
        }
    }
    if (!sanity) {
        // means we never found the initNode which shouldnt happen
        throw new DecompilationException("never found the init node");
    }
    // at this moment newPreinitBody contains all of X except for any stmts
    // above the this.init call in the stmtseq node
    // copy those
    List<AugmentedStmt> newStmts = new ArrayList<AugmentedStmt>();
    for (AugmentedStmt augStmt : initNode.getStatements()) {
        Stmt stmtTemp = augStmt.get_Stmt();
        if (stmtTemp == originalConstructorUnit) {
            break;
        }
        // adding any stmt until constructorUnit into topList for
        // newMethodNode
        /*
			 * notice we dont need to clone these because these will be removed
			 * from the other method from which we are copying these
			 */
        newStmts.add(augStmt);
    }
    if (newStmts.size() > 0) {
        newPreinitBody.add(new ASTStatementSequenceNode(newStmts));
    }
    // setDeclarations in newNode
    // The LocalVariableCleaner which is called in the end of DavaBody will
    // clear up any declarations that are not required
    List<AugmentedStmt> newPreinitDeclarations = new ArrayList<AugmentedStmt>();
    for (AugmentedStmt as : originalASTMethod.getDeclarations().getStatements()) {
        DVariableDeclarationStmt varDecStmt = (DVariableDeclarationStmt) as.get_Stmt();
        newPreinitDeclarations.add(new AugmentedStmt((DVariableDeclarationStmt) varDecStmt.clone()));
    }
    ASTStatementSequenceNode newDecs = new ASTStatementSequenceNode(new ArrayList<AugmentedStmt>());
    if (newPreinitDeclarations.size() > 0) {
        newDecs = new ASTStatementSequenceNode(newPreinitDeclarations);
        // DONT FORGET TO SET THE DECLARATIONS IN THE METHOD ONCE IT IS
        // CREATED
        // newASTPreInitMethod.setDeclarations(newDecs);
        // when we copied the body X the first Node copied was the
        // Declarations from the originalASTMethod
        // replace that with this new one
        newPreinitBody.remove(0);
        newPreinitBody.add(0, newDecs);
    }
    // otherwise super is infact the first stmt
    if (newPreinitBody.size() < 1) {
        // System.out.println("Method node empty doing nothing returning");
        // meaning ASTMethodNode for this method
        newASTPreInitMethod = null;
        // not created
        return;
    }
    // so we have any declarations followed by body X
    // NEXT THING SHOULD BE CODE TO CREATE A DAVAHANDLER AND STORE THE ARGS
    // TO SUPER IN IT
    // HOWEVER WE WILL DELAY THIS TILL UNTIL WE ARE READY TO FINALIZE the
    // PREINIT
    // reason for delaying is that even though we know that the body is not
    // empty the body
    // could be made empty by the transformations which act in the finalize
    // method
    // have to put the newPreinitBody into an list of subBodies which goes
    // into the newASTPreInitMethod
    newASTPreInitMethod = new ASTMethodNode(newPreinitBody);
    // dont forget to set the declarations
    newASTPreInitMethod.setDeclarations(newDecs);
}
Also used : DVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) CorruptASTException(soot.dava.CorruptASTException) ArrayList(java.util.ArrayList) DecompilationException(soot.dava.DecompilationException) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) GReturnStmt(soot.grimp.internal.GReturnStmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) DVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) GInvokeStmt(soot.grimp.internal.GInvokeStmt) Stmt(soot.jimple.Stmt) GAssignStmt(soot.grimp.internal.GAssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) ASTNode(soot.dava.internal.AST.ASTNode) List(java.util.List) ArrayList(java.util.ArrayList) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode)

Example 27 with ASTNode

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

Example 28 with ASTNode

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

the class UnreachableCodeEliminator method caseASTTryNode.

// TODO
public void caseASTTryNode(ASTTryNode node) {
    // get try body
    List<Object> tryBody = node.get_TryBody();
    Iterator<Object> it = tryBody.iterator();
    // go over the ASTNodes in this tryBody and apply
    List<Object> toReturn = new ArrayList<Object>();
    while (it.hasNext()) {
        ASTNode temp = (ASTNode) it.next();
        if (!codeFinder.isConstructReachable(temp)) {
            toReturn.add(temp);
        } else {
            // only apply on reachable nodes
            temp.apply(this);
        }
    }
    it = toReturn.iterator();
    while (it.hasNext()) {
        tryBody.remove(it.next());
    }
    Map<Object, Object> exceptionMap = node.get_ExceptionMap();
    Map<Object, Object> paramMap = node.get_ParamMap();
    // get catch list and apply on the following
    // a, type of exception caught
    // b, local of exception
    // c, catchBody
    List<Object> catchList = node.get_CatchList();
    Iterator<Object> itBody = null;
    it = catchList.iterator();
    while (it.hasNext()) {
        ASTTryNode.container catchBody = (ASTTryNode.container) it.next();
        SootClass sootClass = ((SootClass) exceptionMap.get(catchBody));
        Type type = sootClass.getType();
        // apply on type of exception
        caseType(type);
        // apply on local of exception
        Local local = (Local) paramMap.get(catchBody);
        /*
			 * March 18th, 2006, Since these are always locals we dont have access to ValueBox
			 */
        decideCaseExprOrRef(local);
        // apply on catchBody
        List<Object> body = (List<Object>) catchBody.o;
        toReturn = new ArrayList<Object>();
        itBody = body.iterator();
        while (itBody.hasNext()) {
            ASTNode temp = (ASTNode) itBody.next();
            if (!codeFinder.isConstructReachable(temp)) {
                toReturn.add(temp);
            } else {
                // only apply on reachable nodes
                temp.apply(this);
            }
        }
        itBody = toReturn.iterator();
        while (itBody.hasNext()) {
            body.remove(itBody.next());
        }
    }
}
Also used : ASTTryNode(soot.dava.internal.AST.ASTTryNode) ArrayList(java.util.ArrayList) Local(soot.Local) SootClass(soot.SootClass) Type(soot.Type) ASTNode(soot.dava.internal.AST.ASTNode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 29 with ASTNode

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

the class UnreachableCodeEliminator method dealWithSwitchNode.

private void dealWithSwitchNode(ASTSwitchNode node) {
    // System.out.println("dealing with SwitchNode");
    // do a depthfirst on elements of the switchNode
    List<Object> indexList = node.getIndexList();
    Map<Object, List<Object>> index2BodyList = node.getIndex2BodyList();
    Iterator<Object> it = indexList.iterator();
    while (it.hasNext()) {
        // going through all the cases of the switch statement
        Object currentIndex = it.next();
        List body = index2BodyList.get(currentIndex);
        if (body == null)
            continue;
        // this body is a list of ASTNodes
        List<ASTNode> toReturn = new ArrayList<ASTNode>();
        Iterator itBody = body.iterator();
        // go over the ASTNodes and apply
        while (itBody.hasNext()) {
            ASTNode temp = (ASTNode) itBody.next();
            // System.out.println("Checking whether child of type "+temp.getClass()+" is reachable");
            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 {
                // System.out.println("child of type "+temp.getClass()+" is reachable");
                // only apply on reachable nodes
                temp.apply(this);
            }
        }
        Iterator<ASTNode> newit = toReturn.iterator();
        while (newit.hasNext()) {
            // System.out.println("Removed");
            body.remove(newit.next());
        }
    }
}
Also used : ASTNode(soot.dava.internal.AST.ASTNode) ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

ASTNode (soot.dava.internal.AST.ASTNode)29 ArrayList (java.util.ArrayList)14 List (java.util.List)13 Iterator (java.util.Iterator)12 AugmentedStmt (soot.dava.internal.asg.AugmentedStmt)9 Stmt (soot.jimple.Stmt)9 ASTMethodNode (soot.dava.internal.AST.ASTMethodNode)7 ASTStatementSequenceNode (soot.dava.internal.AST.ASTStatementSequenceNode)7 DefinitionStmt (soot.jimple.DefinitionStmt)6 SootClass (soot.SootClass)4 SootMethod (soot.SootMethod)4 ASTControlFlowNode (soot.dava.internal.AST.ASTControlFlowNode)4 ASTSwitchNode (soot.dava.internal.AST.ASTSwitchNode)4 DVariableDeclarationStmt (soot.dava.internal.javaRep.DVariableDeclarationStmt)4 Body (soot.Body)3 Value (soot.Value)3 DavaBody (soot.dava.DavaBody)3 DecompilationException (soot.dava.DecompilationException)3 ASTTryNode (soot.dava.internal.AST.ASTTryNode)3 GAssignStmt (soot.grimp.internal.GAssignStmt)3