}
// System.out.println("method = " + method);
JimpleBody body = (JimpleBody) method.retrieveActiveBody();
Chain units = body.getUnits();
Stmt insertPoint = (Stmt) units.getLast();
Local modelLocal = Jimple.v().newLocal(
"_CGTemp" + modelField.getName(), modelField.getType());
body.getLocals().add(modelLocal);
units.insertBefore(Jimple.v().newAssignStmt(modelLocal,
Jimple.v().newNewExpr(RefType.v(modelClass))), insertPoint);
// the arguments
List args = new LinkedList();
SootMethod constructor = SootUtilities.getMatchingMethod(
modelClass, "<init>", args);
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newSpecialInvokeExpr(modelLocal,
constructor.makeRef(), args)), insertPoint);
FieldRef fieldRef = Jimple.v().newInstanceFieldRef(
body.getThisLocal(), modelField.makeRef());
units.insertBefore(Jimple.v().newAssignStmt(fieldRef, modelLocal),
insertPoint);
// Set the name.
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(modelLocal,
PtolemyUtilities.setNameMethod.makeRef(),
StringConstant.v(_model.getName()))), insertPoint);
// Set the hardcoded iteration limit, if necessary.
int iterationLimit = PhaseOptions.getInt(options, "iterations");
if (iterationLimit != Integer.MAX_VALUE) {
units.insertBefore(Jimple.v().newAssignStmt(
Jimple.v().newInstanceFieldRef(
body.getThisLocal(),
mainClass.getFieldByName("_iterationLimit")
.makeRef()),
IntConstant.v(iterationLimit)), insertPoint);
}
}
try {
// unroll places where the list of models is used.
// We put this in a try block so that we can exclude it
// if necessary
LinkedList modelList = new LinkedList();
modelList.add(modelField);
SootField modelsField = mainClass.getFieldByName("_models");
if (modelsField != null) {
SootUtilities.unrollIteratorInstances(mainClass, modelsField,
modelList);
}
} catch (RuntimeException ex) {
System.out.println("Warning: did not find _models field: " + ex);
for (Iterator methods = mainClass.getMethods().iterator(); methods
.hasNext();) {
SootMethod method = (SootMethod) methods.next();
JimpleBody body = (JimpleBody) method.retrieveActiveBody();
System.out.println("clt: " + method + " " + body);
}
/*
SootUtilities.createAndSetFieldFromLocal(
body,
modelField,
mainClass,
modelField.getType(),
"_model");
*/
}
// Find calls to Manager.startRun() and replace it with
// iteration code.
// Note: It would be nice if we could inline the manager
// code and optimize it, but in this case, the amount of code
// we would want to throw away is fairly large. This
// just seems simpler here.
//SootClass managerClass = Scene.v()
// .getSootClass("ptolemy.actor.Manager");
//SootMethod managerStartRunMethod = managerClass
// .getMethodByName("startRun");
SootMethod mainStartRunMethod = mainClass.getMethodByName("startRun");
for (Iterator methods = mainClass.getMethods().iterator(); methods
.hasNext();) {
SootMethod method = (SootMethod) methods.next();
JimpleBody body = (JimpleBody) method.retrieveActiveBody();
for (Iterator units = body.getUnits().snapshotIterator(); units
.hasNext();) {
Stmt stmt = (Stmt) units.next();
if (!stmt.containsInvokeExpr()) {
continue;
}
ValueBox box = stmt.getInvokeExprBox();
Value value = box.getValue();
if (value instanceof InstanceInvokeExpr) {
InstanceInvokeExpr expr = (InstanceInvokeExpr) value;