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