if (debug) {
System.out.println("updating types for " + method);
}
Body body = method.retrieveActiveBody();
for (Iterator units = body.getUnits().snapshotIterator(); units
.hasNext();) {
Unit unit = (Unit) units.next();
//System.out.println("unit = " + unit);
Iterator boxes = unit.getUseBoxes().iterator();
while (boxes.hasNext()) {
ValueBox box = (ValueBox) boxes.next();
/*Value value = */box.getValue();
// Replace Array creations with a more specific
// type, if possible.
if (box.getValue() instanceof NewArrayExpr) {
NewArrayExpr newArrayExpr = (NewArrayExpr) box
.getValue();
if (debug) {
System.out
.println("newArrayExpr = " + newArrayExpr);
}
Type baseType = newArrayExpr.getBaseType();
Type newType = typeAnalysis
.getSpecializedSootType(newArrayExpr);
if ((newType != null) && !newType.equals(baseType)) {
if (debug) {
System.out.println("replacing with " + newType);
}
box.setValue(Jimple.v().newNewArrayExpr(newType,
newArrayExpr.getSize()));
}
}
}
// Ignore anything that isn't an assignment.
if (!(unit instanceof AssignStmt)) {
continue;
}
AssignStmt assignStmt = (AssignStmt) unit;
// Ignore anything that isn't an assignment to a field.
if (assignStmt.getRightOp() instanceof FieldRef) {
FieldRef ref = (FieldRef) assignStmt.getRightOp();
SootFieldRef fieldRef = ref.getFieldRef();
SootField field = ref.getField();
Type type = field.getType();
if (!PtolemyUtilities.isTokenType(type)) {
continue;
}
// Things that aren't token types are ignored.
// Things that are already the same type are ignored.
Type newType = typeAnalysis.getSpecializedSootType(field);
if ((newType != null) && !newType.equals(type)) {
ref.setFieldRef(Scene.v().makeFieldRef(
fieldRef.declaringClass(), fieldRef.name(),
newType, fieldRef.isStatic()));
}
continue;
}
if (!(assignStmt.getLeftOp() instanceof FieldRef)) {
continue;
}
if (!PtolemyUtilities.isTokenType(assignStmt.getLeftOp()
.getType())) {
continue;
}
if (debug) {
System.out.println("checking assignment " + assignStmt);
}
// FIXME: We need to figure out a way to insert casts where appropriate.
// See RampFiringLimitSDF
// ptolemy.data.type.Type leftType, rightType;
// leftType = _getReplacementTokenType(
// assignStmt.getLeftOp(), typeAnalysis);
// rightType = _getReplacementTokenType(
// assignStmt.getRightOp(), typeAnalysis);
// if (leftType != null && rightType != null && !leftType.equals(rightType)) {
// if (debug) System.out.println("inserting conversion: leftType = " +
// leftType + ", rightType = " + rightType);
// // insert a call to convert(), and a cast.
// FieldRef ref = (FieldRef)assignStmt.getLeftOp();
// SootField field = ref.getField();
// Type newType =
// typeAnalysis.getSpecializedSootType(field);
// Local tempLocal =
// Jimple.v().newLocal("fieldUpdateLocal", newType);
// body.getLocals().add(tempLocal);
// Local tokenLocal =
// Jimple.v().newLocal("tokenLocal", PtolemyUtilities.tokenType);
// body.getLocals().add(tokenLocal);
// Local typeLocal =
// PtolemyUtilities.buildConstantTypeLocal(body, unit, leftType);
// body.getUnits().insertBefore(
// Jimple.v().newAssignStmt(tokenLocal,
// Jimple.v().newVirtualInvokeExpr(
// typeLocal,
// PtolemyUtilities.typeConvertMethod,
// assignStmt.getRightOp())),
// unit);
// body.getUnits().insertBefore(
// Jimple.v().newAssignStmt(tempLocal,
// Jimple.v().newCastExpr(
// tokenLocal,
// newType)),
// unit);
// assignStmt.setRightOp(tempLocal);
// } else {
FieldRef ref = (FieldRef) assignStmt.getLeftOp();
SootFieldRef fieldRef = ref.getFieldRef();
SootField field = ref.getField();
Type type = field.getType();
// Things that aren't token types are ignored.
// Things that are already the same type are ignored.
Type newType = typeAnalysis.getSpecializedSootType(field);
if ((newType != null) && !newType.equals(type)) {
if (debug) {
System.out.println("inserting cast");
}
Local tempLocal = Jimple.v().newLocal("fieldUpdateLocal",
newType);
body.getLocals().add(tempLocal);
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
tempLocal,
Jimple.v().newCastExpr(
assignStmt.getRightOp(), newType)),
unit);