Adding the old tracker variable for debugging/testing purposes.
[jpf-core.git] / src / main / gov / nasa / jpf / vm / FieldInfo.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 java.lang.reflect.Modifier;
21
22
23 /**
24  * type, name and attribute information of a field.
25  */
26 public abstract class FieldInfo extends InfoObject implements GenericSignatureHolder {
27
28   //--- FieldInfo attributes
29   // don't break transitions on get/putXX insns of this field, even if shared
30   static final int NEVER_BREAK = 0x10000;
31   
32   // always break on this field's access if object is shared
33   // (ignored if NEVER_BREAK is set)
34   static final int BREAK_SHARED = 0x20000;
35
36   // those might relate to sticky ElementInto.ATTR_*
37   protected int attributes;
38
39   
40   protected final String name;
41   protected String type;  // lazy initialized fully qualified type name as per JLS 6.7 ("int", "x.Y[]")
42   protected final String signature; // "I", "[Lx/Y;" etc.
43   protected int storageSize;
44
45   protected ClassInfo ci; // class this field belongs to
46   protected int fieldIndex; // declaration ordinal
47
48   // where in the corresponding Fields object do we store the value
49   // (note this works because of the wonderful single inheritance)
50   protected int storageOffset;
51
52   // optional initializer for this field, can't be final because it is set from
53   // classfile field_info attributes (i.e. after construction)
54   protected  Object cv;
55
56   protected String genericSignature;
57
58   protected int modifiers;
59   
60   public static FieldInfo create (String name, String signature, int modifiers){
61     switch(signature.charAt(0)){
62       case 'Z':
63         return new BooleanFieldInfo(name, modifiers);
64       case 'B':
65         return new ByteFieldInfo(name, modifiers);
66       case 'S':
67         return new ShortFieldInfo(name, modifiers);
68       case 'C':
69         return new CharFieldInfo(name, modifiers);
70       case 'I':
71         return new IntegerFieldInfo(name, modifiers);
72       case 'J':
73         return new LongFieldInfo(name, modifiers);
74       case 'F':
75         return new FloatFieldInfo(name, modifiers);
76       case 'D':
77         return new DoubleFieldInfo(name, modifiers);
78       default:
79         return new ReferenceFieldInfo(name, signature, modifiers);
80     }
81   }
82   
83   protected FieldInfo(String name, String signature, int modifiers) {
84     this.name = name;
85     this.signature = signature;
86     this.modifiers = modifiers;
87   }
88
89   protected void linkToClass (ClassInfo ci, int idx, int off){
90     this.ci = ci;
91     this.fieldIndex = idx;
92     this.storageOffset = off;
93   }
94   
95   // those are set subsequently from classfile attributes
96   public void setConstantValue(Object constValue){
97     cv = constValue;
98   }
99
100   public abstract String valueToString (Fields f);
101
102   public boolean is1SlotField(){
103     return false;
104   }
105   public boolean is2SlotField(){
106     return false;
107   }
108
109   public boolean isBooleanField() {
110     return false;
111   }
112   public boolean isByteField() {
113     return false;
114   }
115   public boolean isCharField() {
116     return false;
117   }
118   public boolean isShortField() {
119     return false;
120   }
121   public boolean isIntField() {
122     return false;
123   }
124   public boolean isLongField() {
125     return false;
126   }
127   public boolean isFloatField(){
128     return false;
129   }
130   public boolean isDoubleField(){
131     return false;
132   }
133
134   public boolean isNumericField(){
135     return false;
136   }
137
138   public boolean isFloatingPointField(){
139     return false;
140   }
141
142   public boolean isReference () {
143     return false;
144   }
145
146   public boolean isArrayField () {
147     return false;
148   }
149
150   /**
151    * Returns the class that this field is associated with.
152    */
153   public ClassInfo getClassInfo () {
154     return ci;
155   }
156
157   public Object getConstantValue () {
158     return cv;
159   }
160
161   public abstract Object getValueObject (Fields data);
162
163   public int getModifiers() {
164     return modifiers;
165   }
166
167   public int getFieldIndex () {
168     return fieldIndex;
169   }
170
171   /**
172    * is this a static field? Counter productive to the current class struct,
173    * but at some point we want to get rid of the Dynamic/Static branch (it's
174    * really just a field attribute)
175    */
176   public boolean isStatic () {
177     return (modifiers & Modifier.STATIC) != 0;
178   }
179
180   /**
181    * is this field declared `final'?
182    */
183   public boolean isFinal () {
184     return (modifiers & Modifier.FINAL) != 0;
185   }
186
187   public boolean isVolatile () {
188     return (modifiers & Modifier.VOLATILE) != 0;
189   }
190
191   public boolean isTransient () {
192     return (modifiers & Modifier.TRANSIENT) != 0;
193   }
194
195   public boolean isPublic () {
196     return (modifiers & Modifier.PUBLIC) != 0;
197   }
198
199   public boolean isPrivate () {
200     return (modifiers & Modifier.PRIVATE) != 0;
201   }
202
203   public boolean isProtected () {
204     return (modifiers & Modifier.PROTECTED) != 0;
205   }
206
207   public boolean isPackagePrivate() {
208     return (modifiers & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE)) == 0;
209   }
210   
211   /**
212    * Returns the name of the field.
213    */
214   public String getName () {
215     return name;
216   }
217
218   /**
219    * @return the storage size of this field, @see Types.getTypeSize
220    */
221   public int getStorageSize () {
222     return 1;
223   }
224
225   /**
226    * Returns the type of the field as a fully qualified type name according to JLS 6.7
227    * ("int", "x.Y[]")
228    */
229   public String getType () {
230     if (type == null){
231       type = Types.getTypeName(signature);
232     }
233     return type;
234   }
235   
236   public byte getTypeCode (){
237     return Types.getTypeCode(signature);
238   }
239
240   public String getSignature(){
241     return signature;
242   }
243
244   @Override
245   public String getGenericSignature() {
246     return genericSignature; 
247   }
248
249   @Override
250   public void setGenericSignature(String sig){
251     genericSignature = sig;
252   }
253
254   public ClassInfo getTypeClassInfo () {
255     return ClassLoaderInfo.getCurrentResolvedClassInfo(getType());
256   }
257
258   public Class<? extends ChoiceGenerator<?>> getChoiceGeneratorType (){
259     return null;
260   }
261
262   /**
263    * pushClinit the corresponding data in the provided Fields instance
264    */
265   public abstract void initialize (ElementInfo ei, ThreadInfo ti);
266
267
268   /**
269    * Returns a string representation of the field.
270    */
271   @Override
272   public String toString () {
273     StringBuilder sb = new StringBuilder();
274
275     if (isStatic()) {
276       sb.append("static ");
277     }
278     if (isFinal()) {
279       sb.append("final ");
280     }
281
282     //sb.append(Types.getTypeName(type));
283     sb.append(getType());
284     sb.append(' ');
285     if (ci != null){ // maybe the fieldinfo isn't linked yet
286       sb.append(ci.getName());
287     }
288     sb.append('.');
289     sb.append(name);
290
291     return sb.toString();
292   }
293   
294   //--- those are the JPF internal attribute flags (not to mix with free user attrs)
295
296   void setAttributes (int a) {
297     attributes = a;
298   }
299
300   public void addAttribute (int a){
301     attributes |= a;
302   }
303
304   public int getAttributes () {
305     return attributes;
306   }
307
308   public boolean breakShared() {
309     return ((attributes & BREAK_SHARED) != 0);
310   }
311   
312   public boolean neverBreak() {
313     return ((attributes & NEVER_BREAK) != 0);    
314   }
315   
316   public int getStorageOffset () {
317     return storageOffset;
318   }
319
320   public String getFullName() {
321     return ci.getName() + '.' + name;
322   }
323
324   /**
325    * Creates a field for a given class, by cloning this FieldInfo
326    * and reseting the class that the field belongs to
327    */
328   public FieldInfo getInstanceFor(ClassInfo ci) {
329     FieldInfo clone;
330
331     try {
332       clone = (FieldInfo)clone();
333       clone.ci = ci;
334     } catch (CloneNotSupportedException cnsx){
335       cnsx.printStackTrace();
336       return null;
337     }
338
339     return clone;
340   }
341 }