package soottocfg.soot.memory_model;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import soottocfg.cfg.Program;
import soottocfg.cfg.SourceLocation;
import soottocfg.cfg.expression.Expression;
import soottocfg.cfg.expression.IdentifierExpression;
import soottocfg.cfg.method.CfgBlock;
import soottocfg.cfg.method.Method;
import soottocfg.cfg.statement.PullStatement;
import soottocfg.cfg.statement.PushStatement;
import soottocfg.cfg.statement.Statement;
import soottocfg.cfg.type.ReferenceType;
import soottocfg.cfg.util.InterProceduralPullPushOrdering;
import soottocfg.cfg.variable.Variable;
/**
* @author Rody Kersten
*
*/
public class PushIdentifierAdder {
private static boolean debug = false;
public void addIDs(Program p) {
InterProceduralPullPushOrdering ordering = new InterProceduralPullPushOrdering(p.getEntryPoint());
Method[] ms = p.getMethods();
for (Method m : ms) {
if (debug) {
System.out.println("Adding IDs to method " + m.getMethodName());
// System.out.println(m);
}
Set<CfgBlock> blocks = m.vertexSet();
for (CfgBlock b : blocks) {
List<Statement> stmts = b.getStatements();
for (int i = 0; i < stmts.size(); i++) {
Statement s = stmts.get(i);
if (s instanceof PullStatement) {
PullStatement pull = (PullStatement) s;
Set<PushStatement> pushes = ordering.getPushsInfluencing(pull);
// Add push of havoced values on the fly if there is none (e.g. because the
// object was returned by a library call).
if (pushes.isEmpty()) {
if (debug)
System.out.println("Adding push on the fly for " + pull.getObject());
ReferenceType rt = (ReferenceType) pull.getObject().getType();
SourceLocation loc = pull.getSourceLocation();
IdentifierExpression id = (IdentifierExpression) pull.getObject();
List<Expression> rhs = new LinkedList<Expression>();
int n = 0;
for (Variable v : rt.getClassVariable().getAssociatedFields()) {
// if (SootTranslationHelpers.isDynamicTypeVar(v)) {
// //Make sure that we set the correct dynamic type.
// rhs.add(new IdentifierExpression(loc, rt.getClassVariable()));
// } else {
Variable undefLocal = new Variable("undef_" + id + "_" + (n++), v.getType());
rhs.add(new IdentifierExpression(loc, undefLocal));
// }
}
PushStatement push = new PushStatement(loc, rt.getClassVariable(), id, rhs);
b.addStatement(i++,push);
pushes.add(push);
if (debug) {
System.out.println("Added push: " + push);
System.out.println(b);
}
}
pull.canAffect(pushes);
if (debug) {
System.out.println("Pushes influencing " + pull + ": ");
for (PushStatement push : pushes)
System.out.println(push);
}
}
}
}
if (debug)
System.out.println("DONE:\n" + m);
}
}
}