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;
  }
Example #2
0
  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;
  }