.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);
}