use of soot.dava.DecompilationException in project soot by Sable.
the class CPFlowSet method intersection.
/*
* The intersection method is called by the object whose set is to be intersected with otherFlow
* and the result to be stored in destFlow
*
* So we will be intersecting elements of "this" and otherFlow
*
* Definition of Intersection:
* If an element e belongs to Set A then Set A ^ B contains e
* if B contains an element such that the constantpropagationFlowSet equals method returns true
* (this will happen if they have the same variable and the same value which better not be TOP)
*
* If the element e is not added to set A ^ B then element e should be changed to hold TOP as the value
* is unknown and that value should be added to the set A ^ B
*
*
*/
public void intersection(FlowSet otherFlow, FlowSet destFlow) {
// System.out.println("In specialized intersection for CopyPropagation");
if (!(otherFlow instanceof CPFlowSet && destFlow instanceof CPFlowSet)) {
super.intersection(otherFlow, destFlow);
return;
}
CPFlowSet other = (CPFlowSet) otherFlow;
CPFlowSet dest = (CPFlowSet) destFlow;
CPFlowSet workingSet;
if (dest == other || dest == this)
workingSet = new CPFlowSet();
else {
workingSet = dest;
workingSet.clear();
}
for (int i = 0; i < this.numElements; i++) {
CPTuple thisTuple = this.getElementAt(i);
String className = thisTuple.getSootClassName();
CPVariable thisVar = thisTuple.getVariable();
CPTuple matchFound = null;
/*
* Find a matching tuple if one exists
*/
CPTuple otherTuple = null;
for (int j = 0; j < other.numElements; j++) {
otherTuple = other.getElementAt(j);
/*
* wont use the CPTuple equal method since that ignores tops
* we want to implement the intersection rules given in the merge table
*/
// check that the two tuples have the same class
String tempClass = otherTuple.getSootClassName();
if (!tempClass.equals(className))
continue;
// Check that the variable contained is the same name and type (local or sootfield)
if (!otherTuple.getVariable().equals(thisVar))
continue;
// match of sootClass and Variable have to use merge table on matchFound and elements[i]
matchFound = otherTuple;
break;
}
if (matchFound != null) {
if (thisTuple.isTop()) {
// cases 8 and 9
workingSet.add(thisTuple.clone());
} else if (matchFound.isTop()) {
// case 6
workingSet.add(matchFound.clone());
} else if (!matchFound.isTop() && !thisTuple.isTop()) {
// this has to be case 5 since there is no other case possible
Object matchedValue = matchFound.getValue();
Object thisValue = thisTuple.getValue();
// using the equals method of Boolean/Float/Integer etc
if (matchedValue.equals(thisValue)) {
workingSet.add(thisTuple.clone());
} else {
// if we get here either the types dont match or the values didnt match just add top
workingSet.add(new CPTuple(className, thisVar, true));
}
} else {
throw new DecompilationException("Ran out of cases in CPVariable values...report bug to developer");
}
} else // if match was found
{
// could not find a match for element[i] in other hence its bottom in other
// CASE 4 and 7 (cant be case 1 since element[i]s presence means its not bottom
// add CLONE OF element[i] to working set unchanged
/*
* TODO: why should a field be turned to TOP... a field is only a constant value field and hence
* should never be changed!!!!!
*
* BUG FOUND DUE TO CHROMOSOME benchmark if(Debug.flag) was not being detected as it was being
* set to top
*
* April 3rd 2006
*/
/* if(thisTuple.containsField()){
//add top
workingSet.add(new CPTuple(thisTuple.getSootClassName(),thisTuple.getVariable(),true));
}
else if(thisTuple.containsLocal()){
*/
workingSet.add(thisTuple.clone());
/*}
else
throw new DecompilationException("CPVariable is not local and not field");
*/
}
}
for (int i = 0; i < other.numElements; i++) {
CPTuple otherTuple = other.getElementAt(i);
String otherClassName = otherTuple.getSootClassName();
CPVariable otherVar = otherTuple.getVariable();
// System.out.print("\t Other:"+otherVar.toString());
boolean inBoth = false;
for (int j = 0; j < this.numElements; j++) {
CPTuple thisTuple = this.getElementAt(j);
String thisClassName = thisTuple.getSootClassName();
CPVariable thisVar = thisTuple.getVariable();
if (!otherClassName.equals(thisClassName)) {
continue;
}
if (!thisVar.equals(otherVar)) {
continue;
}
// if we get here we know both sets have this variable so this is not case 2 or 3
// System.out.println(">>>> FOUND"+thisVar.toString());
inBoth = true;
break;
}
if (!inBoth) {
// System.out.println("....NOT FOUND ....SET IS:"+this.toString());
// not in both so this is case 2 or 3
/*
* clone and add if its local
*
* if field then add top
*/
/*
* TODO why should a field be converted to TOP when all the fiels are only constant value fields
*/
/* if(otherTuple.containsField()){
//add top
workingSet.add(new CPTuple(otherTuple.getSootClassName(),otherTuple.getVariable(),true));
}
else if(otherTuple.containsLocal()){
*/
workingSet.add(otherTuple.clone());
/* }
else
throw new DecompilationException("CPVariable is not local and not field");
*/
}
}
// end going through other elements
}
use of soot.dava.DecompilationException in project soot by Sable.
the class LocalVariableCleaner method outASTMethodNode.
/*
* Get all locals declared in the method
* If the local is never defined (and hence never used) remove it
* If the local is defined BUT never used then you may remove it IF AND ONLY IF
* The definition is either a copy stmt or an assignment of a constant (i.e. no side effects)
*/
public void outASTMethodNode(ASTMethodNode node) {
boolean redo = false;
// create the uD and dU chains
useDefs = new ASTUsesAndDefs(AST);
AST.apply(useDefs);
// get all local variables declared in this method
Iterator decIt = node.getDeclaredLocals().iterator();
ArrayList<Local> removeList = new ArrayList<Local>();
while (decIt.hasNext()) {
// going through each local declared
Local var = (Local) decIt.next();
List<DefinitionStmt> defs = getDefs(var);
// if defs is 0 it means var never got defined
if (defs.size() == 0) {
// var is never defined and hence is certainly not used anywhere
removeList.add(var);
} else {
// if a var is defined but not used then in some conditions we can remove it
// check that each def is removable
Iterator<DefinitionStmt> defIt = defs.iterator();
while (defIt.hasNext()) {
DefinitionStmt ds = defIt.next();
if (canRemoveDef(ds)) {
// if removeStmt is successful since something change we need to redo
// everything hoping something else might be removed....
// in this case method returns true
redo = removeStmt(ds);
}
}
// while going through defs
}
// end else defs was not zero
}
// going through each stmt
// go through the removeList and remove all locals
Iterator<Local> remIt = removeList.iterator();
while (remIt.hasNext()) {
Local removeLocal = remIt.next();
node.removeDeclaredLocal(removeLocal);
// retrieve DavaBody
if (AST instanceof ASTMethodNode) {
// this should always be true but whatever
DavaBody body = ((ASTMethodNode) AST).getDavaBody();
if (DEBUG) {
System.out.println("body information");
System.out.println("Control local is: " + body.get_ControlLocal());
System.out.println("his locals are: " + body.get_ThisLocals());
System.out.println("Param Map is: " + body.get_ParamMap());
System.out.println("Locals are:" + body.getLocals());
}
Collection<Local> localChain = body.getLocals();
if (removeLocal != null && localChain != null)
localChain.remove(removeLocal);
} else
throw new DecompilationException("found AST which is not a methodNode");
if (DEBUG)
System.out.println("Removed" + removeLocal);
redo = true;
}
if (redo) {
// redo the whole function
outASTMethodNode(node);
}
}
use of soot.dava.DecompilationException in project soot by Sable.
the class SuperFirstStmtHandler method createDavaStoreStmts.
/*
* Create the following code:
*
* DavaSuperHandler handler; handler = new DavaSuperHandler(); //code to
* evaluate all args in args2
*
* //evaluate 1st arg in args2 --------- handler.store(firstArg);
*
* //evaluate 2nd arg in args2 --------- handler.store(secondArg);
*
* //AND SO ON TILL ALL ARGS ARE FINISHED
*
* return handler;
*/
private void createDavaStoreStmts() {
List<AugmentedStmt> davaHandlerStmts = new ArrayList<AugmentedStmt>();
// create object of DavaSuperHandler handler
SootClass sootClass = new SootClass("DavaSuperHandler");
Type localType = sootClass.getType();
Local newLocal = new JimpleLocal("handler", localType);
/*
* Create * DavaSuperHandler handler; *
*/
DVariableDeclarationStmt varStmt = null;
varStmt = new DVariableDeclarationStmt(localType, newPreInitDavaBody);
varStmt.addLocal(newLocal);
AugmentedStmt as = new AugmentedStmt(varStmt);
davaHandlerStmts.add(as);
/*
* create * handler = new DavaSuperHandler(); *
*/
// create RHS
DNewInvokeExpr invokeExpr = new DNewInvokeExpr(RefType.v(sootClass), makeMethodRef("DavaSuperHandler", new ArrayList()), new ArrayList());
// create LHS
GAssignStmt initialization = new GAssignStmt(newLocal, invokeExpr);
// add to stmts
davaHandlerStmts.add(new AugmentedStmt(initialization));
/*
* create * handler.store(firstArg); *
*/
// best done in a loop for all args
Iterator typeIt = argsTwoTypes.iterator();
Iterator valIt = argsTwoValues.iterator();
// make reference to a method of name store takes one Object arg belongs
// to DavaSuperHandler
ArrayList tempList = new ArrayList();
// SHOULD BE OBJECT
tempList.add(RefType.v("java.lang.Object"));
SootMethod method = Scene.v().makeSootMethod("store", tempList, VoidType.v());
// set the declaring class of new method to be the DavaSuperHandler
// class
method.setDeclaringClass(sootClass);
SootMethodRef getMethodRef = method.makeRef();
while (typeIt.hasNext() && valIt.hasNext()) {
Type tempType = (Type) typeIt.next();
Value tempVal = (Value) valIt.next();
AugmentedStmt toAdd = createStmtAccordingToType(tempType, tempVal, newLocal, getMethodRef);
davaHandlerStmts.add(toAdd);
}
// sanity check
if (typeIt.hasNext() || valIt.hasNext())
throw new DecompilationException("Error creating DavaHandler stmts");
/*
* code to add defs
*/
List<Local> uniqueLocals = addDefsToLiveVariables();
Iterator<Local> localIt = uniqueLocals.iterator();
while (localIt.hasNext()) {
Local local = localIt.next();
AugmentedStmt toAdd = createStmtAccordingToType(local.getType(), local, newLocal, getMethodRef);
davaHandlerStmts.add(toAdd);
}
// set the mustInitialize field to uniqueLocals so that before Y we can
// assign these locals
mustInitialize = uniqueLocals;
/*
* create * return handler; *
*/
GReturnStmt returnStmt = new GReturnStmt(newLocal);
davaHandlerStmts.add(new AugmentedStmt(returnStmt));
// the appropriate dava handler stmts are all in place within
// davaHandlerStmts
// store them in an ASTSTatementSequenceNode
ASTStatementSequenceNode addedNode = new ASTStatementSequenceNode(davaHandlerStmts);
// add to method body
List<Object> subBodies = newASTPreInitMethod.get_SubBodies();
if (subBodies.size() != 1)
throw new CorruptASTException("ASTMethodNode does not have one subBody");
List<Object> body = (List<Object>) subBodies.get(0);
body.add(addedNode);
newASTPreInitMethod.replaceBody(body);
}
use of soot.dava.DecompilationException in project soot by Sable.
the class SuperFirstStmtHandler method createNewASTConstructor.
public void createNewASTConstructor(ASTStatementSequenceNode initNode) {
List<Object> newConstructorBody = new ArrayList<Object>();
List<AugmentedStmt> newStmts = new ArrayList<AugmentedStmt>();
/*
* add any definitions to live variables that might be in body X
*/
// we have gotten argsTwoType size() out of the handler so thats the
// index count
// mustInitialize has the live variables that need to be initialized
// create new ReftType for DavaSuperHandler
RefType type = (new SootClass("DavaSuperHandler")).getType();
// make JimpleLocal to be used in each arg
// takes care of
Local jimpleLocal = new JimpleLocal("handler", type);
// handler
// make reference to a method of name get takes one int arg belongs to
// DavaSuperHandler
ArrayList tempList = new ArrayList();
tempList.add(IntType.v());
SootMethodRef getMethodRef = makeMethodRef("get", tempList);
// Iterator typeIt = argsTwoTypes.iterator();
if (mustInitialize != null) {
Iterator<Local> initIt = mustInitialize.iterator();
while (initIt.hasNext()) {
Local initLocal = initIt.next();
Type tempType = initLocal.getType();
// takes
DIntConstant arg = DIntConstant.v(mustInitializeIndex, IntType.v());
// care
// of
// the
// index
mustInitializeIndex++;
ArrayList tempArgList = new ArrayList();
tempArgList.add(arg);
DVirtualInvokeExpr tempInvokeExpr = new DVirtualInvokeExpr(jimpleLocal, getMethodRef, tempArgList, new HashSet<Object>());
// NECESASARY CASTING OR RETRIEVAL OF PRIM TYPES TO BE DONE HERE
Value toAddExpr = getProperCasting(tempType, tempInvokeExpr);
if (toAddExpr == null)
throw new DecompilationException("UNABLE TO CREATE TOADDEXPR:" + tempType);
// need to create a def stmt with the local on the left and
// toAddExpr on the right
GAssignStmt assign = new GAssignStmt(initLocal, toAddExpr);
newStmts.add(new AugmentedStmt(assign));
}
}
// add any statements following the this.<init> statement
Iterator<AugmentedStmt> it = initNode.getStatements().iterator();
while (it.hasNext()) {
AugmentedStmt augStmt = (AugmentedStmt) it.next();
Stmt stmtTemp = augStmt.get_Stmt();
if (stmtTemp == originalConstructorUnit) {
break;
}
}
while (it.hasNext()) {
/*
* notice we dont need to clone these because these will be removed
* from the other method from which we are copying these
*/
newStmts.add(it.next());
}
if (newStmts.size() > 0) {
newConstructorBody.add(new ASTStatementSequenceNode(newStmts));
}
// adding body Y now
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> itOld = oldASTBody.iterator();
boolean sanity = false;
while (itOld.hasNext()) {
// going through originalASTMethodNode's ASTNodes
ASTNode tempNode = (ASTNode) itOld.next();
// enter only if its not the initNode
if (tempNode instanceof ASTStatementSequenceNode) {
if ((((ASTStatementSequenceNode) tempNode).getStatements()).equals(initNode.getStatements())) {
sanity = true;
break;
}
}
}
if (!sanity) {
// means we never found the initNode which shouldnt happen
throw new DecompilationException("never found the init node");
}
// Y are all the nodes following the initNode
while (itOld.hasNext()) {
newConstructorBody.add(itOld.next());
}
// setDeclarations in newNode
// The LocalVariableCleaner which is called in the end of DavaBody will
// clear up any declarations that are not required
List<AugmentedStmt> newConstructorDeclarations = new ArrayList<AugmentedStmt>();
for (AugmentedStmt as : originalASTMethod.getDeclarations().getStatements()) {
DVariableDeclarationStmt varDecStmt = (DVariableDeclarationStmt) as.get_Stmt();
newConstructorDeclarations.add(new AugmentedStmt((DVariableDeclarationStmt) varDecStmt.clone()));
}
ASTStatementSequenceNode newDecs = new ASTStatementSequenceNode(new ArrayList<AugmentedStmt>());
if (newConstructorDeclarations.size() > 0) {
newDecs = new ASTStatementSequenceNode(newConstructorDeclarations);
// DONT FORGET TO SET THE DECLARATIONS IN THE METHOD ONCE IT IS
// CREATED
// newASTConstructorMethod.setDeclarations(newDecs);
// declarations are always the first element
newConstructorBody.add(0, newDecs);
}
// so we have any declarations followed by body Y
// have to put the newConstructorBody into an list of subBodies which
// goes into the newASTConstructorMethod
newASTConstructorMethod = new ASTMethodNode(newConstructorBody);
// dont forget to set the declarations
newASTConstructorMethod.setDeclarations(newDecs);
}
use of soot.dava.DecompilationException 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);
}
Aggregations