.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");
}
while (schedule.hasNext()) {
Firing firing = (Firing) schedule.next();
Entity entity = (Entity) firing.getActor();
int firingCount = firing.getIterationCount();
String fieldName = ModelTransformer.getFieldNameForEntity(
entity, model);
SootField field = modelClass.getFieldByName(fieldName);
String className = ModelTransformer.getInstanceClassName(
entity, options);
SootClass theClass = Scene.v().loadClassAndSupport(className);
SootMethod actorPrefireMethod = SootUtilities
.searchForMethodByName(theClass, "prefire");
SootMethod actorFireMethod = SootUtilities
.searchForMethodByName(theClass, "fire");
SootMethod actorPostfireMethod = SootUtilities
.searchForMethodByName(theClass, "postfire");
// Set the field.
units.insertBefore(Jimple.v().newAssignStmt(
actorLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
field.makeRef())), insertPoint);
// The threshold at which it is better to generate loops,
// than to inline code. A threshold of 2 means that loops will
// always be used.
// FIXME: This should be a command line option.
int threshold = 2;
if (firingCount < threshold) {
for (int i = 0; i < firingCount; i++) {
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(actorLocal,
actorPrefireMethod.makeRef())),
insertPoint);
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(actorLocal,
actorFireMethod.makeRef())),
insertPoint);
units.insertBefore(Jimple.v().newAssignStmt(
localPostfireReturnsLocal,
Jimple.v().newVirtualInvokeExpr(actorLocal,
actorPostfireMethod.makeRef())),
insertPoint);
units.insertBefore(Jimple.v().newAssignStmt(
postfireReturnsLocal,
Jimple.v().newAndExpr(postfireReturnsLocal,
localPostfireReturnsLocal)),
insertPoint);
}
} else {
// 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();
bodyList.add(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(actorLocal,
actorPrefireMethod.makeRef())));
bodyList.add(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(actorLocal,
actorFireMethod.makeRef())));
bodyList.add(Jimple.v().newAssignStmt(
localPostfireReturnsLocal,
Jimple.v().newVirtualInvokeExpr(actorLocal,
actorPostfireMethod.makeRef())));
bodyList.add(Jimple.v().newAssignStmt(
postfireReturnsLocal,
Jimple.v().newAndExpr(postfireReturnsLocal,
localPostfireReturnsLocal)));
// Increment the index.
bodyList.add(Jimple.v()
.newAssignStmt(
indexLocal,
Jimple.v().newAddExpr(indexLocal,
IntConstant.v(1))));
Expr conditionalExpr = Jimple.v().newLtExpr(indexLocal,
IntConstant.v(firingCount));
SootUtilities.createForLoopBefore(body, insertPoint,
initializerList, bodyList, conditionalExpr);
}
}
// Transfer outputs from output ports
for (Iterator ports = model.outputPortList().iterator(); ports
.hasNext();) {
IOPort port = (IOPort) ports.next();
int rate;
rate = DFUtilities.getTokenProductionRate(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.getWidthInside(); 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.getInsideMethod.makeRef(),
IntConstant.v(i))));
// Write
bodyList.add(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(portLocal,
PtolemyUtilities.sendMethod.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);
}
}
// Return.
units.insertBefore(Jimple.v().newAssignStmt(
Jimple.v().newInstanceFieldRef(thisLocal,
postfireReturnsField.makeRef()),
postfireReturnsLocal), insertPoint);
// units.insertBefore(Jimple.v().newReturnVoidStmt(),
// insertPoint);
LocalSplitter.v().transform(body, phaseName + ".lns");
LocalNameStandardizer.v().transform(body, phaseName + ".lns");
TypeResolver.resolve(body, Scene.v());
}
{
// populate the postfire method
SootMethod classMethod = modelClass.getMethodByName("postfire");
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);
units.insertBefore(Jimple.v().newAssignStmt(
postfireReturnsLocal,
Jimple.v().newInstanceFieldRef(thisLocal,
postfireReturnsField.makeRef())), insertPoint);
// If we need to keep track of the number of iterations, then...
if (iterationLimit > 0) {
Local iterationLocal = null;
iterationLocal = Jimple.v().newLocal("iteration", IntType.v());
body.getLocals().add(iterationLocal);
// Get the current number of iterations
units.insertBefore(Jimple.v().newAssignStmt(
iterationLocal,
Jimple.v().newInstanceFieldRef(body.getThisLocal(),
iterationField.makeRef())), insertPoint);
// Increment the number of iterations.
units.insertBefore(Jimple.v()
.newAssignStmt(
iterationLocal,
Jimple.v().newAddExpr(iterationLocal,
IntConstant.v(1))), insertPoint);
// Save the current number of iterations
units.insertBefore(Jimple.v().newAssignStmt(
Jimple.v().newInstanceFieldRef(body.getThisLocal(),
iterationField.makeRef()), iterationLocal),
insertPoint);
Stmt endStmt = Jimple.v().newNopStmt();
// If the number of iterations is less than then
// limit, then don't force postfire return to be
// false.
units.insertBefore(Jimple.v().newIfStmt(
Jimple.v().newLtExpr(iterationLocal,
IntConstant.v(iterationLimit)), endStmt),
insertPoint);
units.insertBefore(Jimple.v().newAssignStmt(
postfireReturnsLocal, IntConstant.v(0)), // FALSE
insertPoint);
units.insertBefore(endStmt, insertPoint);
}
units.insertBefore(Jimple.v().newReturnStmt(postfireReturnsLocal),
insertPoint);
LocalSplitter.v().transform(body, phaseName + ".lns");
LocalNameStandardizer.v().transform(body, phaseName + ".lns");
TypeResolver.resolve(body, Scene.v());
}
{
// populate the wrapup method
SootMethod classMethod = modelClass.getMethodByName("wrapup");
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);
for (Iterator entities = model.deepEntityList().iterator(); entities
.hasNext();) {
Entity entity = (Entity) entities.next();