2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
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
10 * http://www.apache.org/licenses/LICENSE-2.0.
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.
18 package gov.nasa.jpf.vm;
20 import gov.nasa.jpf.JPFException;
21 import gov.nasa.jpf.annotation.MJI;
22 import gov.nasa.jpf.vm.ClassInfo;
23 import gov.nasa.jpf.vm.ElementInfo;
24 import gov.nasa.jpf.vm.Heap;
25 import gov.nasa.jpf.vm.MJIEnv;
26 import gov.nasa.jpf.vm.NativePeer;
27 import gov.nasa.jpf.vm.ThreadInfo;
28 import gov.nasa.jpf.vm.Types;
32 * MJI NativePeer class for java.lang.Object library abstraction
34 public class JPF_java_lang_Object extends NativePeer {
37 public int getClass____Ljava_lang_Class_2 (MJIEnv env, int objref) {
38 ClassInfo oci = env.getClassInfo(objref);
40 return oci.getClassObjectRef();
44 public int clone____Ljava_lang_Object_2 (MJIEnv env, int objref) {
45 Heap heap = env.getHeap();
46 ElementInfo ei = heap.get(objref);
47 ClassInfo ci = ei.getClassInfo();
48 ElementInfo eiClone = null;
50 if (!ci.isInstanceOf("java.lang.Cloneable")) {
51 env.throwException("java.lang.CloneNotSupportedException",
52 ci.getName() + " does not implement java.lang.Cloneable.");
53 return MJIEnv.NULL; // meaningless
58 ClassInfo cci = ci.getComponentClassInfo();
61 if (cci.isPrimitive()){
62 componentType = Types.getTypeSignature(cci.getName(),false);
64 componentType = cci.getType();
67 eiClone = heap.newArray(componentType, ei.arrayLength(), env.getThreadInfo());
70 eiClone = heap.newObject(ci, env.getThreadInfo());
73 // Ok, this is nasty but efficient
74 eiClone.fields = ei.getFields().clone();
76 return eiClone.getObjectRef();
81 public int hashCode____I (MJIEnv env, int objref) {
82 return (objref ^ 0xABCD);
85 protected void wait0 (MJIEnv env, int objref, long timeout) {
86 ThreadInfo ti = env.getThreadInfo();
87 ElementInfo ei = env.getModifiableElementInfo(objref);
89 if (!ti.isFirstStepInsn()) {
90 if (!ei.isLockedBy(ti)) {
91 env.throwException("java.lang.IllegalMonitorStateException", "wait() without holding lock");
95 if (ti.isInterrupted(true)) {
96 env.throwException("java.lang.InterruptedException");
98 ei.wait(ti, timeout); // block
103 if (ti.getScheduler().setsWaitCG(ti, timeout)) {
104 env.repeatInvocation();
108 // bottom half, unblock
109 switch (ti.getState()) {
111 case TIMEOUT_WAITING:
112 throw new JPFException("blocking wait() without transition break");
114 // we can get here by direct call from ...Unsafe.park__ZJ__V()
115 // which aquires the park lock and waits natively
118 // note that we can't get here if we are in NOTIFIED or INTERRUPTED state,
119 // since we still have to reacquire the lock
121 case TIMEDOUT: // nobody else acquired the lock
122 // thread status set by explicit notify() call
123 env.lockNotified(objref);
125 if (ti.isInterrupted(true)) {
126 env.throwException("java.lang.InterruptedException");
131 throw new JPFException("invalid thread state of: " + ti.getName() + " is " + ti.getStateName()
132 + " while waiting on " + ei);
136 // we intercept them both so that we don't get the java.lang.Object.wait() location
137 // as the blocking insn
139 public void wait____V (MJIEnv env, int objref){
144 public void wait__J__V (MJIEnv env, int objref, long timeout) {
145 wait0(env,objref,timeout);
149 public void wait__JI__V (MJIEnv env, int objref, long timeout, int nanos) {
150 wait0(env,objref,timeout);
155 public void notify____V (MJIEnv env, int objref) {
156 boolean didNotify = false;
157 ThreadInfo ti = env.getThreadInfo();
159 if (!ti.isFirstStepInsn()) {
160 ElementInfo ei = env.getModifiableElementInfo(objref);
161 if (!ei.isLockedBy(ti)) {
162 env.throwException("java.lang.IllegalMonitorStateException", "notify() without holding lock");
166 didNotify = env.notify(ei);
169 if (ti.getScheduler().setsNotifyCG(ti, didNotify)){
170 env.repeatInvocation();
176 public void notifyAll____V (MJIEnv env, int objref) {
177 boolean didNotify = false;
178 ThreadInfo ti = env.getThreadInfo();
180 if (!ti.isFirstStepInsn()) {
181 ElementInfo ei = env.getModifiableElementInfo(objref);
182 if (!ei.isLockedBy(ti)) {
183 env.throwException("java.lang.IllegalMonitorStateException", "notifyAll() without holding lock");
187 didNotify = env.notifyAll(ei);
190 if (ti.getScheduler().setsNotifyCG(ti, didNotify)){
191 env.repeatInvocation();
197 public int toString____Ljava_lang_String_2 (MJIEnv env, int objref) {
198 ClassInfo ci = env.getClassInfo(objref);
199 int hc = hashCode____I(env,objref);
201 String s = ci.getName() + '@' + hc;
202 int sref = env.newString(s);