&& stmt.getRightOp() instanceof CastExpr) {
if (debug) {
System.out.println("handling as local cast");
}
Value rightLocal = ((CastExpr) stmt.getRightOp())
.getOp();
doneSomething |= _handleImmediateAssignment(body,
stmt, localToFieldToLocal,
localToIsNotNullLocal, stmt.getLeftOp(),
rightLocal, debug);
} else if (stmt.getLeftOp() instanceof FieldRef
&& stmt.getRightOp() instanceof Local) {
if (debug) {
System.out
.println("handling as assignment to Field");
}
FieldRef oldFieldRef = (FieldRef) stmt.getLeftOp();
SootField field = oldFieldRef.getField();
Map fieldToReplacementField = (Map) entityFieldToTokenFieldToReplacementField
.get(field);
Map fieldToReplacementLocal = (Map) localToFieldToLocal
.get(stmt.getRightOp());
// System.out.println("fieldToReplacementField = " + fieldToReplacementField);
// System.out.println("fieldToReplacementLocal = " + fieldToReplacementLocal);
if ((fieldToReplacementLocal != null)
&& (fieldToReplacementField != null)) {
doneSomething = true;
// Replace references to fields with token types.
{
SootField replacementField = (SootField) entityFieldToIsNotNullField
.get(field);
//System.out.println("replacementField = " + replacementField);
FieldRef isNotNullFieldRef;
if (oldFieldRef instanceof InstanceFieldRef) {
isNotNullFieldRef = Jimple
.v()
.newInstanceFieldRef(
((InstanceFieldRef) oldFieldRef)
.getBase(),
replacementField
.makeRef());
} else {
isNotNullFieldRef = Jimple.v()
.newStaticFieldRef(
replacementField
.makeRef());
}
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
isNotNullFieldRef,
(Local) localToIsNotNullLocal
.get(stmt
.getRightOp())),
unit);
}
if (debug) {
System.out.println("local = "
+ stmt.getLeftOp());
}
for (Iterator tokenFields = fieldToReplacementField
.keySet().iterator(); tokenFields
.hasNext();) {
SootField tokenField = (SootField) tokenFields
.next();
if (debug) {
System.out.println("tokenField = "
+ tokenField);
}
SootField replacementField = (SootField) fieldToReplacementField
.get(tokenField);
Local replacementLocal = (Local) fieldToReplacementLocal
.get(tokenField);
if (debug) {
System.out
.println("replacementLocal = "
+ replacementLocal);
}
FieldRef fieldRef;
if (stmt.getLeftOp() instanceof InstanceFieldRef) {
Local base = (Local) ((InstanceFieldRef) stmt
.getLeftOp()).getBase();
fieldRef = Jimple.v()
.newInstanceFieldRef(
base,
replacementField
.makeRef());
} else {
fieldRef = Jimple.v()
.newStaticFieldRef(
replacementField
.makeRef());
}
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(fieldRef,
replacementLocal), unit);
}
stmt.getRightOpBox().setValue(NullConstant.v());
// body.getUnits().remove(unit);
}
} else if (stmt.getLeftOp() instanceof Local
&& stmt.getRightOp() instanceof FieldRef) {
if (debug) {
System.out
.println("handling as assignment from Field");
}
FieldRef oldFieldRef = (FieldRef) stmt.getRightOp();
Map fieldToReplacementLocal = (Map) localToFieldToLocal
.get(stmt.getLeftOp());
SootField field = oldFieldRef.getField();
Map fieldToReplacementField = (Map) entityFieldToTokenFieldToReplacementField
.get(field);
// There are some fields that represent
// singleton tokens. Deal with them
// specially.
// This is awkward, but it is simpler than
// doing a dataflow analysis of the static
// initializer of the token class to
// figure out what the value is.
boolean isSingleton = false;
if (field.getName().equals("TRUE")
|| field.getName().equals("FALSE")
|| field.getName().equals("ZERO")
|| field.getName().equals("ONE")) {
isSingleton = true;
}
if ((isSingleton)
&& (fieldToReplacementLocal != null)) {
doneSomething = true;
// Replace references to fields with
// token types. The special fields
// should never be null
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
(Local) localToIsNotNullLocal
.get(stmt.getLeftOp()),
IntConstant.v(1)), unit);
if (debug) {
System.out.println("local = "
+ stmt.getLeftOp());
}
for (Iterator localFields = fieldToReplacementLocal
.keySet().iterator(); localFields
.hasNext();) {
SootField localField = (SootField) localFields
.next();
if (debug) {
System.out.println("localField = "
+ localField);
}
// if (localField.getName().equals("_isNil")) {
// Local replacementLocal = (Local) fieldToReplacementLocal
// .get(localField);
// body
// .getUnits()
// .insertBefore(
// Jimple
// .v()
// .newAssignStmt(
// replacementLocal,
// IntConstant
// .v(1)),
// unit);
// } else
if (localField.getName().equals(
"_unitCategoryExponents")) {
Local replacementLocal = (Local) fieldToReplacementLocal
.get(localField);
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
replacementLocal,
NullConstant
.v()),
unit);
} else if (localField.getName().equals(
"_value")) {
Local replacementLocal = (Local) fieldToReplacementLocal
.get(localField);
if (field
.getSignature()
.equals(
"<ptolemy.data.BooleanToken: ptolemy.data.BooleanToken TRUE>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
IntConstant.v(1)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.BooleanToken: ptolemy.data.BooleanToken FALSE>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
IntConstant.v(0)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.UnsignedByteToken: ptolemy.data.UnsignedByteToken ONE>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
IntConstant.v(1)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.UnsignedByteToken: ptolemy.data.UnsignedByteToken ZERO>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
IntConstant.v(0)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.IntToken: ptolemy.data.IntToken ONE>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
IntConstant.v(1)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.IntToken: ptolemy.data.IntToken ZERO>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
IntConstant.v(0)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.LongToken: ptolemy.data.LongToken ONE>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
LongConstant.v(1)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.LongToken: ptolemy.data.LongToken ZERO>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
LongConstant.v(0)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.DoubleToken: ptolemy.data.DoubleToken ONE>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
DoubleConstant
.v(1.0)),
unit);
} else if (field
.getSignature()
.equals(
"<ptolemy.data.DoubleToken: ptolemy.data.DoubleToken ZERO>")) {
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
DoubleConstant
.v(0.0)),
unit);
}
} else {
throw new RuntimeException(
"Unknown Field in Token: "
+ localField
.getSignature());
}
}
stmt.getRightOpBox().setValue(NullConstant.v());
//body.getUnits().remove(unit);
} else if ((fieldToReplacementLocal != null)
&& (fieldToReplacementField != null)) {
doneSomething = true;
// Replace references to fields with token types.
// FIXME properly handle isNotNull field?
{
SootField replacementField = (SootField) entityFieldToIsNotNullField
.get(field);
// System.out.println("replacementField = " + replacementField);
FieldRef isNotNullFieldRef;
if (oldFieldRef instanceof InstanceFieldRef) {
isNotNullFieldRef = Jimple
.v()
.newInstanceFieldRef(
((InstanceFieldRef) oldFieldRef)
.getBase(),
replacementField
.makeRef());
} else {
isNotNullFieldRef = Jimple.v()
.newStaticFieldRef(
replacementField
.makeRef());
}
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
(Local) localToIsNotNullLocal
.get(stmt
.getLeftOp()),
isNotNullFieldRef),
unit);
}
if (debug) {
System.out.println("local = "
+ stmt.getLeftOp());
}
for (Iterator tokenFields = fieldToReplacementField
.keySet().iterator(); tokenFields
.hasNext();) {
SootField tokenField = (SootField) tokenFields
.next();
if (debug) {
System.out.println("tokenField = "
+ tokenField);
}
SootField replacementField = (SootField) fieldToReplacementField
.get(tokenField);
Local replacementLocal = (Local) fieldToReplacementLocal
.get(tokenField);
FieldRef fieldRef;
if (stmt.getRightOp() instanceof InstanceFieldRef) {
Local base = (Local) ((InstanceFieldRef) stmt
.getRightOp()).getBase();
fieldRef = Jimple.v()
.newInstanceFieldRef(
base,
replacementField
.makeRef());
} else {
fieldRef = Jimple.v()
.newStaticFieldRef(
replacementField
.makeRef());
}
if (debug) {
System.out
.println("replacementLocal = "
+ replacementLocal);
}
body.getUnits()
.insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
fieldRef), unit);
}
stmt.getRightOpBox().setValue(NullConstant.v());
// body.getUnits().remove(unit);
}
} else if (stmt.getLeftOp() instanceof ArrayRef
&& stmt.getRightOp() instanceof Local) {
if (debug) {
System.out
.println("handling as assignment to Array");
}
ArrayRef arrayRef = (ArrayRef) stmt.getLeftOp();
Local baseLocal = (Local) arrayRef.getBase();
Map fieldToReplacementArrayLocal = (Map) localToFieldToLocal
.get(baseLocal);
Map fieldToReplacementLocal = (Map) localToFieldToLocal
.get(stmt.getRightOp());
if (debug) {
System.out
.println("fieldToReplacementArrayLocal = "
+ fieldToReplacementArrayLocal);
}
if (debug) {
System.out.println("fieldToReplacementLocal = "
+ fieldToReplacementLocal);
}
if ((fieldToReplacementLocal != null)
&& (fieldToReplacementArrayLocal != null)) {
doneSomething = true;
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
Jimple
.v()
.newArrayRef(
(Local) localToIsNotNullLocal
.get(baseLocal),
arrayRef
.getIndex()),
(Local) localToIsNotNullLocal
.get(stmt
.getRightOp())),
unit);
if (debug) {
System.out.println("local = "
+ stmt.getLeftOp());
}
for (Iterator tokenFields = fieldToReplacementLocal
.keySet().iterator(); tokenFields
.hasNext();) {
SootField tokenField = (SootField) tokenFields
.next();
if (debug) {
System.out.println("tokenField = "
+ tokenField);
}
Local replacementArrayLocal = (Local) fieldToReplacementArrayLocal
.get(tokenField);
Local replacementLocal = (Local) fieldToReplacementLocal
.get(tokenField);
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
Jimple
.v()
.newArrayRef(
replacementArrayLocal,
arrayRef
.getIndex()),
replacementLocal),
unit);
}
// Have to remove here, because otherwise we'll try to
// index into a null array.
//stmt.getRightOpBox().setValue(NullConstant.v());
body.getUnits().remove(unit);
}
} else if (stmt.getLeftOp() instanceof Local
&& stmt.getRightOp() instanceof ArrayRef) {
if (debug) {
System.out
.println("handling as assignment from Array");
}
ArrayRef arrayRef = (ArrayRef) stmt.getRightOp();
Map fieldToReplacementLocal = (Map) localToFieldToLocal
.get(stmt.getLeftOp());
Local baseLocal = (Local) arrayRef.getBase();
Map fieldToReplacementArrayLocal = (Map) localToFieldToLocal
.get(baseLocal);
if ((fieldToReplacementLocal != null)
&& (fieldToReplacementArrayLocal != null)) {
doneSomething = true;
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
(Local) localToIsNotNullLocal
.get(stmt
.getLeftOp()),
Jimple
.v()
.newArrayRef(
(Local) localToIsNotNullLocal
.get(baseLocal),
arrayRef
.getIndex())),
unit);
if (debug) {
System.out.println("local = "
+ stmt.getLeftOp());
}
for (Iterator tokenFields = fieldToReplacementLocal
.keySet().iterator(); tokenFields
.hasNext();) {
SootField tokenField = (SootField) tokenFields
.next();
if (debug) {
System.out.println("tokenField = "
+ tokenField);
}
Local replacementArrayLocal = (Local) fieldToReplacementArrayLocal
.get(tokenField);
Local replacementLocal = (Local) fieldToReplacementLocal
.get(tokenField);
if (debug) {
System.out
.println("replacementLocal = "
+ replacementLocal);
}
if (debug) {
System.out
.println("replacementArrayLocal = "
+ replacementArrayLocal);
}
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
replacementLocal,
Jimple
.v()
.newArrayRef(
replacementArrayLocal,
arrayRef
.getIndex())),
unit);
}
stmt.getRightOpBox().setValue(NullConstant.v());
//body.getUnits().remove(unit);
}
} else if (stmt.getLeftOp() instanceof Local
&& stmt.getRightOp() instanceof NewArrayExpr) {
if (debug) {
System.out
.println("handling as new array object");
}
NewArrayExpr newExpr = (NewArrayExpr) stmt
.getRightOp();
// We have an assignment to a local from a new array.
Map map = (Map) localToFieldToLocal.get(stmt
.getLeftOp());
if (map != null) {
doneSomething = true;
Type isNotNullType = SootUtilities
.createIsomorphicType(newExpr
.getBaseType(), BooleanType.v());
Local isNotNullLocal = (Local) localToIsNotNullLocal
.get(stmt.getLeftOp());
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
isNotNullLocal,
Jimple.v().newNewArrayExpr(
isNotNullType,
newExpr.getSize())),
unit);
for (Iterator tokenFields = map.keySet()
.iterator(); tokenFields.hasNext();) {
SootField tokenField = (SootField) tokenFields
.next();
if (debug) {
System.out.println("tokenField = "
+ tokenField);
}
Local replacementLocal = (Local) map
.get(tokenField);
Type replacementType = SootUtilities
.createIsomorphicType(newExpr
.getBaseType(), tokenField
.getType());
// Initialize fields?
body
.getUnits()
.insertBefore(
Jimple
.v()
.newAssignStmt(
replacementLocal,
Jimple
.v()
.newNewArrayExpr(
replacementType,
newExpr
.getSize())),
unit);
}
stmt.getRightOpBox().setValue(NullConstant.v());
//body.getUnits().remove(unit);
}
} else if (stmt.getLeftOp() instanceof Local
&& stmt.getRightOp() instanceof NewExpr) {
if (debug) {
System.out.println("handling as new object");
}
/* NewExpr newExpr = (NewExpr)*/stmt.getRightOp();
// We have an assignment from one local token to another.
Map map = (Map) localToFieldToLocal.get(stmt
.getLeftOp());
if (map != null) {
doneSomething = true;
Local isNotNullLocal = (Local) localToIsNotNullLocal
.get(stmt.getLeftOp());
if (debug) {
System.out.println("Stmt = " + stmt);
}
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
isNotNullLocal,
IntConstant.v(1)), unit);
for (Iterator tokenFields = map.keySet()
.iterator(); tokenFields.hasNext();) {
SootField tokenField = (SootField) tokenFields
.next();
Local replacementLocal = (Local) map
.get(tokenField);
// Initialize fields?
if (debug) {
System.out.println("tokenField = "
+ tokenField);
}
// FIXME: ??
Value replacementValue = _getNullValueForType(replacementLocal
.getType());
body.getUnits().insertBefore(
Jimple.v().newAssignStmt(
replacementLocal,
replacementValue), unit);
}
stmt.getRightOpBox().setValue(NullConstant.v());
// body.getUnits().remove(unit);
}
}
// else if (stmt.getLeftOp() instanceof Local &&
// stmt.getRightOp() instanceof InvokeExpr) {
// System.out.println("handling as method call.");
// // We have an assignment from one local token to another.
// Map map = (Map)localToFieldToLocal.get(stmt.getLeftOp());
// if (map != null) {
// Local isNotNullLocal = (Local)
// localToIsNotNullLocal.get(stmt.getLeftOp());
// body.getUnits().insertAfter(
// Jimple.v().newAssignStmt(
// isNotNullLocal,
// IntConstant.v(0)),
// unit);
// for (Iterator tokenFields = map.keySet().iterator();
// tokenFields.hasNext();) {
// SootField tokenField = (SootField)tokenFields.next();
// Local replacementLocal = (Local)
// map.get(tokenField);
// // Initialize fields?
// body.getUnits().insertAfter(
// Jimple.v().newAssignStmt(
// replacementLocal,
// ),
// unit);
// }
// }
// }
}
}
// FIXME! This does not handle null values in fields well...
for (Iterator boxes = unit.getUseAndDefBoxes().iterator(); boxes
.hasNext();) {
ValueBox box = (ValueBox) boxes.next();
Value value = box.getValue();
if (value instanceof BinopExpr) {
BinopExpr expr = (BinopExpr) value;
boolean op1IsToken = PtolemyUtilities.isTokenType(expr
.getOp1().getType());
boolean op2IsToken = PtolemyUtilities.isTokenType(expr
.getOp2().getType());
if (op1IsToken && op2IsToken) {
// throw new RuntimeException(
// "Unable to handle expression"
// + " of two token types: " + unit);
} else if (op1IsToken
&& expr.getOp2().getType().equals(NullType.v())) {
doneSomething = true;
Local isNotNullLocal = (Local) localToIsNotNullLocal
.get(expr.getOp1());
if (isNotNullLocal != null) {
if (debug) {
System.out
.println("replacing binary expression "
+ expr);
}
Value nullValue;
if (isNotNullLocal.getType().equals(
BooleanType.v())) {
// If the isNotNullLocal is for a regular Object.
nullValue = IntConstant.v(0);
} else {
// If the isNotNullLocal is for an Array Object.
nullValue = NullConstant.v();
}
if (expr instanceof EqExpr) {
box.setValue(Jimple.v().newEqExpr(
isNotNullLocal, nullValue));
} else if (expr instanceof NeExpr) {
box.setValue(Jimple.v().newNeExpr(
isNotNullLocal, nullValue));
}
}
} else if (op2IsToken
&& expr.getOp1().getType().equals(NullType.v())) {
doneSomething = true;
Local isNotNullLocal = (Local) localToIsNotNullLocal
.get(expr.getOp2());
if (isNotNullLocal != null) {
Value nullValue;
if (isNotNullLocal.getType().equals(
BooleanType.v())) {
// If the isNotNullLocal is for a regular Object.
nullValue = IntConstant.v(0);