use of soot.dava.internal.asg.AugmentedStmt in project soot by Sable.
the class MethodCallFinder method inInvokeStmt.
/*
* some ASTConstuct{ ASTConstruct{ Some bodies Some Bodies Statement
* SequenceNode New Stmt seq node with some stmts some stmts ---------->
* Body of method to inline the invoke stmt New Stmt seq node with other
* stmts some other stmts Some other bodies Some other bodies End
* ASTConstruct End ASTConstruct
*/
/*
* Notice that since this class is only invoked for clinit methods this
* invoke statement is some invocation that occured within the clinit method
*/
public void inInvokeStmt(InvokeStmt s) {
InvokeExpr invokeExpr = s.getInvokeExpr();
SootMethod maybeInline = invokeExpr.getMethod();
// check whether we want to inline
ASTMethodNode toInlineASTMethod = cleaner.inline(maybeInline);
if (toInlineASTMethod == null) {
// not to inline
return;
} else {
// yes we want to inline
// we know that the method to be inlined has no declarations.
List<Object> subBodies = toInlineASTMethod.get_SubBodies();
if (subBodies.size() != 1) {
throw new RuntimeException("Found ASTMEthod node with more than one subBodies");
}
List body = (List) subBodies.get(0);
ASTParentNodeFinder finder = new ASTParentNodeFinder();
underAnalysis.apply(finder);
List<ASTStatementSequenceNode> newChangedBodyPart = createChangedBodyPart(s, body, finder);
boolean replaced = replaceSubBody(s, newChangedBodyPart, finder);
if (replaced) {
// so the invoke stmt has been replaced with the body of the
// method invoked
/*
* if the inlined method contained an assignment to a static
* field we want to replace that with a throw stmt
*/
StaticDefinitionFinder defFinder = new StaticDefinitionFinder(maybeInline);
toInlineASTMethod.apply(defFinder);
if (defFinder.anyFinalFieldDefined()) {
// create throw stmt to be added to inlined method
// create a SootMethodRef
SootClass runtime = Scene.v().loadClassAndSupport("java.lang.RuntimeException");
if (runtime.declaresMethod("void <init>(java.lang.String)")) {
SootMethod sootMethod = runtime.getMethod("void <init>(java.lang.String)");
SootMethodRef methodRef = sootMethod.makeRef();
RefType myRefType = RefType.v(runtime);
StringConstant tempString = StringConstant.v("This method used to have a definition of a final variable. " + "Dava inlined the definition into the static initializer");
List list = new ArrayList();
list.add(tempString);
GNewInvokeExpr newInvokeExpr = new GNewInvokeExpr(myRefType, methodRef, list);
GThrowStmt throwStmt = new GThrowStmt(newInvokeExpr);
AugmentedStmt augStmt = new AugmentedStmt(throwStmt);
List<AugmentedStmt> sequence = new ArrayList<AugmentedStmt>();
sequence.add(augStmt);
ASTStatementSequenceNode seqNode = new ASTStatementSequenceNode(sequence);
List<Object> subBody = new ArrayList<Object>();
subBody.add(seqNode);
toInlineASTMethod.replaceBody(subBody);
}
}
}
}
}
use of soot.dava.internal.asg.AugmentedStmt in project soot by Sable.
the class MethodCallFinder method createChangedBodyPart.
/*
* Given an invoke stmt this method finds the parent of this stmt which
* should always be a StatementSequenceNode Then the sequence is broken into
* three parts. The first part contains stmts till above the invoke stmt.
* The second part contains the body argument which is the body of the
* inlined method and the third part are the stmts below the invoke stmt
*/
public List<ASTStatementSequenceNode> createChangedBodyPart(InvokeStmt s, List body, ASTParentNodeFinder finder) {
// get parent node of invoke stmt
Object parent = finder.getParentOf(s);
if (parent == null) {
throw new RuntimeException("MethodCall FInder: parent of invoke stmt not found");
}
ASTNode parentNode = (ASTNode) parent;
if (!(parentNode instanceof ASTStatementSequenceNode)) {
throw new RuntimeException("MethodCall FInder: parent node not a stmt seq node");
}
ASTStatementSequenceNode orignal = (ASTStatementSequenceNode) parentNode;
// copying the stmts till above the inoke stmt into one stmt sequence
// node
List<AugmentedStmt> newInitialNode = new ArrayList<AugmentedStmt>();
Iterator<AugmentedStmt> it = orignal.getStatements().iterator();
while (it.hasNext()) {
AugmentedStmt as = it.next();
Stmt tempStmt = as.get_Stmt();
if (tempStmt != s) {
newInitialNode.add(as);
} else {
// stmt we break
break;
}
}
// copy remaining stmts into the AFTER stmt sequence node
List<AugmentedStmt> newSecondNode = new ArrayList<AugmentedStmt>();
while (it.hasNext()) {
newSecondNode.add(it.next());
}
List<ASTStatementSequenceNode> toReturn = new ArrayList<ASTStatementSequenceNode>();
if (newInitialNode.size() != 0)
toReturn.add(new ASTStatementSequenceNode(newInitialNode));
// add inline methods body
toReturn.addAll(body);
if (newSecondNode.size() != 0)
toReturn.add(new ASTStatementSequenceNode(newSecondNode));
return toReturn;
}
use of soot.dava.internal.asg.AugmentedStmt in project soot by Sable.
the class StructuredAnalysis method process.
/*
* The parameter body contains the body to be analysed It can be an ASTNode,
* a Stmt, an augmentedStmt or a list of ASTNodes The input is any data that
* is gathered plus any info needed for making decisions during the analysis
*/
public DavaFlowSet<E> process(Object body, DavaFlowSet<E> input) {
if (body instanceof ASTNode) {
beforeSets.put(body, input);
DavaFlowSet<E> temp = processASTNode((ASTNode) body, input);
afterSets.put(body, temp);
return temp;
} else if (body instanceof Stmt) {
beforeSets.put(body, input);
DavaFlowSet<E> result = processAbruptStatements((Stmt) body, input);
afterSets.put(body, result);
return result;
} else if (body instanceof AugmentedStmt) {
AugmentedStmt as = (AugmentedStmt) body;
Stmt s = as.get_Stmt();
beforeSets.put(s, input);
DavaFlowSet<E> result = processAbruptStatements(s, input);
afterSets.put(s, result);
return result;
} else if (body instanceof List) {
// this should always be a list of ASTNodes
Iterator it = ((List) body).iterator();
DavaFlowSet<E> result = input;
while (it.hasNext()) {
Object temp = it.next();
if (!(temp instanceof ASTNode))
throw new RuntimeException("Body sent to be processed by " + "StructuredAnalysis contains a list which does not have ASTNodes");
else {
/*
* As we are simply going through a list of ASTNodes The
* output of the previous becomes the input of the next
*/
beforeSets.put(temp, result);
result = processASTNode((ASTNode) temp, result);
afterSets.put(temp, result);
}
}
// the List
return result;
} else {
throw new RuntimeException("Body sent to be processed by " + "StructuredAnalysis is not a valid body");
}
}
use of soot.dava.internal.asg.AugmentedStmt in project soot by Sable.
the class CPApplication method inASTForLoopNode.
public void inASTForLoopNode(ASTForLoopNode node) {
/*
* For the init part we should actually use the before set for each init
* stmt
*/
for (AugmentedStmt as : node.getInit()) {
Stmt s = as.get_Stmt();
List useBoxes = s.getUseBoxes();
Object obj = cp.getBeforeSet(s);
if (obj == null)
continue;
if (!(obj instanceof CPFlowSet))
continue;
// before set is a non null CPFlowSet
CPFlowSet beforeSet = (CPFlowSet) obj;
// System.out.println("Init Statement: "+s);
// System.out.println("Before set is: "+beforeSet.toString());
/*
* get all use boxes see if their value is determined from the
* before set if yes replace them
*/
substituteUses(useBoxes, beforeSet);
}
// get after set for the condition and update
Object obj = cp.getAfterSet(node);
if (obj == null)
return;
if (!(obj instanceof CPFlowSet))
return;
// after set is a non null CPFlowSet
CPFlowSet afterSet = (CPFlowSet) obj;
// conditon
ASTCondition cond = node.get_Condition();
// System.out.println("For Loop with condition: "+cond);
// System.out.println("After set is: "+afterSet.toString());
changedCondition(cond, afterSet);
// update
for (AugmentedStmt as : node.getUpdate()) {
Stmt s = as.get_Stmt();
List useBoxes = s.getUseBoxes();
// System.out.println("For update Statement: "+s);
// System.out.println("After set is: "+afterSet.toString());
/*
* get all use boxes see if their value is determined from the
* before set if yes replace them
*/
substituteUses(useBoxes, afterSet);
}
}
use of soot.dava.internal.asg.AugmentedStmt in project soot by Sable.
the class CPApplication method inASTStatementSequenceNode.
public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
for (AugmentedStmt as : node.getStatements()) {
Stmt s = as.get_Stmt();
List useBoxes = s.getUseBoxes();
Object obj = cp.getBeforeSet(s);
if (obj == null)
continue;
if (!(obj instanceof CPFlowSet))
continue;
// before set is a non null CPFlowSet
CPFlowSet beforeSet = (CPFlowSet) obj;
// System.out.println("Statement: "+s);
// System.out.println("Before set is: "+beforeSet.toString());
/*
* get all use boxes see if their value is determined from the
* before set if yes replace them
*/
substituteUses(useBoxes, beforeSet);
}
}
Aggregations