Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / AASTORE.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.util.InstructionState;
21 import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException;
22 import gov.nasa.jpf.vm.ClassInfo;
23 import gov.nasa.jpf.vm.ElementInfo;
24 import gov.nasa.jpf.vm.Instruction;
25 import gov.nasa.jpf.vm.MJIEnv;
26 import gov.nasa.jpf.vm.Scheduler;
27 import gov.nasa.jpf.vm.StackFrame;
28 import gov.nasa.jpf.vm.ThreadInfo;
29
30
31 /**
32  * Store into reference array
33  * ..., arrayref, index, value  => ...
34  */
35 public class AASTORE extends ArrayStoreInstruction {
36
37   int value;
38
39   @Override
40   public boolean isReferenceArray() {
41     return true;
42   }
43   
44   @Override
45   protected void popValue(StackFrame frame){
46     value = frame.pop();
47   }
48
49   @Override
50   protected void setField (ElementInfo ei, int index) throws ArrayIndexOutOfBoundsExecutiveException {
51     ei.checkArrayBounds(index);
52     ei.setReferenceElement(index, value);
53   }
54   
55   /**
56    * overridden because AASTORE can cause ArrayStoreExceptions and exposure CGs 
57    */
58   @Override
59   public Instruction execute (ThreadInfo ti) {
60     StackFrame frame = ti.getModifiableTopFrame();
61     int refValue = frame.peek();
62     int idx = frame.peek(1);
63     int aref = frame.peek(2);
64     
65     value = aref;
66     index = idx;
67     
68     if (aref == MJIEnv.NULL) {
69       return ti.createAndThrowException("java.lang.NullPointerException");
70     }
71     
72     ElementInfo eiArray = ti.getModifiableElementInfo(aref);
73         
74     if (!ti.isFirstStepInsn()){ // we only need to check this once
75       Instruction xInsn = checkArrayStoreException(ti, frame, eiArray);
76       if (xInsn != null){
77         return xInsn;
78       }
79     }
80     
81     boolean checkExposure = false;
82     Scheduler scheduler = ti.getScheduler();
83     if (scheduler.canHaveSharedArrayCG(ti, this, eiArray, idx)){
84       checkExposure = true;
85       eiArray = scheduler.updateArraySharedness(ti, eiArray, index);
86       if (scheduler.setsSharedArrayCG(ti, this, eiArray, idx)){
87         return this;
88       }
89     }
90
91     // check if this gets re-executed from an exposure CG
92     if (frame.getAndResetFrameAttr(InstructionState.class) == null){
93       try {
94         Object attr = frame.getOperandAttr();
95         eiArray.checkArrayBounds(idx);
96         eiArray.setReferenceElement(idx, refValue);
97         eiArray.setElementAttrNoClone(idx, attr);
98         
99       } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed
100         return ex.getInstruction();
101       }
102
103       if (checkExposure) {
104         if (refValue != MJIEnv.NULL) {
105           ElementInfo eiExposed = ti.getElementInfo(refValue);
106           if (scheduler.setsSharedObjectExposureCG(ti, this, eiArray, null, eiArray)) {
107             frame.addFrameAttr( InstructionState.processed);
108             return this;
109           }
110         }
111       }
112     }
113     
114     frame.pop(3);
115     
116     return getNext(ti);      
117   }
118
119   protected Instruction checkArrayStoreException(ThreadInfo ti, StackFrame frame, ElementInfo ei){
120     ClassInfo c = ei.getClassInfo();
121     int refVal = frame.peek();
122     
123     if (refVal != MJIEnv.NULL) { // no checks for storing 'null'
124       ClassInfo elementCi = ti.getClassInfo(refVal);
125       ClassInfo arrayElementCi = c.getComponentClassInfo();
126       if (!elementCi.isInstanceOf(arrayElementCi)) {
127         String exception = "java.lang.ArrayStoreException";
128         String exceptionDescription = elementCi.getName();
129         return ti.createAndThrowException(exception, exceptionDescription);
130       }
131     }
132
133     return null;
134   }
135
136
137   @Override
138   public int getByteCode () {
139     return 0x53;
140   }
141
142   @Override
143   public void accept(JVMInstructionVisitor insVisitor) {
144           insVisitor.visit(this);
145   }
146 }