use of soot.dava.toolkits.base.AST.traversals.ASTUsesAndDefs in project soot by Sable.
the class SuperFirstStmtHandler method addDefsToLiveVariables.
/*
* newASTPreInitMethod at time of invocation just contains body X find all
* defs for this body
*/
private List<Local> addDefsToLiveVariables() {
// get all defs within x
AllDefinitionsFinder finder = new AllDefinitionsFinder();
newASTPreInitMethod.apply(finder);
List<DefinitionStmt> allDefs = finder.getAllDefs();
List<Local> uniqueLocals = new ArrayList<Local>();
List<DefinitionStmt> uniqueLocalDefs = new ArrayList<DefinitionStmt>();
// remove any defs for fields, and any which are done multiple times
Iterator<DefinitionStmt> it = allDefs.iterator();
while (it.hasNext()) {
DefinitionStmt s = it.next();
Value left = s.getLeftOp();
if (left instanceof Local) {
if (uniqueLocals.contains(left)) {
// a def for this local already encountered
int index = uniqueLocals.indexOf(left);
uniqueLocals.remove(index);
uniqueLocalDefs.remove(index);
} else {
// no def for this local yet
uniqueLocals.add((Local) left);
uniqueLocalDefs.add(s);
}
}
}
// at this point unique locals contains all locals defined and
// uniqueLocaldef list has a list of the corresponding definitions
// Now remove those unique locals and localdefs whose stmtseq node does
// not have the ASTMEthodNode as a parent
// This is a conservative step!!
ASTParentNodeFinder parentFinder = new ASTParentNodeFinder();
newASTPreInitMethod.apply(parentFinder);
List<DefinitionStmt> toRemoveDefs = new ArrayList<DefinitionStmt>();
it = uniqueLocalDefs.iterator();
while (it.hasNext()) {
DefinitionStmt s = it.next();
Object parent = parentFinder.getParentOf(s);
if (parent == null || (!(parent instanceof ASTStatementSequenceNode))) {
// shouldnt happen but if it does add this s to toRemove list
toRemoveDefs.add(s);
}
// parent is an ASTStatementsequence node. check that its parent is
// the ASTMethodNode
Object grandParent = parentFinder.getParentOf(parent);
if (grandParent == null || (!(grandParent instanceof ASTMethodNode))) {
// can happen if obfuscators are really smart. add s to toRemove
// list
toRemoveDefs.add(s);
}
}
// remove any defs and corresponding locals if present in the
// toRemoveDefs list
it = toRemoveDefs.iterator();
while (it.hasNext()) {
DefinitionStmt s = it.next();
int index = uniqueLocalDefs.indexOf(s);
uniqueLocals.remove(index);
uniqueLocalDefs.remove(index);
}
// the uniqueLocalDefs contains all those definitions to unique locals
// which are not deeply nested in the X body
// find all the uses of these definitions in the original method body
toRemoveDefs = new ArrayList<DefinitionStmt>();
ASTUsesAndDefs uDdU = new ASTUsesAndDefs(originalASTMethod);
originalASTMethod.apply(uDdU);
it = uniqueLocalDefs.iterator();
while (it.hasNext()) {
DefinitionStmt s = it.next();
Object temp = uDdU.getDUChain(s);
if (temp == null) {
// couldnt find uses
toRemoveDefs.add(s);
continue;
}
ArrayList uses = (ArrayList) temp;
// check if uses is non-empty
if (uses.size() == 0) {
toRemoveDefs.add(s);
}
// check for all the non zero uses
Iterator useIt = uses.iterator();
boolean onlyInConstructorUnit = true;
while (useIt.hasNext()) {
// a use is either a statement or a node(condition, synch,
// switch , for etc)
Object tempUse = useIt.next();
if (tempUse != originalConstructorUnit) {
onlyInConstructorUnit = false;
}
}
if (onlyInConstructorUnit) {
// mark it to be removed
toRemoveDefs.add(s);
}
}
// remove any defs and corresponding locals if present in the
// toRemoveDefs list
it = toRemoveDefs.iterator();
while (it.hasNext()) {
DefinitionStmt s = it.next();
int index = uniqueLocalDefs.indexOf(s);
uniqueLocals.remove(index);
uniqueLocalDefs.remove(index);
}
// the remaining uniquelocals are the ones which are needed for body Y
return uniqueLocals;
}
Aggregations