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;
}
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;
}
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;
}
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;
}
}
Aggregations