Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / ArrayStoreInstruction.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.StoreInstruction;
21 import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException;
22 import gov.nasa.jpf.vm.ElementInfo;
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
29
30 /**
31  * abstraction for all array store instructions
32  *
33  *  ... array, index, <value> => ...
34  */
35 public abstract class ArrayStoreInstruction extends JVMArrayElementInstruction implements StoreInstruction, JVMInstruction {
36
37
38   @Override
39   public Instruction execute (ThreadInfo ti) {
40     StackFrame frame = ti.getModifiableTopFrame();
41     int idx = peekIndex(ti);
42     int aref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore
43     ElementInfo eiArray = ti.getElementInfo(aref);
44
45     arrayOperandAttr = peekArrayAttr(ti);
46     indexOperandAttr = peekIndexAttr(ti);
47
48     if (!ti.isFirstStepInsn()){ // first execution, top half
49       //--- runtime exceptions
50       if (aref == MJIEnv.NULL) {
51         return ti.createAndThrowException("java.lang.NullPointerException");
52       }
53     
54       //--- shared access CG
55       Scheduler scheduler = ti.getScheduler();
56       if (scheduler.canHaveSharedArrayCG(ti, this, eiArray, idx)){
57         eiArray = scheduler.updateArraySharedness(ti, eiArray, idx);
58         if (scheduler.setsSharedArrayCG(ti, this, eiArray, idx)){
59           return this;
60         }
61       }
62     }
63     
64     try {
65       setArrayElement(ti, frame, eiArray); // this pops operands
66     } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed
67       return ex.getInstruction();
68     }
69
70     return getNext(ti);
71   }
72
73   protected void setArrayElement (ThreadInfo ti, StackFrame frame, ElementInfo eiArray) throws ArrayIndexOutOfBoundsExecutiveException {
74     int esize = getElementSize();
75     Object attr = esize == 1 ? frame.getOperandAttr() : frame.getLongOperandAttr();
76     
77     popValue(frame);
78     index = frame.pop();
79     // don't set 'arrayRef' before we do the CG checks (would kill loop optimization)
80     arrayRef = frame.pop();
81
82     eiArray = eiArray.getModifiableInstance();
83     setField(eiArray, index);
84     eiArray.setElementAttrNoClone(index,attr); // <2do> what if the value is the same but not the attr?
85   }
86   
87   /**
88    * this is for pre-exec use
89    */
90   @Override
91   public int peekArrayRef(ThreadInfo ti) {
92     return ti.getTopFrame().peek(2);
93   }
94
95   @Override
96   public int peekIndex(ThreadInfo ti){
97     return ti.getTopFrame().peek(1);
98   }
99
100   // override in LongArrayStoreInstruction
101   @Override
102   public Object  peekArrayAttr (ThreadInfo ti){
103     return ti.getTopFrame().getOperandAttr(2);
104   }
105
106   @Override
107   public Object peekIndexAttr (ThreadInfo ti){
108     return ti.getTopFrame().getOperandAttr(1);
109   }
110
111
112   protected abstract void popValue(StackFrame frame);
113  
114   protected abstract void setField (ElementInfo e, int index)
115                     throws ArrayIndexOutOfBoundsExecutiveException;
116
117
118   @Override
119   public boolean isRead() {
120     return false;
121   }
122   
123   @Override
124   public void accept(JVMInstructionVisitor insVisitor) {
125           insVisitor.visit(this);
126   }
127
128 }