// // Copyright (C) 2012 United States Government as represented by the // Administrator of the National Aeronautics and Space Administration // (NASA). All Rights Reserved. // // This software is distributed under the NASA Open Source Agreement // (NOSA), version 1.3. The NOSA has been approved by the Open Source // Initiative. See the file NOSA-1.3-JPF at the top of the distribution // directory tree for the complete NOSA document. // // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.vm; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import gov.nasa.jpf.util.FinalBitSet; import gov.nasa.jpf.util.PrintUtils; /** * stream to write program state info in a readable and diff-able format. * This is mostly intended for debugging, but could also at some point be * used to restore such states. * * Currently supports heap objects, classes (static fields), threads and stack frames */ public class JPFOutputStream extends OutputStream { PrintStream ps; boolean useSid = false; int maxElements = -1; public JPFOutputStream (OutputStream os){ ps = new PrintStream(os); } public JPFOutputStream (PrintStream ps){ this.ps = ps; } public JPFOutputStream (){ this(System.out); } public void close(){ ps.flush(); if (ps != System.err && ps != System.out){ ps.close(); } } public void printCommentLine(String msg){ ps.print("// "); ps.println(msg); } public void print (ElementInfo ei, FieldInfo fi, boolean isFiltered){ ps.print(fi.getName()); ps.print(':'); if (isFiltered){ ps.print("X"); } else { switch (fi.getTypeCode()) { case Types.T_BOOLEAN: ps.print(ei.getBooleanField(fi)); break; case Types.T_BYTE: ps.print(ei.getByteField(fi)); break; case Types.T_CHAR: PrintUtils.printCharLiteral(ps, ei.getCharField(fi).getValue()); break; case Types.T_SHORT: ps.print(ei.getShortField(fi)); break; case Types.T_INT: ps.print(ei.getIntField(fi)); break; case Types.T_LONG: ps.print(ei.getLongField(fi)); break; case Types.T_FLOAT: ps.print(ei.getFloatField(fi)); break; case Types.T_DOUBLE: ps.print(ei.getDoubleField(fi)); break; case Types.T_REFERENCE: case Types.T_ARRAY: PrintUtils.printReference(ps, ei.getReferenceField(fi).getValue()); break; } } } protected void printFields (ElementInfo ei, FieldInfo[] fields, FinalBitSet filterMask){ if (fields != null){ for (int i = 0; i < fields.length; i++) { if (i > 0) { ps.print(','); } print(ei, fields[i], (filterMask != null && filterMask.get(i))); } } } public void print (ElementInfo ei, FinalBitSet filterMask){ boolean isObject = ei.isObject(); ClassInfo ci = ei.getClassInfo(); int ref = (useSid) ? ei.getSid() : ei.getObjectRef(); ps.printf("@%x ", ref); if (isObject){ ps.print("object "); if (ei.isArray()){ ps.print( Types.getTypeName(ci.getName())); } else { ps.print(ci.getName()); } } else { ps.print("class "); ps.print(ci.getName()); } ps.print(':'); if (isObject){ if (ei.isArray()){ ps.print('['); ei.getArrayFields().printElements(ps, maxElements); ps.print(']'); } else { ps.print('{'); printFields(ei, ci.getInstanceFields(), filterMask); ps.print('}'); } } else { ps.print('{'); printFields( ei, ci.getDeclaredStaticFields(), filterMask); ps.print('}'); } } public void print (ThreadInfo ti){ PrintUtils.printReference(ps, ti.getThreadObjectRef()); ps.print(' '); ps.print(ti.getStateDescription()); } public void print (StackFrame frame){ MethodInfo mi = frame.getMethodInfo(); ps.print('@'); ps.print(frame.getDepth()); ps.print(" frame "); ps.print( mi.getFullName()); ps.print( ":{" ); if (!mi.isStatic()){ ps.print("this:"); PrintUtils.printReference(ps, frame.getThis().getValue()); ps.print(','); } ps.print("pc:"); ps.print(frame.getPC().getValue().getInstructionIndex()); ps.print(",slots:["); frame.printSlots(ps); ps.print(']'); ps.print('}'); } public void println(){ ps.println(); } @Override public void write(int b) throws IOException { ps.write(b); } }