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.jvm.bytecode;
20 import gov.nasa.jpf.util.InstructionState;
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.MJIEnv;
25 import gov.nasa.jpf.vm.Scheduler;
26 import gov.nasa.jpf.vm.StackFrame;
27 import gov.nasa.jpf.vm.ThreadInfo;
28 import gov.nasa.jpf.vm.bytecode.WriteInstruction;
32 * ..., objectref, value => ...
34 public class PUTFIELD extends JVMInstanceFieldInstruction implements WriteInstruction {
36 public PUTFIELD(String fieldName, String clsDescriptor, String fieldDescriptor){
37 super(fieldName, clsDescriptor, fieldDescriptor);
41 public int getObjectSlot (StackFrame frame){
42 return frame.getTopPos() - size;
46 * where do we get the value from?
47 * NOTE: only makes sense in a executeInstruction() context
50 public int getValueSlot (StackFrame frame){
51 return frame.getTopPos();
56 * where do we write to?
57 * NOTE: this should only be used from a executeInstruction()/instructionExecuted() context
60 public ElementInfo getElementInfo(ThreadInfo ti){
62 return ti.getElementInfo(lastThis);
64 return peekElementInfo(ti); // get it from the stack
69 public Instruction execute (ThreadInfo ti) {
70 StackFrame frame = ti.getModifiableTopFrame();
71 int objRef = frame.peek( size);
74 if (objRef == MJIEnv.NULL) {
75 return ti.createAndThrowException("java.lang.NullPointerException", "referencing field '" + fname + "' on null object");
78 ElementInfo eiFieldOwner = ti.getModifiableElementInfo(objRef);
79 FieldInfo fieldInfo = getFieldInfo();
80 if (fieldInfo == null) {
81 return ti.createAndThrowException("java.lang.NoSuchFieldError", "no field " + fname + " in " + eiFieldOwner);
84 //--- check scheduling point due to shared object access
85 Scheduler scheduler = ti.getScheduler();
86 if (scheduler.canHaveSharedObjectCG(ti,this,eiFieldOwner,fieldInfo)){
87 eiFieldOwner = scheduler.updateObjectSharedness( ti, eiFieldOwner, fi);
88 if (scheduler.setsSharedObjectCG( ti, this, eiFieldOwner, fieldInfo)){
89 return this; // re-execute
93 // this might be re-executed
94 if (frame.getAndResetFrameAttr(InstructionState.class) == null){
95 lastValue = PutHelper.setField(ti, frame, eiFieldOwner, fieldInfo);
98 //--- check scheduling point due to exposure through shared object
99 if (isReferenceField()){
100 int refValue = frame.peek();
101 if (refValue != MJIEnv.NULL){
102 ElementInfo eiExposed = ti.getElementInfo(refValue);
103 if (scheduler.setsSharedObjectExposureCG(ti, this, eiFieldOwner, fi, eiExposed)){
104 frame.addFrameAttr( InstructionState.processed);
105 return this; // re-execute AFTER assignment
114 protected void popOperands (StackFrame frame){
116 frame.pop(2); // .. objref, val => ..
118 frame.pop(3); // .. objref, highVal,lowVal => ..
123 public ElementInfo peekElementInfo (ThreadInfo ti) {
124 FieldInfo fi = getFieldInfo();
125 int storageSize = fi.getStorageSize();
126 int objRef = ti.getTopFrame().peek( (storageSize == 1) ? 1 : 2);
127 ElementInfo ei = ti.getElementInfo( objRef);
134 public int getLength() {
135 return 3; // opcode, index1, index2
139 public int getByteCode () {
144 public boolean isRead() {
149 public void accept(JVMInstructionVisitor insVisitor) {
150 insVisitor.visit(this);