package nhandler.conversion.jvm2jpf; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import cmu.conditional.Conditional; import cmu.conditional.One; import de.fosd.typechef.featureexpr.FeatureExpr; import gov.nasa.jpf.vm.ClassInfo; import gov.nasa.jpf.vm.DynamicElementInfo; import gov.nasa.jpf.vm.FieldInfo; import gov.nasa.jpf.vm.MJIEnv; import gov.nasa.jpf.vm.StaticElementInfo; import nhandler.conversion.ConversionException; import nhandler.conversion.ConverterBase; /** * This class is used to convert objects and classes from JVM to JPF. This is only * applicable on types which are compatible between JPF and JVM, meaning that the same * classes are used to represent them in both environments. * * @author Nastaran Shafiei */ public class JVM2JPFGenericConverter extends JVM2JPFConverter { @Override protected void setStaticFields(Class<?> JVMCls, StaticElementInfo sei, MJIEnv env, FeatureExpr ctx) throws ConversionException { Field fld[] = JVMCls.getDeclaredFields(); for (int i = 0; i < fld.length; i++) { boolean isStatic = ((Modifier.toString(fld[i].getModifiers())).indexOf("static") != -1); boolean isFinal = ((Modifier.toString(fld[i].getModifiers())).indexOf("final") != -1); // Provide access to private and final fields fld[i].setAccessible(true); FieldInfo fi = sei.getFieldInfo(fld[i].getName()); // Provide access to private and final fields if (fi != null) { if (isStatic && !isFinal) { // If the current field is of reference type if (fi.isReference()) { try { // retrieving the value of the field in JVM final Object JVMfieldValue = fld[i].get(JVMCls); Conditional<Integer> conditionalJPFfieldValue = sei.getReferenceField(fi).simplify(ctx); conditionalJPFfieldValue = conditionalJPFfieldValue.mapf(ctx, (FeatureExpr ctx1, Integer JPFfieldValue) -> { try { if (JVMfieldValue == null) { JPFfieldValue = MJIEnv.NULL; } else if (JPFfieldValue == MJIEnv.NULL || ConverterBase.objMapJPF2JVM.get(JPFfieldValue) != JVMfieldValue) { JPFfieldValue = obtainJPFObj(JVMfieldValue, env, ctx1); } else if (ConverterBase.objMapJPF2JVM.get(JPFfieldValue) == JVMfieldValue) { updateJPFObj(JVMfieldValue, JPFfieldValue, env, ctx1); } else { throw new ConversionException("Unconsidered case observed! - JVM2JPF.getJPFCls()"); } } catch (ConversionException e) { throw new RuntimeException(e); } return One.MJIEnvNULL; }); sei.setReferenceField(ctx, fi, conditionalJPFfieldValue); } catch (IllegalAccessException e) { e.printStackTrace(); } } else { // If the current field is of primitive type try { Utilities.setJPFPrimitiveField(ctx, sei, fi.getStorageOffset(), fld[i], JVMCls); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } @Override protected void setInstanceFields(Object JVMObj, DynamicElementInfo dei, MJIEnv env, FeatureExpr ctx) throws ConversionException { Class<?> JVMCl = JVMObj.getClass(); ClassInfo JPFCl = this.getJPFCls(JVMObj.getClass(), env, ctx); while (JVMCl!=null){ Field fld[] = JVMCl.getDeclaredFields(); for (int i = 0; i < fld.length; i++){ // Check if the field is declared as non-static boolean isNonStaticField = ((Modifier.toString(fld[i].getModifiers())).indexOf("static") == -1); FieldInfo fi = JPFCl.getInstanceField(fld[i].getName()); fld[i].setAccessible(true); if (fi != null && isNonStaticField){ // If the current field is of reference type if (fi.isReference()){ Conditional<Integer> JPFfldValue = One.MJIEnvNULL; Object JVMfldValue = null; try{ // retrieving the value of the field in JVM JVMfldValue = fld[i].get(JVMObj); } catch (IllegalAccessException e2){ e2.printStackTrace(); } JPFfldValue = dei.getReferenceField(fi); if (JPFfldValue != null) { JPFfldValue = JPFfldValue.simplify(ctx); } if (JVMfldValue == null){ JPFfldValue = One.MJIEnvNULL; } else if (JPFfldValue == One.MJIEnvNULL || ConverterBase.objMapJPF2JVM.get(JPFfldValue) != JVMfldValue){ JPFfldValue = new One<>(obtainJPFObj(JVMfldValue, env, ctx)); } else if (ConverterBase.objMapJPF2JVM.get(JPFfldValue) == JVMfldValue){ updateJPFObj(JVMfldValue, JPFfldValue.getValue(), env, ctx); } else{ throw new ConversionException("Unconsidered case observed! - JVM2JPF.updateObj()"); } dei.setReferenceField(ctx, fi, JPFfldValue); } // If the current field is of primitive type else{ try{ Utilities.setJPFPrimitiveField(ctx, dei, fi.getStorageOffset(), fld[i], JVMObj); } catch (IllegalAccessException e){ e.printStackTrace(); } } } } JVMCl = JVMCl.getSuperclass(); JPFCl = JPFCl.getSuperClass(); } } }