package nhandler.conversion.jpf2jvm;
import java.lang.reflect.Field;
import cmu.conditional.One;
import de.fosd.typechef.featureexpr.FeatureExpr;
import gov.nasa.jpf.vm.ArrayFields;
import gov.nasa.jpf.vm.ElementInfo;
import gov.nasa.jpf.vm.FieldInfo;
import nhandler.conversion.ConversionException;
/**
* Helper methods needed for the conversion from JPF to JVM
*
* @author Nastaran Shafiei
*/
public class Utilities {
/**
* Sets a primitive field of a JVM object to a value of the corresponding
* field of the given JPF object.
*
* @param fld
* a field of a JVM object which is of primitive type.
* @param obj
* The JVM object that includes the field fld.
* @param ei
* a JPF object which is corresponding to the given JVM object, obj.
* @throws IllegalAccessException
* when method trying to access a private field of an JVM object
* whose "isAccessible" is not true. But that will not happen,
* because in "getJVMObj" before invoking this method we always
* invoke "fld.setAccessible(true)".
*
* @throws ConversionException
* if the given field is not of primitive type
*/
public static void setJVMPrimitiveField (Field fld, Object obj, ElementInfo ei, FieldInfo fi, FeatureExpr ctx) throws IllegalAccessException, ConversionException {
if (fi.isBooleanField()) {
fld.setBoolean(obj, ei.getBooleanField(fi).getValue());
} else if (fi.isByteField()) {
fld.setByte(obj, ei.getByteField(fi).simplify(ctx).getValue());
} else if (fi.isShortField()) {
fld.setShort(obj, ei.getShortField(fi).getValue());
} else if (fi.isIntField()) {
fld.setInt(obj, ei.getIntField(fi).getValue());
} else if (fi.isLongField()) {
fld.setLong(obj, ei.getLongField(fi).getValue());
} else if (fi.isCharField()) {
fld.setChar(obj, ei.getCharField(fi).getValue());
} else if (fi.isFloatField()) {
fld.setFloat(obj, ei.getFloatField(fi).getValue());
} else if (fi.isDoubleField()) {
fld.setDouble(obj, ei.getDoubleField(fi).getValue());
} else {
throw new ConversionException("Unknown premitive type " + fi.getType());
}
}
/**
* Creates an array of primitive type which is corresponding to the given JPF
* array.
*
* @param ei
* An ElementInfo which represents a JPF array of primitive type
* @param ctx TODO
*
* @return a JVM array of primitive type which is created corresponding to the
* given JPF array represented by ei
*
* @throws ConversionException
* if the given array is not of primitive type
*/
public static Object createJVMPrimitiveArr (ElementInfo ei, FeatureExpr ctx) throws ConversionException {
String type = ei.getType();
Object JVMObj = null;
// byte[]
if (type.equals("[B")) {
// JVMObj = ((ArrayFields) ei.getFields()).asByteArrayConcrete();
Byte[] ByteArray = ((ArrayFields) ei.getFields()).asByteArrayConcrete(ctx);
byte[] byteArray = new byte[ByteArray.length];
for (int i = 0; i < ByteArray.length; i++) {
byteArray[i] = ByteArray[i].byteValue();
}
JVMObj = byteArray;
}
// char[]
else if (type.equals("[C")) {
JVMObj = ((ArrayFields) ei.getFields()).asCharArray();
if (JVMObj instanceof One) {
JVMObj = ((One<?>) JVMObj).getValue();
}
}
// short[]
else if (type.equals("[S")) {
JVMObj = ((ArrayFields) ei.getFields()).asShortArray();
}
// int[]
else if (type.equals("[I")) {
// JVMObj = ((ArrayFields) ei.getFields()).asIntArray();
Integer[] IntegerArray = ((ArrayFields) ei.getFields()).asIntArrayConcrete();
int[] intArray = new int[IntegerArray.length];
for (int i = 0; i < IntegerArray.length; i++) {
intArray[i] = IntegerArray[i].intValue();
}
JVMObj = intArray;
}
// float[]
else if (type.equals("[F")) {
JVMObj = ((ArrayFields) ei.getFields()).asFloatArray();
}
// long[]
else if (type.equals("[J")) {
JVMObj = ((ArrayFields) ei.getFields()).asLongArray();
}
// double[]
else if (type.equals("[D")) {
JVMObj = ((ArrayFields) ei.getFields()).asDoubleArray();
}
// boolean[]
else if (type.equals("[Z")) {
JVMObj = ((ArrayFields) ei.getFields()).asBooleanArray();
} else {
throw new ConversionException("Unknown array type " + type);
}
return JVMObj;
}
public static boolean isPrimitiveClass (String name) {
return (name.equals("boolean") || name.equals("byte") || name.equals("int") || name.equals("short") || name.equals("long") || name.equals("char") || name.equals("float") || name.equals("double"));
}
/**
* Returns a class corresponding to the given primitive type
*
* @param name
* primitive type name
*
* @return class corresponding to the given primitive type
*/
public static Class<?> getPrimitiveClass (String name) {
if (name.equals("boolean")) {
return boolean.class;
} else if (name.equals("byte")) {
return byte.class;
} else if (name.equals("int")) {
return int.class;
} else if (name.equals("short")) {
return short.class;
} else if (name.equals("long")) {
return long.class;
} else if (name.equals("char")) {
return char.class;
} else if (name.equals("float")) {
return float.class;
} else if (name.equals("double")) {
return double.class;
}
return null;
}
public static boolean isArray(String cname) {
return cname.startsWith("[");
}
}