Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / NEW.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.bytecode.NewInstruction;
21 import gov.nasa.jpf.vm.ClassInfo;
22 import gov.nasa.jpf.vm.ElementInfo;
23 import gov.nasa.jpf.vm.Heap;
24 import gov.nasa.jpf.vm.Instruction;
25 import gov.nasa.jpf.vm.LoadOnJPFRequired;
26 import gov.nasa.jpf.vm.MJIEnv;
27 import gov.nasa.jpf.vm.StackFrame;
28 import gov.nasa.jpf.vm.ThreadInfo;
29 import gov.nasa.jpf.vm.Types;
30
31
32 /**
33  * Create new object
34  * ... => ..., objectref
35  */
36 public class NEW extends NewInstruction implements JVMInstruction  {
37   protected String cname;
38   protected int newObjRef = MJIEnv.NULL;
39
40   public NEW (String clsDescriptor){
41     cname = Types.getClassNameFromTypeName(clsDescriptor);
42   }
43   
44   public String getClassName(){    // Needed for Java Race Finder
45     return(cname);
46   }
47
48   @Override
49   public Instruction execute (ThreadInfo ti) {
50     Heap heap = ti.getHeap();
51     ClassInfo ci;
52
53     // resolve the referenced class
54     try {
55       ci = ti.resolveReferencedClass(cname);
56     } catch(LoadOnJPFRequired lre) {
57       return ti.getPC();
58     }
59
60     if (ci.initializeClass(ti)){
61       // continue with the topframe and re-exec this insn once the clinits are done
62       return ti.getPC();
63     }
64
65     if (heap.isOutOfMemory()) { // simulate OutOfMemoryError
66       return ti.createAndThrowException("java.lang.OutOfMemoryError",
67                                         "trying to allocate new " + cname);
68     }
69
70     ElementInfo ei = heap.newObject(ci, ti);
71     int objRef = ei.getObjectRef();
72     newObjRef = objRef;
73
74     // pushes the return value onto the stack
75     StackFrame frame = ti.getModifiableTopFrame();
76     frame.pushRef( objRef);
77
78     return getNext(ti);
79   }
80
81   @Override
82   public int getLength() {
83     return 3; // opcode, index1, index2
84   }
85
86   @Override
87   public int getByteCode () {
88     return 0xBB;
89   }
90   
91   @Override
92   public void accept(JVMInstructionVisitor insVisitor) {
93           insVisitor.visit(this);
94   }
95
96   public int getNewObjectRef() {
97     return newObjRef;
98   }
99
100   @Override
101   public String toString() {
102     if (newObjRef != MJIEnv.NULL){
103       return "new " + cname + '@' + Integer.toHexString(newObjRef);
104
105     } else {
106       return "new " + cname;
107     }
108   }
109 }