Adding ParameterizedTypeImpl to getGenericSuperclass method.
[jpf-core.git] / src / main / gov / nasa / jpf / vm / Fields.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.vm;
19
20 import gov.nasa.jpf.util.HashData;
21 import gov.nasa.jpf.util.IntVector;
22 import gov.nasa.jpf.util.Misc;
23 import gov.nasa.jpf.util.ObjectList;
24
25
26 /**
27  * Represents the variable, hash-collapsed pooled data associated with an object
28  * that is related to the object values (as opposed to synchronization ->Monitor).
29  * Contains the values of the fields, not their descriptors.  Descriptors are represented
30  * by gov.nasa.jpf.vm.FieldInfo objects, which are stored in the ClassInfo structure.
31  *
32  * @see gov.nasa.jpf.vm.FieldInfo
33  * @see gov.nasa.jpf.vm.Monitor
34  */
35 public abstract class Fields implements Cloneable {
36
37   /**
38    * we use this to store arbitrary field attributes (like symbolic values),
39    * but only create this on demand
40    */
41   protected Object[] fieldAttrs;
42
43   /**
44    * attribute attached to the object as a whole
45    */
46   protected Object objectAttr;
47
48
49   protected Fields() {}
50
51   public boolean hasFieldAttr() {
52     return fieldAttrs != null;
53   }
54
55   public boolean hasFieldAttr (Class<?> attrType){    
56     Object[] fa = fieldAttrs;
57     if (fa != null){
58       for (int i=0; i<fa.length; i++){
59         Object a = fa[i];
60         if (a != null && ObjectList.containsType(a, attrType)){
61           return true;
62         }
63       }
64     }
65     return false;
66   }
67
68
69   /**
70    * this returns all of them - use either if you know there will be only
71    * one attribute at a time, or check/process result with ObjectList
72    */
73   public Object getFieldAttr(int fieldOrElementIndex){
74     if (fieldAttrs != null){
75       return fieldAttrs[fieldOrElementIndex];
76     }
77     return null;
78   }
79
80   /**
81    * this replaces all of them - use only if you know 
82    *  - there will be only one attribute at a time
83    *  - you obtained the value you set by a previous getXAttr()
84    *  - you constructed a multi value list with ObjectList.createList()
85    */
86   public void setFieldAttr (int nFieldsOrElements, int fieldOrElementIndex, Object attr){
87     if (fieldAttrs == null){
88       if (attr == null){
89         return; // no need to waste an array object for storing null
90       }
91       fieldAttrs = new Object[nFieldsOrElements];
92     }
93     fieldAttrs[fieldOrElementIndex] = attr;
94   }
95   
96   public void addFieldAttr (int nFieldsOrElements, int fieldOrElementIndex, Object attr){
97     if (attr != null){
98       if (fieldAttrs == null) {
99         fieldAttrs = new Object[nFieldsOrElements];
100       }
101       fieldAttrs[fieldOrElementIndex] = ObjectList.add(fieldAttrs[fieldOrElementIndex], attr);
102     }
103   }
104   
105   public void removeFieldAttr (int fieldOrElementIndex, Object attr){
106     if (fieldAttrs != null){
107      fieldAttrs[fieldOrElementIndex] = ObjectList.remove(fieldAttrs[fieldOrElementIndex], attr);
108     }
109   }
110   
111   public void replaceFieldAttr (int fieldOrElementIndex, Object oldAttr, Object newAttr){
112     if (fieldAttrs != null){
113      fieldAttrs[fieldOrElementIndex] = ObjectList.replace(fieldAttrs[fieldOrElementIndex], oldAttr, newAttr);
114     }
115   }
116   
117   public boolean hasFieldAttr (int fieldOrElementIndex, Class<?> type){
118     if (fieldAttrs != null){
119      return ObjectList.containsType(fieldAttrs[fieldOrElementIndex], type);
120     }
121     return false;
122   }
123
124   /**
125    * this only returns the first attr of this type, there can be more
126    * if you don't use client private types or the provided type is too general
127    */
128   public <T> T getFieldAttr (int fieldOrElementIndex, Class<T> type){
129     if (fieldAttrs != null){
130      return ObjectList.getFirst(fieldAttrs[fieldOrElementIndex], type);
131     }
132     return null;    
133   }
134   
135   public <T> T getNextFieldAttr (int fieldOrElementIndex, Class<T> type, Object prev){
136     if (fieldAttrs != null){
137      return ObjectList.getNext(fieldAttrs[fieldOrElementIndex], type, prev);
138     }
139     return null;    
140   }
141   
142   public ObjectList.Iterator fieldAttrIterator(int fieldOrElementIndex){
143     Object a = (fieldAttrs != null) ? fieldAttrs[fieldOrElementIndex] : null;
144     return ObjectList.iterator(a);
145   }
146   
147   public <T> ObjectList.TypedIterator<T> fieldAttrIterator(int fieldOrElementIndex, Class<T> type){
148     Object a = (fieldAttrs != null) ? fieldAttrs[fieldOrElementIndex] : null;
149     return ObjectList.typedIterator(a, type);
150   }
151   
152
153   //--- object attributes
154   public boolean hasObjectAttr () {
155     return (objectAttr != null);
156   }
157
158   public boolean hasObjectAttr (Class<?> attrType){
159     return ObjectList.containsType(objectAttr, attrType);
160   }
161
162   /**
163    * this returns all of them - use either if you know there will be only
164    * one attribute at a time, or check/process result with ObjectList
165    */
166   public Object getObjectAttr(){
167     return objectAttr;
168   }
169
170   /**
171    * this replaces all of them - use only if you know 
172    *  - there will be only one attribute at a time
173    *  - you obtained the value you set by a previous getXAttr()
174    *  - you constructed a multi value list with ObjectList.createList()
175    */
176   public void setObjectAttr (Object attr){
177     objectAttr = attr;    
178   }
179
180   public void addObjectAttr (Object attr){
181     objectAttr = ObjectList.add(objectAttr, attr);
182   }
183
184   public void removeObjectAttr (Object attr){
185     objectAttr = ObjectList.remove(objectAttr, attr);
186   }
187
188   public void replaceObjectAttr (Object oldAttr, Object newAttr){
189     objectAttr = ObjectList.replace(objectAttr, oldAttr, newAttr);
190   }
191
192   /**
193    * this only returns the first attr of this type, there can be more
194    * if you don't use client private types or the provided type is too general
195    */
196   public <T> T getObjectAttr (Class<T> attrType) {
197     return ObjectList.getFirst(objectAttr, attrType);
198   }
199
200   public <T> T getNextObjectAttr (Class<T> attrType, Object prev) {
201     return ObjectList.getNext(objectAttr, attrType, prev);
202   }
203
204   public ObjectList.Iterator objectAttrIterator(){
205     return ObjectList.iterator(objectAttr);
206   }
207   
208   public <T> ObjectList.TypedIterator<T> objectAttrIterator(Class<T> attrType){
209     return ObjectList.typedIterator(objectAttr, attrType);
210   }
211
212
213   public abstract int[] asFieldSlots();
214
215   /**
216    * give an approximation of the heap size in bytes - we assume fields are word
217    * aligned, hence the number of values*4 should be good. Note that this is
218    * overridden by ArrayFields (arrays would be packed)
219    */
220   public abstract int getHeapSize ();
221
222
223   public boolean isReferenceArray () {
224     return false;
225   }
226
227   // our low level getters and setters
228   public abstract int getIntValue (int index);
229
230   // same as getIntValue(), just here to make intentions clear
231   public abstract int getReferenceValue (int index);
232
233   public abstract long getLongValue (int index);
234
235   public abstract boolean getBooleanValue (int index);
236
237   public abstract byte getByteValue (int index);
238
239   public abstract char getCharValue (int index);
240
241   public abstract short getShortValue (int index);
242
243   public abstract float getFloatValue (int index);
244
245   public abstract double getDoubleValue (int index);
246
247   //--- the field modifier methods (both instance and static)
248
249   public abstract void setReferenceValue (int index, int newValue);
250
251   public abstract void setBooleanValue (int index, boolean newValue);
252
253   public abstract void setByteValue (int index, byte newValue);
254
255   public abstract void setCharValue (int index, char newValue);
256
257   public abstract void setShortValue (int index, short newValue);
258
259   public abstract void setFloatValue (int index, float newValue);
260
261   public abstract void setIntValue (int index, int newValue);
262
263   public abstract void setLongValue (int index, long newValue);
264
265   public abstract void setDoubleValue (int index, double newValue);
266
267   @Override
268   public abstract Fields clone ();
269
270   protected Fields cloneFields() {
271     try {
272       Fields f = (Fields)super.clone();
273
274       if (fieldAttrs != null) {
275         f.fieldAttrs = fieldAttrs.clone();
276       }
277
278       if (objectAttr != null) {
279         f.objectAttr = objectAttr; //
280       }
281
282       return f;
283     } catch (CloneNotSupportedException cnsx){
284       return null;
285     }
286   }
287
288   @Override
289   public abstract boolean equals(Object o);
290
291   // <2do> not multi-attr aware yet
292   protected boolean compareAttrs(Fields f) {
293     if (fieldAttrs != null || f.fieldAttrs != null) {
294       if (!Misc.equals(fieldAttrs, f.fieldAttrs)) {
295         return false;
296       }
297     }
298
299     if (!ObjectList.equals(objectAttr, f.objectAttr)){
300       return false;
301     }
302
303     return true;
304   }
305
306   // serialization interface
307   public abstract void appendTo(IntVector v);
308
309
310   @Override
311   public int hashCode () {
312     HashData hd = new HashData();
313     hash(hd);
314     hashAttrs(hd);
315     return hd.getValue();
316   }
317
318   public abstract void hash(HashData hd);
319
320   /**
321    * Adds some data to the computation of an hashcode.
322    */
323   public void hashAttrs (HashData hd) {
324
325     // it's debatable if we add the attributes to the state, but whatever it
326     // is, it should be kept consistent with the StackFrame.hash()
327     Object[] a = fieldAttrs;
328     if (a != null) {
329       for (int i=0, l=a.length; i < l; i++) {
330         ObjectList.hash(a[i], hd);
331       }
332     }
333
334     if (objectAttr != null){
335       ObjectList.hash(objectAttr, hd);
336     }
337   }
338
339
340   // <2do> not multi-attr aware yet
341   public void copyAttrs(Fields other) {
342     if (other.fieldAttrs != null){
343       if (fieldAttrs == null){
344         fieldAttrs = other.fieldAttrs.clone();
345       } else {
346         System.arraycopy(other.fieldAttrs, 0, fieldAttrs, 0, fieldAttrs.length);
347       }
348     }
349
350     objectAttr = other.objectAttr;
351   }
352 }