00001 package gov.nasa.arc.ase.jpf.jvm; 00002 00003 import gov.nasa.arc.ase.jpf.Engine; 00004 import gov.nasa.arc.ase.jpf.Path; 00005 import gov.nasa.arc.ase.jpf.ByteArray; 00006 import gov.nasa.arc.ase.util.Debug; 00007 import java.io.Serializable; 00008 00009 public class JVMPath implements Path, Serializable { 00010 private JVMPathEntry[] moves; 00011 private int ups; 00012 00013 public JVMPath(byte[] data) { 00014 ByteArray a = new ByteArray(data); 00015 00016 int u = a.unpackInt(); 00017 int m = a.unpackInt(); 00018 00019 init(m, u); 00020 00021 for(int i = 0; i < m; i++) { 00022 int thread = a.unpackInt(); 00023 int random = a.unpackInt(); 00024 00025 set(i, new JVMPathEntry(0, null, thread, random)); 00026 } 00027 } 00028 JVMPath(int m) { 00029 init(m, 0); 00030 } 00031 JVMPath(int m, int u) { 00032 init(m, u); 00033 } 00034 public Path append(Path o) { 00035 if(o == null) return (Path)clone(); 00036 if(!(o instanceof JVMPath)) 00037 throw new IllegalArgumentException("o must be a JVMPath"); 00038 00039 JVMPath p = (JVMPath)o; 00040 JVMPathEntry[] m1 = moves; 00041 JVMPathEntry[] m2 = p.moves; 00042 int l1 = m1.length; 00043 int l2 = m2.length; 00044 int u1 = ups; 00045 int u2 = p.ups; 00046 00047 int l, u, d; 00048 00049 if(l1 > u2) { 00050 d = l1 - u2; 00051 u = u1; 00052 } else { 00053 d = 0; 00054 u = u1 + u2 - l1; 00055 } 00056 l = d + l2; 00057 00058 JVMPath n = new JVMPath(l, u); 00059 00060 if(d != 0) 00061 System.arraycopy(m1, 0, n.moves, 0, d); 00062 System.arraycopy(m2, 0, n.moves, d, l2); 00063 00064 return n; 00065 } 00066 public Object clone() { 00067 int l = moves.length; 00068 00069 JVMPath p = new JVMPath(l, ups); 00070 00071 for(int i = 0; i < l; i++) 00072 p.moves[i] = moves[i]; 00073 00074 return p; 00075 } 00076 public boolean equals(Object o) { 00077 if(o == null) return false; 00078 if(!(o instanceof JVMPath)) return false; 00079 00080 JVMPath p = (JVMPath)o; 00081 00082 if(p.ups != ups) 00083 return false; 00084 00085 if(p.moves.length != moves.length) 00086 return false; 00087 00088 for(int i = 0; i < moves.length; i++) 00089 if(!p.moves[i].equals(moves[i])) 00090 return false; 00091 00092 return true; 00093 } 00094 public JVMPathEntry get(int index) { 00095 return moves[index]; 00096 } 00097 public byte[] getData() { 00098 ByteArray a = new ByteArray(); 00099 00100 a.pack(ups); 00101 a.pack(moves.length); 00102 00103 for(int i = 0; i < moves.length; i++) { 00104 a.pack(moves[i].thread); 00105 a.pack(moves[i].random); 00106 } 00107 00108 return a.getData(); 00109 } 00110 private void init(int m, int u) { 00111 moves = new JVMPathEntry[m]; 00112 ups = u; 00113 } 00114 public Path relativeTo(Path o) { 00115 if(o == null) return (Path)clone(); 00116 if(!(o instanceof JVMPath)) 00117 throw new IllegalArgumentException("o must be a JVMPath"); 00118 00119 JVMPath p = (JVMPath)o; 00120 JVMPathEntry[] m1 = moves; 00121 JVMPathEntry[] m2 = p.moves; 00122 int l1 = m1.length; 00123 int l2 = m2.length; 00124 int l = Math.min(l1, l2); 00125 int common = 0; 00126 00127 for(int idx = 0; idx < l; idx++) 00128 if(m1[idx].equals(m2[idx])) 00129 common++; 00130 else 00131 break; 00132 00133 JVMPath n = new JVMPath(l1 - common, l2 - common); 00134 00135 for(int idx = common; idx < l1; idx++) 00136 n.moves[idx - common] = m1[idx]; 00137 00138 return n; 00139 } 00140 void set(int index, JVMPathEntry e) { 00141 moves[index] = e; 00142 } 00143 public int size() { 00144 return moves.length; 00145 } 00146 public String toString() { 00147 StringBuffer sb = new StringBuffer("( "); 00148 00149 sb.append(ups); 00150 sb.append(", ["); 00151 00152 int l = moves.length; 00153 for(int i = 0; i < l; i++) { 00154 if(i != 0) sb.append(", "); 00155 if(moves[i] == null) 00156 sb.append("<null>"); 00157 else { 00158 sb.append("t"); 00159 sb.append(moves[i].thread); 00160 sb.append("/r"); 00161 sb.append(moves[i].random); 00162 } 00163 } 00164 00165 sb.append("] )"); 00166 00167 return sb.toString(); 00168 } 00169 public int upCount() { 00170 return ups; 00171 } 00172 }