00001 package gov.nasa.arc.ase.jpf.jvm;
00002
00003 import de.fub.bytecode.*;
00004 import de.fub.bytecode.classfile.*;
00005 import de.fub.bytecode.generic.*;
00006 import gov.nasa.arc.ase.jpf.*;
00007 import gov.nasa.arc.ase.util.Debug;
00008 import gov.nasa.arc.ase.util.HashData;
00009 import java.io.*;
00010 import java.util.*;
00011
00012 import gov.nasa.arc.ase.util.BSet;
00013
00014
00015
00016
00017
00018 public class Fields {
00019
00020
00021
00022 private String type;
00023
00024
00025
00026
00027 private ClassInfo ci;
00028
00029
00030
00031
00032 private int[] values;
00033
00034
00035
00036
00037 private int nFields;
00038
00039
00040
00041
00042 private boolean isClass;
00043
00044
00045
00046
00047
00048
00049
00050 BSet vRefs;
00051
00052
00053
00054
00055
00056
00057 private Fields() {
00058 }
00059
00060
00061
00062 public Fields(String t,
00063 ClassInfo c,
00064 int size,
00065 int nf,
00066 boolean ic
00067
00068 , BSet v
00069
00070 ) {
00071 type = t;
00072 ci = c;
00073 values = new int[size];
00074 nFields = nf;
00075 isClass = ic;
00076
00077 vRefs = v;
00078
00079 initFields();
00080 }
00081
00082
00083
00084 public Object clone() {
00085 Fields f = new Fields();
00086
00087 f.type = type;
00088 f.ci = ci;
00089 f.values = new int[values.length];
00090 System.arraycopy(values, 0, f.values, 0, values.length);
00091 f.nFields = nFields;
00092 f.isClass = isClass;
00093
00094 f.vRefs = vRefs;
00095
00096
00097 return f;
00098 }
00099
00100
00101
00102 public int countFields() {
00103 return nFields;
00104 }
00105
00106
00107
00108 public boolean equals(Object o) {
00109 if(o == null) return false;
00110 if(!(o instanceof Fields)) return false;
00111
00112 Fields f = (Fields)o;
00113
00114 if(!type.equals(f.type)) return false;
00115 if(ci != f.ci) return false;
00116 if(nFields != f.nFields) return false;
00117 if(isClass != f.isClass) return false;
00118
00119 int[] v1 = values;
00120 int[] v2 = f.values;
00121 int l = v1.length;
00122
00123 if(l != v2.length) return false;
00124
00125 for(int i = 0; i < l; i++)
00126 if(v1[i] != v2[i]) return false;
00127
00128
00129
00130
00131
00132
00133 return true;
00134 }
00135 public int findex(String fname) {
00136 if(isClass)
00137 return ci.staticFieldIndex(fname);
00138 else
00139 return ci.dynamicFieldIndex(fname);
00140 }
00141
00142
00143
00144 public ClassInfo getClassInfo() {
00145 return ci;
00146 }
00147
00148
00149
00150 public int getField(int index) { return values[index]; }
00151
00152
00153
00154
00155
00156 public int getField(String fname) {
00157 return getField(findex(fname));
00158 }
00159
00160
00161
00162
00163
00164 public String getFieldName(int index) {
00165 if(isArray())
00166 return Integer.toString(index / Types.getTypeSize(Types.getArrayElementType(type)));
00167 else
00168 if(isClass)
00169 return ci.getStaticField(index).getName();
00170 else
00171 return ci.getDynamicField(index).getName();
00172 }
00173 public String getFieldType(int findex) {
00174 if(isArray())
00175 return type.substring(1);
00176 else
00177 if(isClass)
00178 return ci.getStaticField(findex).getType();
00179 else
00180 return ci.getDynamicField(findex).getType();
00181 }
00182 public String getFieldType(String fname) {
00183 return getFieldType(findex(fname));
00184 }
00185 public long getLongField(int index) {
00186 return Types.intsToLong(values[index+1], values[index]);
00187 }
00188 public long getLongField(String fname) {
00189 return getLongField(findex(fname));
00190 }
00191
00192
00193
00194 public String getType() {
00195 return type;
00196 }
00197
00198
00199
00200 public void hash(HashData hd) {
00201 for(int i = 0, s = values.length; i < s; i++)
00202 hd.add(values[i]);
00203 }
00204
00205
00206
00207 public int hashCode() {
00208 HashData hd = new HashData();
00209
00210 hash(hd);
00211
00212 return hd.getValue();
00213 }
00214 private void initFields() {
00215 for(int i = 0; i < values.length; ) {
00216 String t = getFieldType(i);
00217 switch(Types.getBaseType(t)) {
00218 case Types.T_CHAR:
00219 case Types.T_FLOAT:
00220 case Types.T_BYTE:
00221 case Types.T_INT:
00222 case Types.T_SHORT:
00223 case Types.T_BOOLEAN:
00224 values[i] = 0;
00225 break;
00226
00227 case Types.T_DOUBLE:
00228 case Types.T_LONG:
00229 values[i] = 0;
00230 values[i+1] = 0;
00231 break;
00232
00233 case Types.T_ARRAY:
00234 case Types.T_REFERENCE:
00235 values[i] = -1;
00236 break;
00237 }
00238 i += Types.getTypeSize(t);
00239 }
00240 }
00241
00242
00243
00244 public boolean isArray() {
00245 return Types.getBaseType(type) == Types.T_ARRAY;
00246 }
00247
00248
00249
00250 public boolean isClass() {
00251 return isClass;
00252 }
00253
00254
00255
00256 public boolean isRef(int index) {
00257 return vRefs.get(index);
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 public boolean isRef(String fname) {
00280 return isRef(findex(fname));
00281 }
00282
00283
00284
00285 public void log(int ref) {
00286 Debug.print(Debug.MESSAGE, " ");
00287 if(isClass())
00288 Debug.print(Debug.MESSAGE, "@");
00289 else
00290 Debug.print(Debug.MESSAGE, "#");
00291 Debug.println(Debug.MESSAGE, ref + " " + Types.getTypeName(type) + "("+type+")");
00292 for(int i = 0; i < values.length; ) {
00293 Debug.print(Debug.MESSAGE, " " + getFieldName(i) + ":");
00294
00295 String t = getFieldType(i);
00296 Debug.print(Debug.MESSAGE, "(" + Types.getTypeName(t) + ")");
00297 switch(Types.getBaseType(t)) {
00298 case Types.T_CHAR:
00299 Debug.println(Debug.MESSAGE, new Character((char)getField(i)).toString());
00300 break;
00301
00302 case Types.T_DOUBLE:
00303 Debug.println(Debug.MESSAGE, Double.toString(Types.longToDouble(getLongField(i))));
00304 break;
00305
00306 case Types.T_FLOAT:
00307 Debug.println(Debug.MESSAGE, Float.toString(Types.intToFloat(getField(i))));
00308 break;
00309
00310 case Types.T_BYTE:
00311 case Types.T_INT:
00312 case Types.T_SHORT:
00313 Debug.println(Debug.MESSAGE, Integer.toString(getField(i)));
00314 break;
00315
00316 case Types.T_LONG:
00317 Debug.println(Debug.MESSAGE, Long.toString(getLongField(i)));
00318 break;
00319
00320 case Types.T_BOOLEAN:
00321 Debug.println(Debug.MESSAGE, new Boolean(Types.intToBoolean(getField(i))).toString());
00322 break;
00323
00324 case Types.T_ARRAY:
00325 case Types.T_REFERENCE:
00326 Debug.println(Debug.MESSAGE, "#" + values[i]);
00327 break;
00328 }
00329 i += Types.getTypeSize(t);
00330 }
00331 }
00332
00333
00334
00335
00336
00337
00338 public void mark(DynamicArea da) {
00339 for(int i = 0, l = values.length; i < l; i++)
00340 if(vRefs.get(i))
00341 da.mark(values[i]);
00342 }
00343
00344
00345
00346 public void setField(int index, int value) {
00347
00348 if(vRefs.get(index)
00349 && values[index] != -1
00350 && values[index] != value)
00351 VirtualMachine.getSS().activateGC();
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 values[index] = value;
00363 }
00364
00365
00366
00367 public void setField(String fname, int value) {
00368 setField(findex(fname), value);
00369 }
00370 public void setLongField(int index, long value) {
00371 setField(index, Types.hiLong(value));
00372 setField(index+1, Types.loLong(value));
00373 }
00374 public void setLongField(String fname, long value) {
00375 setLongField(findex(fname), value);
00376 }
00377
00378
00379
00380 public int size() {
00381 return values.length;
00382 }
00383 public String toString() {
00384 StringBuffer sb = new StringBuffer();
00385 sb.append("Fields(");
00386
00387 sb.append("type=");
00388 sb.append(type);
00389 sb.append(",");
00390
00391 sb.append("ci=");
00392 sb.append(ci.getName());
00393 sb.append(",");
00394
00395 sb.append("values=");
00396 sb.append('[');
00397 for(int i = 0; i < values.length; i++) {
00398 if(i != 0)
00399 sb.append(',');
00400 sb.append(values[i]);
00401 }
00402 sb.append(']');
00403 sb.append(",");
00404
00405 sb.append("nFields=");
00406 sb.append(nFields);
00407 sb.append(",");
00408
00409 sb.append("isClass=");
00410 sb.append(isClass);
00411 sb.append(",");
00412
00413
00414 sb.append("vRefs=");
00415 sb.append(vRefs);
00416
00417
00418 sb.append(")");
00419
00420 return sb.toString();
00421 }
00422 }