Fixes null captured parameters
[jpf-core.git] / src / main / gov / nasa / jpf / vm / DynamicElementInfo.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.JPFException;
21
22 /**
23  * A specialized version of ElementInfo that represents heap objects
24  */
25 public class DynamicElementInfo extends ElementInfo {
26   
27   public DynamicElementInfo () {
28     // for restoration
29   }
30
31   public DynamicElementInfo (int objref, ClassInfo ci, Fields f, Monitor m, ThreadInfo ti) {
32     super(objref, ci, f, m, ti);
33
34     attributes = ci.getElementInfoAttrs();
35
36     ti.getScheduler().initializeObjectSharedness(ti, this);
37   }
38
39   @Override
40   public ElementInfo getModifiableInstance() {
41     if (!isFrozen()) {
42       return this;
43     } else {
44       return VM.getVM().getHeap().getModifiable( objRef);
45     }
46   }
47     
48   @Override
49   public boolean isObject(){
50     return true;
51   }
52   
53   @Override
54   public boolean hasFinalizer() {
55     return (ci.getFinalizer()!=null);
56   }
57   
58   @Override
59   protected int getNumberOfFieldsOrElements(){
60     if (fields instanceof ArrayFields){
61       return ((ArrayFields)fields).arrayLength();
62     } else {
63       return ci.getNumberOfInstanceFields();
64     }
65   }
66
67   @Override
68   public int getNumberOfFields () {
69     return getClassInfo().getNumberOfInstanceFields();
70   }
71
72   @Override
73   public FieldInfo getFieldInfo (int fieldIndex) {
74     return getClassInfo().getInstanceField(fieldIndex);
75   }
76
77   @Override
78   public FieldInfo getFieldInfo (String fname) {
79     return getClassInfo().getInstanceField(fname);
80   }
81   @Override
82   protected FieldInfo getDeclaredFieldInfo (String clsBase, String fname) {
83     return getClassInfo().getClassLoaderInfo().getResolvedClassInfo(clsBase).getDeclaredInstanceField(fname);
84   }
85
86   @Override
87   public ElementInfo getEnclosingElementInfo(){
88     for (FieldInfo fi : getClassInfo().getDeclaredInstanceFields()){
89       if (fi.getName().startsWith("this$")){
90         int objref = getReferenceField(fi);
91         return VM.getVM().getElementInfo(objref);
92       }
93     }
94     return null;
95   }
96
97   @Override
98   public String asString() {
99     char[] data = getStringChars();
100     if (data != null){
101       return new String(data);
102       
103     } else {
104       return "";
105     }
106   }
107
108   @Override
109   public char[] getStringChars(){
110     if (!ClassInfo.isStringClassInfo(ci)) {
111       throw new JPFException("object is not of type java.lang.String");
112     }
113
114     int vref = getDeclaredReferenceField("value", "java.lang.String");    
115     if (vref != MJIEnv.NULL){
116       ElementInfo eVal = VM.getVM().getHeap().get(vref);
117       char[] value = eVal.asCharArray();
118       return value;
119       
120     } else {
121       return null;
122     }    
123   }
124   
125   /**
126    * just a helper to avoid creating objects just for the sake of comparing
127    */
128   @Override
129   public boolean equalsString (String s) {
130     if (!ClassInfo.isStringClassInfo(ci)) {
131       return false;
132     }
133
134     int vref = getDeclaredReferenceField("value", "java.lang.String");
135     ElementInfo e = VM.getVM().getHeap().get(vref);
136     CharArrayFields cf = (CharArrayFields)e.getFields();
137     char[] v = cf.asCharArray();
138     
139     return new String(v).equals(s);
140   }
141
142   @Override
143   public boolean isBoxObject(){
144     String cname = ci.getName();
145     if (cname.startsWith("java.lang.")){
146       cname = cname.substring(10);
147       return ("Boolean".equals(cname) ||
148           "Character".equals(cname) ||
149           "Byte".equals(cname) ||
150           "Short".equals(cname) ||
151           "Integer".equals(cname) ||
152           "Float".equals(cname) ||
153           "Long".equals(cname) ||
154           "Double".equals(cname) );
155         
156     } else {
157       return false;
158     }
159   }
160   
161   @Override
162   public Object asBoxObject(){
163     String cname = ci.getName();
164     if (cname.startsWith("java.lang.")){
165       cname = cname.substring(10);
166       if ("Boolean".equals(cname)){
167         return Boolean.valueOf( getBooleanField("value"));
168       } else if ("Character".equals(cname)){
169         return Character.valueOf(getCharField("value"));
170       } else if ("Byte".equals(cname)){
171         return Byte.valueOf( getByteField("value"));
172       } else if ("Short".equals(cname)){
173         return Short.valueOf( getShortField("value"));
174       } else if ("Integer".equals(cname)){
175         return Integer.valueOf( getIntField("value"));
176       } else if ("Float".equals(cname)){
177         return Float.valueOf( getFloatField("value"));
178       } else if ("Long".equals(cname)){
179         return Long.valueOf( getLongField("value"));
180       } else if ("Double".equals(cname)){
181         return Double.valueOf( getDoubleField("value"));
182       }
183     }
184     
185     throw new JPFException("object is not a box object: " + this);    
186   }
187 }