public static void makeFieldsSymbolic(MJIEnv env, int objRef, int stringRef, int objvRef) { // makes all the fields of obj v symbolic and adds obj v to the symbolic heap to kick off lazy // initialization if (objvRef == -1) throw new RuntimeException("## Error: null object"); // introduce a heap choice generator for the element in the heap ThreadInfo ti = env.getVM().getCurrentThread(); SystemState ss = env.getVM().getSystemState(); ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { cg = new HeapChoiceGenerator(1); // new ss.setNextChoiceGenerator(cg); env.repeatInvocation(); return; // not used anyways } // else this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof HeapChoiceGenerator) : "expected HeapChoiceGenerator, got: " + cg; // see if there were more inputs added before ChoiceGenerator<?> prevHeapCG = cg.getPreviousChoiceGenerator(); while (!((prevHeapCG == null) || (prevHeapCG instanceof HeapChoiceGenerator))) { prevHeapCG = prevHeapCG.getPreviousChoiceGenerator(); } PathCondition pcHeap; SymbolicInputHeap symInputHeap; if (prevHeapCG == null) { pcHeap = new PathCondition(); symInputHeap = new SymbolicInputHeap(); } else { pcHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentPCheap(); symInputHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentSymInputHeap(); } // set all the fields to be symbolic ClassInfo ci = env.getClassInfo(objvRef); FieldInfo[] fields = ci.getDeclaredInstanceFields(); FieldInfo[] staticFields = ci.getDeclaredStaticFields(); String name = env.getStringObject(stringRef); String refChain = name + "[" + objvRef + "]"; // why is the type used here? should use the name of the field instead SymbolicInteger newSymRef = new SymbolicInteger(refChain); // ElementInfo eiRef = DynamicArea.getHeap().get(objvRef); ElementInfo eiRef = JVM.getVM().getHeap().get(objvRef); Helper.initializeInstanceFields(fields, eiRef, refChain); Helper.initializeStaticFields(staticFields, ci, ti); // create new HeapNode based on above info // update associated symbolic input heap ClassInfo typeClassInfo = eiRef.getClassInfo(); HeapNode n = new HeapNode(objvRef, typeClassInfo, newSymRef); symInputHeap._add(n); pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1)); ((HeapChoiceGenerator) cg).setCurrentPCheap(pcHeap); ((HeapChoiceGenerator) cg).setCurrentSymInputHeap(symInputHeap); // System.out.println(">>>>>>>>>>>> initial pcHeap: " + pcHeap.toString()); return; }
public static HelperResult addNewArrayHeapNode( ClassInfo typeClassInfo, ThreadInfo ti, Object attr, PathCondition pcHeap, SymbolicInputHeap symInputHeap, int numSymRefs, HeapNode[] prevSymRefs, boolean setShared, IntegerExpression indexAttr, int arrayRef) { int daIndex = ti.getHeap().newObject(typeClassInfo, ti).getObjectRef(); ti.getHeap().registerPinDown(daIndex); String refChain = ((ArrayExpression) attr) .getName(); // + "[" + daIndex + "]"; // do we really need to add daIndex here? SymbolicInteger newSymRef = new SymbolicInteger(refChain); ElementInfo eiRef = ti.getModifiableElementInfo(daIndex); // ti.getElementInfo(daIndex); // TODO to review! if (setShared) { eiRef.setShared(ti, true); // ?? } // daIndex.getObjectRef() -> number // neha: this change allows all the fields in the class hierarchy of the // object to be initialized as symbolic and not just its instance fields int numOfFields = eiRef.getNumberOfFields(); FieldInfo[] fields = new FieldInfo[numOfFields]; for (int fieldIndex = 0; fieldIndex < numOfFields; fieldIndex++) { fields[fieldIndex] = eiRef.getFieldInfo(fieldIndex); } Helper.initializeInstanceFields(fields, eiRef, refChain); // neha: this change allows all the static fields in the class hierarchy // of the object to be initialized as symbolic and not just its immediate // static fields ClassInfo superClass = typeClassInfo; while (superClass != null) { FieldInfo[] staticFields = superClass.getDeclaredStaticFields(); Helper.initializeStaticFields(staticFields, superClass, ti); superClass = superClass.getSuperClass(); } // Put symbolic array in PC if we create a new array. if (typeClassInfo.isArray()) { String typeClass = typeClassInfo.getType(); ArrayExpression arrayAttr = null; if (typeClass.charAt(1) != 'L') { arrayAttr = new ArrayExpression(eiRef.toString()); } else { arrayAttr = new ArrayExpression(eiRef.toString(), typeClass.substring(2, typeClass.length() - 1)); } ti.getVM() .getLastChoiceGeneratorOfType(PCChoiceGenerator.class) .getCurrentPC() .arrayExpressions .put(eiRef.toString(), arrayAttr); } // create new HeapNode based on above info // update associated symbolic input heap ArrayHeapNode n = new ArrayHeapNode(daIndex, typeClassInfo, newSymRef, indexAttr, arrayRef); symInputHeap._add(n); pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1)); pcHeap._addDet(Comparator.EQ, newSymRef, new IntegerConstant(numSymRefs)); for (int i = 0; i < numSymRefs; i++) pcHeap._addDet(Comparator.NE, n.getSymbolic(), prevSymRefs[i].getSymbolic()); HelperResult result = new HelperResult(n, daIndex); return result; }