Fixing a few bugs in the statistics printout.
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / StaticFieldInstruction.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.jvm.bytecode;
19
20 import gov.nasa.jpf.vm.ClassInfo;
21 import gov.nasa.jpf.vm.ElementInfo;
22 import gov.nasa.jpf.vm.FieldInfo;
23 import gov.nasa.jpf.vm.Instruction;
24 import gov.nasa.jpf.vm.MethodInfo;
25 import gov.nasa.jpf.vm.StaticElementInfo;
26 import gov.nasa.jpf.vm.ThreadInfo;
27 import gov.nasa.jpf.vm.bytecode.FieldInstruction;
28
29 /**
30  * class to abstract instructions accessing static fields
31  */
32 public abstract class StaticFieldInstruction extends FieldInstruction {
33
34   protected StaticFieldInstruction(String fieldName, String clsDescriptor, String fieldDescriptor){
35     super(fieldName, clsDescriptor, fieldDescriptor);
36   }
37
38   /**
39    * on-demand initialize the ClassInfo and FieldInfo fields. Note that
40    * classinfo might not correspond with the static className, but can be one of
41    * the super classes. Rather than checking for this on each subsequent access,
42    * we get the right one that declares the field here
43    */
44   protected void initialize() {
45     ClassInfo ciRef = mi.getClassInfo().resolveReferencedClass(className);
46     
47     FieldInfo f = ciRef.getStaticField(fname);
48     ClassInfo ciField = f.getClassInfo();
49     if (!ciField.isRegistered()){
50       // classLoaded listeners might change/remove this field
51       ciField.registerClass(ThreadInfo.getCurrentThread());
52       f = ciField.getStaticField(fname);
53     }
54     
55     fi = f;
56   }
57
58   /**
59    * who owns the field?
60    * NOTE: this should only be used from a executeInstruction()/instructionExecuted() context
61    */
62   @Override
63   public ElementInfo getElementInfo(ThreadInfo ti){
64     return getFieldInfo().getClassInfo().getStaticElementInfo();
65   }
66   
67   @Override
68   public String toPostExecString(){
69     StringBuilder sb = new StringBuilder();
70     sb.append(getMnemonic());
71     sb.append(' ');
72     sb.append( fi.getFullName());
73     
74     return sb.toString();
75   }
76
77   public ClassInfo getClassInfo() {
78     if (fi == null) {
79       initialize();
80     }
81     return fi.getClassInfo();
82   }
83
84   @Override
85   public FieldInfo getFieldInfo() {
86     if (fi == null) {
87       initialize();
88     }
89     return fi;
90   }
91
92   /**
93    *  that's invariant, as opposed to InstanceFieldInstruction, so it's
94    *  not really a peek
95    */
96   @Override
97   public ElementInfo peekElementInfo (ThreadInfo ti) {
98     return getLastElementInfo();
99   }
100
101   @Override
102   public StaticElementInfo getLastElementInfo() {
103     return getFieldInfo().getClassInfo().getStaticElementInfo();
104   }
105
106   // this can be different than ciField - the field might be in one of its
107   // superclasses
108   public ClassInfo getLastClassInfo(){
109     return getFieldInfo().getClassInfo();
110   }
111
112   public String getLastClassName() {
113     return getLastClassInfo().getName();
114   }
115
116   public void accept(JVMInstructionVisitor insVisitor) {
117           insVisitor.visit(this);
118   }
119
120   @Override
121   public Instruction typeSafeClone(MethodInfo mi) {
122     StaticFieldInstruction clone = null;
123
124     try {
125       clone = (StaticFieldInstruction) super.clone();
126
127       // reset the method that this insn belongs to
128       clone.mi = mi;
129       clone.fi = null; // ClassInfo is going to be different
130       
131     } catch (CloneNotSupportedException e) {
132       e.printStackTrace();
133     }
134
135     return clone;
136   }
137 }
138