SootField postfireReturnsField = new SootField("_postfireReturns",
BooleanType.v(), Modifier.PRIVATE);
modelClass.addField(postfireReturnsField);
int iterationLimit = 0;
SDFDirector director = (SDFDirector) model.getDirector();
if (director != null) {
Attribute attribute = director.getAttribute("iterations");
if (attribute instanceof Variable) {
IntToken token = (IntToken) ((Variable) attribute).getToken();
iterationLimit = token.intValue();
}
}
// Inline the director
{
// populate the preinitialize method
SootMethod classMethod = modelClass
.getMethodByName("preinitialize");
JimpleBody body = (JimpleBody) classMethod.getActiveBody();
Stmt insertPoint = body.getFirstNonIdentityStmt();
Chain units = body.getUnits();
Local thisLocal = body.getThisLocal();
Local postfireReturnsLocal = Jimple.v().newLocal("postfireReturns",
BooleanType.v());
body.getLocals().add(postfireReturnsLocal);
// Initialize the postfire flag.
units.insertBefore(Jimple.v().newAssignStmt(postfireReturnsLocal,
IntConstant.v(1)), insertPoint);
units.insertBefore(Jimple.v().newAssignStmt(
Jimple.v().newInstanceFieldRef(thisLocal,
postfireReturnsField.makeRef()),
postfireReturnsLocal), insertPoint);
// Add code to the beginning of the preinitialize method that
// initializes the attributes.
// ModelTransformer.initializeAttributesBefore(body, insertPoint,
// model, body.getThisLocal(),
// model, body.getThisLocal(),
// modelClass);
for (Iterator entities = model.deepEntityList().iterator(); entities
.hasNext();) {
Entity entity = (Entity) entities.next();
String fieldName = ModelTransformer.getFieldNameForEntity(
entity, model);
SootField field = modelClass.getFieldByName(fieldName);
String className = ModelTransformer.getInstanceClassName(
entity, options);
SootClass theClass = Scene.v().loadClassAndSupport(className);
SootMethod preinitializeMethod = SootUtilities
.searchForMethodByName(theClass, "preinitialize");
Local actorLocal = Jimple.v().newLocal("actor",
RefType.v(theClass));
body.getLocals().add(actorLocal);
// Get the field.
units.insertBefore(Jimple.v().newAssignStmt(
actorLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
field.makeRef())), insertPoint);
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(actorLocal,
preinitializeMethod.makeRef())), insertPoint);
}
// units.insertBefore(Jimple.v().newReturnVoidStmt(),
// insertPoint);
}
SootField iterationField = new SootField("_iteration", IntType.v());
modelClass.addField(iterationField);
{
// populate the initialize method
SootMethod classMethod = modelClass.getMethodByName("initialize");
JimpleBody body = (JimpleBody) classMethod.getActiveBody();
Stmt insertPoint = body.getFirstNonIdentityStmt();
Chain units = body.getUnits();
Local thisLocal = body.getThisLocal();
if (iterationLimit > 0) {
units.insertBefore(Jimple.v().newAssignStmt(
Jimple.v().newInstanceFieldRef(thisLocal,
iterationField.makeRef()), IntConstant.v(0)),
insertPoint);
}
Local actorLocal = Jimple.v().newLocal("actor", actorType);
body.getLocals().add(actorLocal);
for (Iterator entities = model.deepEntityList().iterator(); entities
.hasNext();) {
Entity entity = (Entity) entities.next();
String fieldName = ModelTransformer.getFieldNameForEntity(
entity, model);
SootField field = modelClass.getFieldByName(fieldName);
String className = ModelTransformer.getInstanceClassName(
entity, options);
SootClass theClass = Scene.v().loadClassAndSupport(className);
SootMethod initializeMethod = SootUtilities
.searchForMethodByName(theClass, "initialize");
// Set the field.
units.insertBefore(Jimple.v().newAssignStmt(
actorLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
field.makeRef())), insertPoint);
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(actorLocal,
initializeMethod.makeRef())), insertPoint);
}
// units.insertBefore(Jimple.v().newReturnVoidStmt(),insertPoint);
}
// ModelTransformer does this.
// {
// // populate the prefire method
// SootMethod classMethod =
// modelClass.getMethodByName("prefire");
// JimpleBody body = (JimpleBody)classMethod.getActiveBody();
// Stmt insertPoint = body.getFirstNonIdentityStmt();
// Chain units = body.getUnits();
// Local thisLocal = body.getThisLocal();
// Local prefireReturnsLocal =
// Jimple.v().newLocal("preReturns", BooleanType.v());
// body.getLocals().add(prefireReturnsLocal);
// units.insertBefore(Jimple.v().newAssignStmt(prefireReturnsLocal,
// IntConstant.v(1)),
// insertPoint);
// units.insertBefore(Jimple.v().newReturnStmt(prefireReturnsLocal),
// insertPoint);
// LocalSplitter.v().transform(body, phaseName + ".lns");
// LocalNameStandardizer.v().transform(body, phaseName + ".lns");
// TypeResolver.resolve(body, Scene.v());
// }
{
// populate the fire method
SootMethod classMethod = modelClass.getMethodByName("fire");
JimpleBody body = (JimpleBody) classMethod.getActiveBody();
Stmt insertPoint = body.getFirstNonIdentityStmt();
Chain units = body.getUnits();
Local thisLocal = body.getThisLocal();
Local actorLocal = Jimple.v().newLocal("actor", actorType);
body.getLocals().add(actorLocal);
Local postfireReturnsLocal = Jimple.v().newLocal("postfireReturns",
BooleanType.v());
body.getLocals().add(postfireReturnsLocal);
Local indexLocal = Jimple.v().newLocal("index", IntType.v());
body.getLocals().add(indexLocal);
Local tokenLocal = Jimple.v().newLocal("token",
PtolemyUtilities.tokenType);
body.getLocals().add(tokenLocal);
// Update PortParameters.
for (Iterator parameters = model.attributeList(PortParameter.class)
.iterator(); parameters.hasNext();) {
PortParameter parameter = (PortParameter) parameters.next();
String fieldName = ModelTransformer.getFieldNameForAttribute(
parameter, model);
SootField field = modelClass.getFieldByName(fieldName);
RefType fieldType = (RefType) field.getType();
Local parameterLocal = Jimple.v().newLocal("parameter",
fieldType);
SootClass fieldClass = fieldType.getSootClass();
body.getLocals().add(parameterLocal);
// Get a reference to the port parameter.
units.insertBefore(Jimple.v().newAssignStmt(
parameterLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
field.makeRef())), insertPoint);
// Invoke the update() method.
units
.insertBefore(
Jimple
.v()
.newInvokeStmt(
Jimple
.v()
.newVirtualInvokeExpr(
parameterLocal,
fieldClass
.getMethod(
PtolemyUtilities.portParameterUpdateMethod
.getSubSignature())
.makeRef())),
insertPoint);
}
// FIXME: This is the quiescent point where parameters
// reconfigured as a result of port parameters should be
// evaluated.
// Transfer Inputs from input ports.
for (Iterator ports = model.inputPortList().iterator(); ports
.hasNext();) {
IOPort port = (IOPort) ports.next();
if (port instanceof ParameterPort) {
continue;
}
int rate;
rate = DFUtilities.getTokenConsumptionRate(port);
String fieldName = ModelTransformer.getFieldNameForPort(port,
model);
SootField field = modelClass.getFieldByName(fieldName);
// Get a reference to the port.
Local portLocal = Jimple.v().newLocal("port",
PtolemyUtilities.ioportType);
body.getLocals().add(portLocal);
Local tempPortLocal = Jimple.v().newLocal("tempPort",
PtolemyUtilities.ioportType);
body.getLocals().add(tempPortLocal);
units.insertBefore(Jimple.v().newAssignStmt(
tempPortLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
field.makeRef())), insertPoint);
units.insertBefore(Jimple.v().newAssignStmt(
portLocal,
Jimple.v().newCastExpr(tempPortLocal,
PtolemyUtilities.ioportType)), insertPoint);
for (int i = 0; i < port.getWidth(); i++) {
// The list of initializer instructions.
List initializerList = new LinkedList();
initializerList.add(Jimple.v().newAssignStmt(indexLocal,
IntConstant.v(0)));
// The list of body instructions.
List bodyList = new LinkedList();
// Read
bodyList.add(Jimple.v().newAssignStmt(
tokenLocal,
Jimple.v().newVirtualInvokeExpr(portLocal,
PtolemyUtilities.getMethod.makeRef(),
IntConstant.v(i))));
// Write
bodyList.add(Jimple.v().newInvokeStmt(
Jimple.v()
.newVirtualInvokeExpr(
portLocal,
PtolemyUtilities.sendInsideMethod
.makeRef(),
IntConstant.v(i), tokenLocal)));
// Increment the index.
bodyList.add(Jimple.v()
.newAssignStmt(
indexLocal,
Jimple.v().newAddExpr(indexLocal,
IntConstant.v(1))));
Expr conditionalExpr = Jimple.v().newLtExpr(indexLocal,
IntConstant.v(rate));
SootUtilities.createForLoopBefore(body, insertPoint,
initializerList, bodyList, conditionalExpr);
}
}
Local localPostfireReturnsLocal = Jimple.v().newLocal(
"localPostfireReturns", BooleanType.v());
body.getLocals().add(localPostfireReturnsLocal);
units.insertBefore(Jimple.v().newAssignStmt(
postfireReturnsLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
postfireReturnsField.makeRef())), insertPoint);
// Execute the schedule
Iterator schedule = null;
try {
schedule = director.getScheduler().getSchedule()
.firingIterator();
} catch (Exception ex) {
throw new KernelRuntimeException(ex, "Failed to get schedule");
}