Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / jvm / bytecode / JVMArrayElementInstruction.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
19 package gov.nasa.jpf.jvm.bytecode;
20
21 import gov.nasa.jpf.vm.ElementInfo;
22 import gov.nasa.jpf.vm.ThreadInfo;
23 import gov.nasa.jpf.vm.bytecode.ArrayElementInstruction;
24
25 /**
26  * abstract class for operations that access elements of arrays
27  */
28 public abstract class JVMArrayElementInstruction extends  ArrayElementInstruction {
29   
30   protected int arrayRef;
31   protected int index; // the accessed element
32
33   // we cache these to avoid the need for executeInstruction() listening
34   // if attrs are processed in instructionExecuted()
35   protected Object arrayOperandAttr;
36   protected Object indexOperandAttr;
37   
38   // we need this to be abstract because of the LongArrayStore insns
39   @Override
40   abstract public int peekIndex (ThreadInfo ti);
41   abstract public int peekArrayRef (ThreadInfo ti);
42
43   abstract public Object peekIndexAttr (ThreadInfo ti);
44   abstract public Object peekArrayAttr (ThreadInfo ti);
45
46   public boolean isReferenceArray() {
47     return false;
48   }
49   
50   @Override
51   public ElementInfo getElementInfo (ThreadInfo ti){
52     if (isCompleted(ti)){
53       return ti.getElementInfo(arrayRef);
54     } else {
55       int ref = peekArrayRef(ti);
56       return ti.getElementInfo(arrayRef);
57     }
58   }
59   
60   /**
61    * only makes sense from an executeInstruction() or instructionExecuted() listener,
62    * it is undefined outside of insn exec notifications
63    */
64   public int getArrayRef (ThreadInfo ti){
65     if (ti.isPreExec()){
66       return peekArrayRef(ti);
67     } else {
68       return arrayRef;
69     }
70   }
71
72   public Object getArrayOperandAttr (ThreadInfo ti){
73     if (ti.isPreExec()) {
74       return peekArrayAttr(ti);
75     } else {
76       return arrayOperandAttr;
77     }
78   }
79
80   public Object getIndexOperandAttr (ThreadInfo ti){
81     if (ti.isPreExec()) {
82       return peekIndexAttr(ti);
83     } else {
84       return indexOperandAttr;
85     }
86   }
87
88
89   @Override
90   public ElementInfo peekArrayElementInfo (ThreadInfo ti){
91     int aref = getArrayRef(ti);
92     return ti.getElementInfo(aref);
93   }
94   
95   public int getIndex (ThreadInfo ti){
96     if (!isCompleted(ti)){
97       return peekIndex(ti);
98     } else {
99       return index;
100     }
101   }
102   
103   /**
104    * return size of array elements in stack words (long,double: 2, all other: 1)
105    * e.g. used to determine where the object reference is on the stack
106    * 
107    * should probably be abstract, but there are lots of subclasses and only LongArrayLoad/Store insns have different size
108    */
109   protected int getElementSize () {
110     return 1;
111   }
112   
113   @Override
114   public abstract boolean isRead();
115   
116 }