Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / ArrayLoadInstruction.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.ArrayIndexOutOfBoundsExecutiveException;
21 import gov.nasa.jpf.vm.ElementInfo;
22 import gov.nasa.jpf.vm.Instruction;
23 import gov.nasa.jpf.vm.MJIEnv;
24 import gov.nasa.jpf.vm.Scheduler;
25 import gov.nasa.jpf.vm.StackFrame;
26 import gov.nasa.jpf.vm.ThreadInfo;
27
28
29 /**
30  * abstraction for all array load instructions
31  *
32  * ..., array, index => ..., value
33  */
34 public abstract class ArrayLoadInstruction extends JVMArrayElementInstruction implements JVMInstruction {
35   
36   @Override
37   public Instruction execute (ThreadInfo ti) {
38     StackFrame frame = ti.getModifiableTopFrame();
39
40     index = frame.peek();
41     arrayRef = frame.peek(1); // ..,arrayRef,idx
42     if (arrayRef == MJIEnv.NULL) {
43       return ti.createAndThrowException("java.lang.NullPointerException");
44     }
45     ElementInfo eiArray = ti.getElementInfo(arrayRef);
46
47     indexOperandAttr = peekIndexAttr(ti);
48     arrayOperandAttr = peekArrayAttr(ti);
49
50     Scheduler scheduler = ti.getScheduler();
51     if (scheduler.canHaveSharedArrayCG( ti, this, eiArray, index)){ // don't modify the frame before this
52       eiArray = scheduler.updateArraySharedness(ti, eiArray, index);
53       if (scheduler.setsSharedArrayCG( ti, this, eiArray, index)){
54         return this;
55       }
56     }
57     
58     frame.pop(2); // now we can pop index and array reference
59     
60     try {
61       push(frame, eiArray, index);
62
63       Object elementAttr = eiArray.getElementAttr(index);
64       if (elementAttr != null) {
65         if (getElementSize() == 1) {
66           frame.setOperandAttr(elementAttr);
67         } else {
68           frame.setLongOperandAttr(elementAttr);
69         }
70       }
71       
72       return getNext(ti);
73       
74     } catch (ArrayIndexOutOfBoundsExecutiveException ex) {
75       return ex.getInstruction();
76     }
77   }
78
79   protected boolean isReference () {
80     return false;
81   }
82
83   /**
84    * only makes sense pre-exec
85    */
86   @Override
87   public int peekArrayRef (ThreadInfo ti){
88     return ti.getTopFrame().peek(1);
89   }
90
91   @Override
92   public Object peekArrayAttr (ThreadInfo ti){
93     return ti.getTopFrame().getOperandAttr(1);
94   }
95
96   // wouldn't really be required for loads, but this is a general
97   // ArrayInstruction API
98   @Override
99   public int peekIndex (ThreadInfo ti){
100     return ti.getTopFrame().peek();
101   }
102
103   @Override
104   public Object peekIndexAttr (ThreadInfo ti){
105     return ti.getTopFrame().getOperandAttr();
106   }
107
108   protected abstract void push (StackFrame frame, ElementInfo e, int index)
109                 throws ArrayIndexOutOfBoundsExecutiveException;
110
111   
112   @Override
113   public boolean isRead() {
114     return true;
115   }
116   
117   @Override
118   public void accept(JVMInstructionVisitor insVisitor) {
119           insVisitor.visit(this);
120   }
121  }