protected void push(FeatureExpr ctx, StackFrame frame, ElementInfo ei, int index) throws ArrayIndexOutOfBoundsExecutiveException { ei.checkArrayBounds(ctx, index); Conditional<Byte> value; Fields f = ei.getFields(); if (f instanceof ByteArrayFields) { value = ei.getByteElement(index); } else if (f instanceof BooleanArrayFields) { value = ei.getBooleanElement(index) .mapr( new Function<Boolean, Conditional<Byte>>() { @Override public Conditional<Byte> apply(Boolean v) { return One.valueOf((byte) (v ? 1 : 0)); } }) .simplify(); } else { value = nullValue; } frame.push(ctx, value); }
/* * (non-Javadoc) * @see gov.nasa.jpf.jdart.objects.SymbolicObjectHandler#annotateObject(gov.nasa.jpf.vm.ElementInfo, java.lang.String, gov.nasa.jpf.jdart.objects.SymbolicObjectsContext) */ @Override public void annotateObject(ElementInfo ei, String name, SymbolicObjectsContext ctx) { int size = ei.getIntField(sizeField); int edRef = ei.getReferenceField(edField); Heap heap = ctx.getHeap(); ElementInfo data = heap.get(edRef); if (data == null) return; for (int i = 0; i < size; i++) { int elemRef = data.getReferenceElement(i); ElementInfo elem = heap.get(elemRef); if (elem == null) continue; ctx.processObject(elem, name + "[" + i + "]"); } }
@Override public void exceptionThrown(VM vm, ThreadInfo ti, ElementInfo ei) { if (traceActive) { String xCls = ei.getClassInfo().getName(); trace.add("X " + xCls); System.out.println("X " + xCls); } }
public static Expression initializeInstanceField( FieldInfo field, ElementInfo eiRef, String refChain, String suffix) { Expression sym_v = null; String name = ""; name = field.getName(); String fullName = refChain + "." + name + suffix; if (field instanceof IntegerFieldInfo || field instanceof LongFieldInfo) { sym_v = new SymbolicInteger(fullName); } else if (field instanceof FloatFieldInfo || field instanceof DoubleFieldInfo) { sym_v = new SymbolicReal(fullName); } else if (field instanceof ReferenceFieldInfo) { if (field.getType().equals("java.lang.String")) sym_v = new StringSymbolic(fullName); else sym_v = new SymbolicInteger(fullName); } else if (field instanceof BooleanFieldInfo) { // treat boolean as an integer with range [0,1] sym_v = new SymbolicInteger(fullName, 0, 1); } eiRef.setFieldAttr(field, sym_v); return sym_v; }
protected void setField(ElementInfo ei, int index) throws ArrayIndexOutOfBoundsExecutiveException { ei.checkArrayBounds(index); ei.setDoubleElement(index, value); }
@Override public Instruction execute(ThreadInfo ti) { // We may need to add the case where we have a smybolic index and a concrete array IntegerExpression indexAttr = null; ArrayExpression arrayAttr = null; StackFrame frame = ti.getModifiableTopFrame(); int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore if (arrayRef == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } // Retrieve the array expression if it was previously in the pathcondition, and store it as an // array attr PCChoiceGenerator temp_cg = (PCChoiceGenerator) ti.getVM().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); if (temp_cg != null) { if (temp_cg .getCurrentPC() .arrayExpressions .containsKey(ti.getElementInfo(ti.getModifiableTopFrame().peek(2)).toString())) { ti.getModifiableTopFrame() .setOperandAttr( 2, temp_cg .getCurrentPC() .arrayExpressions .get(ti.getElementInfo(ti.getModifiableTopFrame().peek(2)).toString())); } } // If only the value is symbolic, we use the concrete instruction if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { // In this case, the array isn't symbolic if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { return super.execute(ti); } } ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(3); ((PCChoiceGenerator) cg).setOffset(this.position); ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); ti.getVM().setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = ti.getVM().getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; } PathCondition pc; ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); if (prev_cg == null) pc = new PathCondition(); else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { int index = ti.getTopFrame().peek(1); indexAttr = new IntegerConstant(index); } else { indexAttr = (IntegerExpression) peekIndexAttr(ti); } assert (indexAttr != null) : "indexAttr shouldn't be null in FASTORE instruction"; if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { // In this case, the array isn't symbolic if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { return super.execute(ti); } else { // We create a symbolic array out of the concrete array ElementInfo arrayInfo = ti.getElementInfo(arrayRef); arrayAttr = ArrayExpression.create(arrayInfo.toString(), arrayInfo.arrayLength()); // We add the constraints about all the elements of the array for (int i = 0; i < arrayInfo.arrayLength(); i++) { float arrValue = arrayInfo.getFloatElement(i); pc._addDet( Comparator.EQ, new SelectExpression(arrayAttr, new IntegerConstant(i)), new RealConstant(arrValue)); } } } else { arrayAttr = (ArrayExpression) peekArrayAttr(ti); } assert (arrayAttr != null) : "arrayAttr shouldn't be null in FASTORE instruction"; if ((Integer) cg.getNextChoice() == 1) { // check bounds of the index pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); return ti.createAndThrowException( "java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); } else { ti.getVM().getSystemState().setIgnored(true); return getNext(ti); } } else if ((Integer) cg.getNextChoice() == 2) { pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); return ti.createAndThrowException( "java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); } else { ti.getVM().getSystemState().setIgnored(true); return getNext(ti); } } else { pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); RealExpression sym_value = null; if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof RealExpression)) { float value = frame.popFloat(); sym_value = new RealConstant(value); } else { // The value is symbolic. sym_value = (RealExpression) frame.getOperandAttr(0); frame.popFloat(); } // We create a new arrayAttr, and inherits information from the previous attribute ArrayExpression newArrayAttr = new ArrayExpression(arrayAttr); frame.pop(2); // We pop the array and the index RealStoreExpression se = new RealStoreExpression(arrayAttr, indexAttr, sym_value); pc._addDet(Comparator.EQ, se, newArrayAttr); pc.arrayExpressions.put(newArrayAttr.getRootName(), newArrayAttr); return getNext(ti); } else { ti.getVM().getSystemState().setIgnored(true); return getNext(ti); } } }
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; }