KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gov > nasa > jpf > jvm > bytecode > Instruction


1 //
2
// Copyright (C) 2005 United States Government as represented by the
3
// Administrator of the National Aeronautics and Space Administration
4
// (NASA). All Rights Reserved.
5
//
6
// This software is distributed under the NASA Open Source Agreement
7
// (NOSA), version 1.3. The NOSA has been approved by the Open Source
8
// Initiative. See the file NOSA-1.3-JPF at the top of the distribution
9
// directory tree for the complete NOSA document.
10
//
11
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
12
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
13
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
14
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
15
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
16
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
17
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
18
//
19
package gov.nasa.jpf.jvm.bytecode;
20
21 import gov.nasa.jpf.JPFException;
22 import gov.nasa.jpf.jvm.ClassInfo;
23 import gov.nasa.jpf.jvm.JVM;
24 import gov.nasa.jpf.jvm.KernelState;
25 import gov.nasa.jpf.jvm.MethodInfo;
26 import gov.nasa.jpf.jvm.SystemState;
27 import gov.nasa.jpf.jvm.ThreadInfo;
28 import gov.nasa.jpf.util.Debug;
29
30 import java.util.ArrayList JavaDoc;
31 import java.util.List JavaDoc;
32
33 import org.apache.bcel.classfile.ConstantPool;
34 import org.apache.bcel.generic.InstructionHandle;
35
36 /**
37  * common root of all JPF bytecode instruction classes
38  */

39 public abstract class Instruction {
40   protected static List JavaDoc Unimplemented = new ArrayList JavaDoc();
41   protected int position; // accumulated position (prev pos + prev bc-length)
42
protected int offset; // consecutive index of instruction
43

44   /**
45    * NOTE - this is the method this instruction belongs to!
46    * <2do> pcm - Seems nobody has noticed this gets shadowed all over the place
47    * by local vars with a different meaning (InvokeInstruction)
48    */

49   protected MethodInfo mi;
50   protected String JavaDoc asString;
51   protected boolean isObservable;
52
53   abstract public int getByteCode();
54   
55   // to allow a classname and methodname context for each instruction
56
public void setContext (String JavaDoc className, String JavaDoc methodName, int lineNumber,
57                           int offset) {
58   }
59
60   public boolean isFirstInstruction () {
61     return (offset == 0);
62   }
63   
64   /**
65    * answer if this is a potential loop closing jump
66    */

67   public boolean isBackJump () {
68     return false;
69   }
70   
71   public boolean isDeterministic (SystemState ss, KernelState ks, ThreadInfo ti) {
72     return true;
73   }
74
75   public boolean isExecutable (SystemState ss, KernelState ks, ThreadInfo th) {
76     return true;
77   }
78
79   public MethodInfo getMethod () {
80     return mi;
81   }
82
83   
84   public Instruction getNext () {
85     return mi.getInstruction(offset + 1);
86   }
87
88   public void setObservable () {
89     isObservable = true;
90   }
91
92   
93   public boolean isObservable () {
94     if (!isObservable) {
95       Instruction prev = getPrev();
96
97       if (prev != null) {
98         if (prev instanceof INVOKESTATIC) {
99           INVOKESTATIC invoke = (INVOKESTATIC) prev;
100           isObservable |= (invoke.cname.equals("gov.nasa.jpf.jvm.Verify") && invoke.mname.equals(
101                                                                                    "assertTrue(Z)V"));
102         }
103       }
104     }
105
106     return isObservable;
107   }
108
109   public int getOffset () {
110     return offset;
111   }
112
113   public int getPosition () {
114     return position;
115   }
116
117   public Instruction getPrev () {
118     if (offset > 0) {
119       return mi.getInstruction(offset - 1);
120     } else {
121       return null;
122     }
123   }
124
125   //SUNYSB
126
public boolean isVisible (SystemState ss, KernelState ks, ThreadInfo th) {
127     return false;
128   }
129
130   public boolean isSchedulingRelevant(SystemState ss, KernelState ks, ThreadInfo ti) {
131     return false;
132   }
133   
134   public abstract Instruction execute (SystemState ss, KernelState ks,
135                                        ThreadInfo th);
136
137   public static Instruction create (InstructionHandle h, int o, MethodInfo m,
138                                     ConstantPool cp) {
139     Instruction i = null;
140     String JavaDoc name = null;
141
142     try {
143       name = h.getInstruction().getClass().getName();
144
145       if (!name.startsWith("org.apache.bcel.generic.")) {
146         throw new JPFException("not a BCEL instruction type: " + name);
147       }
148
149       name = "gov.nasa.jpf.jvm.bytecode." + name.substring(24);
150       Class JavaDoc clazz = Class.forName(name);
151
152       i = (gov.nasa.jpf.jvm.bytecode.Instruction) clazz.newInstance();
153       i.init(h, o, m, cp);
154     } catch (ClassNotFoundException JavaDoc e) {
155       if (!Unimplemented.contains(name)) {
156         Unimplemented.add(name);
157         Debug.println(Debug.WARNING,
158                       "warning: unimplemented bytecode instruction: " +
159                       name.substring(34));
160       }
161     } catch (Exception JavaDoc e) {
162       e.printStackTrace();
163       throw new JPFException("creation of instruction " +
164                                        name.substring(34) + " failed");
165     }
166
167     return i;
168   }
169
170   public boolean Methodexamine (ThreadInfo th) {
171     return false; // default: next ins is not already covered method
172
}
173
174   public boolean examine (SystemState ss, KernelState ks, ThreadInfo th) {
175     return false;
176   }
177
178   public boolean examineAbstraction (SystemState ss, KernelState ks,
179                                      ThreadInfo th) {
180     return false;
181   }
182
183   public String JavaDoc toString () {
184     return asString;
185   }
186
187   public String JavaDoc getMnemonic () {
188     String JavaDoc s = getClass().getName();
189     return s.substring(26); // gov.nasa.jpf.jvm.bytecode package
190
}
191   
192   public String JavaDoc getSourceLocation () {
193     ClassInfo ci = mi.getClassInfo();
194     int line = mi.getLineNumber(this);
195     String JavaDoc file = ci.getSourceFileName();
196     
197     String JavaDoc s = ci.getName() + '.' + mi.getFullName() + " at ";
198     
199     if (file != null) {
200       s += file;
201       s += ':';
202       s += line;
203     } else {
204       s += "pc ";
205       s += position;
206     }
207     
208     return s;
209   }
210   
211   //SUNYSB
212
protected abstract void setPeer (org.apache.bcel.generic.Instruction i,
213                                    ConstantPool cp);
214
215   protected void init (InstructionHandle h, int o, MethodInfo m,
216                        ConstantPool cp) {
217     position = h.getPosition();
218     offset = o;
219     mi = m;
220     asString = h.getInstruction().toString(cp);
221     setPeer(h.getInstruction(), cp);
222     isObservable = JVM.observablePositions.contains(mi.getCompleteName() +
223                                                     ":" + position);
224   }
225
226   /**
227    * this is returning the next Instruction to execute, to be called after
228    * we executed ourselves.
229    *
230    * Be aware of that we might have had exceptions caused by our execution,
231    * i.e. we can't simply assume it's the next insn following us (we have to
232    * acquire the 'current' insn after our exec from the ThreadInfo).
233    *
234    * To make it even more interesting, the ThreadInfo might return null because
235    * we might have run into a System.exit, which purges all stacks.
236    * It's questionable if it's the right way to handle this by just returning
237    * our own successor, and rely on ThreadInfo.executeXXMethod to catch
238    * this, but it seems to be the smallest change
239    *
240    * <?> pcm - this is hackish control in case of System.exit
241    */

242   Instruction getNext (ThreadInfo th) {
243     Instruction insn = th.getPC();
244
245     if (insn == null) {
246       // could be all purged (System.exit)
247
insn = this;
248     }
249
250     return insn.getNext();
251   }
252 }
253
254
255
Popular Tags