Fixing a subtle bug: the method isParameterWithType() did not consider arbitrary...
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / LDC.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.Instruction;
21 import gov.nasa.jpf.vm.ClassInfo;
22 import gov.nasa.jpf.vm.ElementInfo;
23 import gov.nasa.jpf.vm.LoadOnJPFRequired;
24 import gov.nasa.jpf.vm.StackFrame;
25 import gov.nasa.jpf.vm.ThreadInfo;
26 import gov.nasa.jpf.vm.Types;
27
28
29 /**
30  * Push item from runtime constant pool
31  * ... => ..., value
32  */
33 public class LDC extends Instruction implements JVMInstruction {
34
35   public enum Type {STRING, CLASS, INT, FLOAT};
36
37   Type type;
38
39   protected String  string;  // the string value if Type.STRING, classname if Type.CLASS
40   protected int     value;
41
42   public LDC() {}
43
44   public LDC (String s, boolean isClass){
45     if (isClass){
46       string = Types.getClassNameFromTypeName(s);
47       type = Type.CLASS;
48     } else {
49       string = s;
50       type = Type.STRING;
51     }
52   }
53
54   public LDC (int v){
55     value = v;
56     type = Type.INT;
57   }
58
59   public LDC (float f){
60     value = Float.floatToIntBits(f);
61     type = Type.FLOAT;
62   }
63
64
65   @Override
66   public Instruction execute (ThreadInfo ti) {
67     StackFrame frame = ti.getModifiableTopFrame();
68     
69     switch (type){
70       case STRING:
71         // too bad we can't cache it, since location might change between different paths
72         ElementInfo eiValue = ti.getHeap().newInternString(string, ti); 
73         value = eiValue.getObjectRef();
74         frame.pushRef(value);
75         break;
76
77       case INT:
78       case FLOAT:
79         frame.push(value);
80         break;
81
82       case CLASS:
83         ClassInfo ci;
84         // resolve the referenced class
85         try {
86           ci = ti.resolveReferencedClass(string);
87         } catch(LoadOnJPFRequired lre) {
88           return frame.getPC();
89         }
90
91         // LDC doesn't cause a <clinit> - we only register all required classes
92         // to make sure we have class objects. <clinit>s are called prior to
93         // GET/PUT or INVOKE
94         if (!ci.isRegistered()) {
95           ci.registerClass(ti);
96         }
97
98         frame.pushRef( ci.getClassObjectRef());
99
100         break;
101     }
102     
103     return getNext(ti);
104   }
105
106   @Override
107   public int getLength() {
108     return 2; // opcode, index
109   }
110
111   @Override
112   public int getByteCode () {
113     return 0x12;
114   }
115   
116   public int getValue() {
117     return value;
118   }
119   
120   public Type getType() {
121     return type;
122   }
123   
124   public boolean isString() {
125     return (type == Type.STRING);
126   }
127   
128   public float getFloatValue(){
129           if(type!=Type.FLOAT){
130       throw new IllegalStateException();
131           }
132     
133           return Float.intBitsToFloat(value);
134         }
135
136   public String getStringValue() { // if it is a String (not acquired from the class const pool)
137     if (type == Type.STRING) {
138       return string;
139     } else {
140       return null;
141     }
142   }
143   
144   public String getClassValue() { // if it is the name of a Class (acquired from the class const pool)
145             if (type == Type.CLASS) {
146               return string;
147             } else {
148               return null;
149             }
150           }
151
152   
153   @Override
154   public void accept(JVMInstructionVisitor insVisitor) {
155           insVisitor.visit(this);
156   }
157 }