1 cananian 1.1.2.1  // Method.java, created Mon Dec 28 01:31:03 1998 by cananian
  2 cananian 1.1.2.12 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.12 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1  package harpoon.Interpret.Quads;
  5 cananian 1.1.2.1  
  6 cananian 1.1.2.5  import harpoon.ClassFile.HClass;
  7 cananian 1.1.2.5  import harpoon.ClassFile.HCode;
  8 cananian 1.1.2.5  import harpoon.ClassFile.HCodeFactory;
  9 cananian 1.1.2.9  import harpoon.ClassFile.HField;
 10 cananian 1.1.2.9  import harpoon.ClassFile.HMember;
 11 cananian 1.1.2.5  import harpoon.ClassFile.HMethod;
 12 cananian 1.1.2.18 import harpoon.ClassFile.Linker;
 13 cananian 1.1.2.5  import harpoon.IR.Quads.Quad;
 14 cananian 1.1.2.23 import harpoon.IR.Quads.QuadRSSx;
 15 cananian 1.1.2.23 import harpoon.IR.Quads.QuadSSA;
 16 cananian 1.1.2.14 import harpoon.IR.Quads.QuadSSI;
 17 cananian 1.1.2.5  import harpoon.IR.Quads.QuadNoSSA;
 18 cananian 1.1.2.5  import harpoon.IR.Quads.QuadWithTry;
 19 cananian 1.1.2.5  import harpoon.IR.Quads.QuadVisitor;
 20 cananian 1.1.2.5  import harpoon.IR.Quads.AGET;
 21 cananian 1.1.2.5  import harpoon.IR.Quads.ANEW;
 22 cananian 1.1.2.5  import harpoon.IR.Quads.ALENGTH;
 23 cananian 1.1.2.5  import harpoon.IR.Quads.ARRAYINIT;
 24 cananian 1.1.2.5  import harpoon.IR.Quads.ASET;
 25 cananian 1.1.2.5  import harpoon.IR.Quads.CALL;
 26 cananian 1.1.2.5  import harpoon.IR.Quads.CJMP;
 27 cananian 1.1.2.5  import harpoon.IR.Quads.COMPONENTOF;
 28 cananian 1.1.2.5  import harpoon.IR.Quads.CONST;
 29 cananian 1.1.2.5  import harpoon.IR.Quads.DEBUG;
 30 cananian 1.1.2.5  import harpoon.IR.Quads.GET;
 31 cananian 1.1.2.5  import harpoon.IR.Quads.FOOTER;
 32 cananian 1.1.2.5  import harpoon.IR.Quads.HANDLER;
 33 cananian 1.1.2.5  import harpoon.IR.Quads.HEADER;
 34 cananian 1.1.2.5  import harpoon.IR.Quads.INSTANCEOF;
 35 cananian 1.1.2.5  import harpoon.IR.Quads.LABEL;
 36 cananian 1.1.2.5  import harpoon.IR.Quads.METHOD;
 37 cananian 1.1.2.5  import harpoon.IR.Quads.MONITORENTER;
 38 cananian 1.1.2.5  import harpoon.IR.Quads.MONITOREXIT;
 39 cananian 1.1.2.5  import harpoon.IR.Quads.MOVE;
 40 cananian 1.1.2.5  import harpoon.IR.Quads.NEW;
 41 cananian 1.1.2.5  import harpoon.IR.Quads.NOP;
 42 cananian 1.1.2.5  import harpoon.IR.Quads.OPER;
 43 cananian 1.1.2.5  import harpoon.IR.Quads.PHI;
 44 cananian 1.1.2.5  import harpoon.IR.Quads.RETURN;
 45 cananian 1.1.2.5  import harpoon.IR.Quads.SET;
 46 cananian 1.1.2.5  import harpoon.IR.Quads.SIGMA;
 47 cananian 1.1.2.5  import harpoon.IR.Quads.SWITCH;
 48 cananian 1.1.2.5  import harpoon.IR.Quads.THROW;
 49 cananian 1.1.2.5  import harpoon.IR.Quads.TYPECAST;
 50 cananian 1.1.2.20 import harpoon.IR.Quads.TYPESWITCH;
 51 cananian 1.1.2.5  import harpoon.IR.Quads.Edge;
 52 cananian 1.1.2.5  import harpoon.IR.Quads.HandlerSet;
 53 cananian 1.1.2.5  import harpoon.IR.Quads.Qop;
 54 cananian 1.1.2.1  import harpoon.Temp.Temp;
 55 cananian 1.1.2.1  import harpoon.Util.Util;
 56 cananian 1.1.2.1  
 57 cananian 1.1.2.1  import java.lang.reflect.Modifier;
 58 cananian 1.1.2.1  import java.io.PrintWriter;
 59 cananian 1.1.2.2  import java.util.Enumeration;
 60 cananian 1.1.2.1  /**
 61 cananian 1.1.2.10  * <code>Method</code> interprets method code in quad form.
 62 cananian 1.1.2.1   * 
 63 cananian 1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 64 cananian 1.4       * @version $Id: Method.java,v 1.4 2002/04/10 03:05:50 cananian Exp $
 65 cananian 1.1.2.1   */
 66 cananian 1.1.2.18 public final class Method {
 67 cananian 1.1.2.1  
 68 cananian 1.1.2.13     /** Write a start-up static state to disk. */
 69 cananian 1.1.2.18     public static final void makeStartup(Linker linker, HCodeFactory hcf,
 70 cananian 1.1.2.24                                          java.io.OutputStream os,
 71 cananian 1.1.2.24                                          boolean trace)
 72 cananian 1.1.2.13         throws java.io.IOException {
 73 cananian 1.1.2.18         StaticState ss = new StaticState(linker, hcf);
 74 cananian 1.1.2.24         ss.TRACE = trace;
 75 cananian 1.1.2.13         try {
 76 cananian 1.1.2.18             HMethod HMinit =
 77 cananian 1.1.2.18                 ss.HCsystem.getMethod("initializeSystemClass", "()V");
 78 cananian 1.1.2.13             // set up static state.
 79 cananian 1.1.2.18             ss.load(ss.HCsystem);
 80 cananian 1.1.2.13             invoke(ss, HMinit, new Object[0]);
 81 cananian 1.1.2.24             if (ss.TRACE)
 82 cananian 1.1.2.13             System.err.println("Writing.");
 83 cananian 1.1.2.13             java.io.ObjectOutputStream oos=new java.io.ObjectOutputStream(os);
 84 cananian 1.1.2.13             oos.writeObject(ss);
 85 cananian 1.1.2.13             oos.close();
 86 cananian 1.1.2.13         } catch (InterpretedThrowable it) { prettyPrint(ss, it); }
 87 cananian 1.1.2.13     }
 88 cananian 1.1.2.13 
 89 cananian 1.1.2.13     /** invoke a static main method, using a static state loaded from disk. */
 90 cananian 1.1.2.13     public static final void run(PrintWriter prof, HCodeFactory hcf,
 91 cananian 1.1.2.13                                  HClass cls, String[] args,
 92 cananian 1.1.2.24                                  java.io.InputStream is, boolean trace)
 93 cananian 1.1.2.13         throws java.io.IOException {
 94 cananian 1.1.2.13         StaticState ss;
 95 cananian 1.1.2.13         try {
 96 cananian 1.1.2.13             System.err.println("Reading.");
 97 cananian 1.1.2.13             java.io.ObjectInputStream ois = new java.io.ObjectInputStream(is);
 98 cananian 1.1.2.13             ss = (StaticState) ois.readObject();
 99 cananian 1.1.2.13             ss.prof = prof;
100 cananian 1.1.2.13             ss.hcf = hcf;
101 cananian 1.1.2.24             ss.TRACE = trace;
102 cananian 1.1.2.13             ois.close();
103 cananian 1.3.2.1              assert cls.getLinker()==ss.linker : "Saved static state uses incompatible linker";
104 cananian 1.1.2.13         } catch (ClassNotFoundException e) {
105 cananian 1.1.2.13             throw new java.io.IOException(e.toString());
106 cananian 1.1.2.13         } try {
107 cananian 1.1.2.13             run(ss, cls, args);
108 cananian 1.1.2.13         } catch (InterpretedThrowable it) { prettyPrint(ss, it); }
109 cananian 1.1.2.19         // if profiling, force gc and finalization.
110 cananian 1.1.2.19         if (ss.prof!=null) {
111 cananian 1.1.2.19             ss=null; System.gc(); System.runFinalization();
112 cananian 1.1.2.19         }
113 cananian 1.1.2.13     }
114 cananian 1.1.2.13 
115 cananian 1.1.2.1      /** invoke a static main method with no static state. */
116 cananian 1.1.2.3      public static final void run(PrintWriter prof, HCodeFactory hcf,
117 cananian 1.1.2.24                                  HClass cls, String[] args, boolean trace) {
118 cananian 1.1.2.18         StaticState ss = new StaticState(cls.getLinker(), hcf, prof);
119 cananian 1.1.2.24         ss.TRACE = trace;
120 cananian 1.1.2.1          try {
121 cananian 1.1.2.18             HMethod HMinit =
122 cananian 1.1.2.18                 ss.HCsystem.getMethod("initializeSystemClass", "()V");
123 cananian 1.1.2.1              // set up static state.
124 cananian 1.1.2.18             ss.load(ss.HCsystem);
125 cananian 1.1.2.1              invoke(ss, HMinit, new Object[0]);
126 cananian 1.1.2.13             run(ss, cls, args);
127 cananian 1.1.2.13         } catch (InterpretedThrowable it) { prettyPrint(ss, it); }
128 cananian 1.1.2.19         // if profiling, force gc and finalization.
129 cananian 1.1.2.19         if (ss.prof!=null) {
130 cananian 1.1.2.19             ss=null; System.gc(); System.runFinalization();
131 cananian 1.1.2.19         }
132 cananian 1.1.2.13     }
133 cananian 1.1.2.13 
134 cananian 1.1.2.13     private static final void run(StaticState ss, HClass cls, String[] args)
135 cananian 1.1.2.13         throws InterpretedThrowable {
136 cananian 1.1.2.18         HMethod method=cls.getMethod("main", new HClass[]{ ss.HCstringA });
137 cananian 1.3.2.1          assert method.isStatic();
138 cananian 1.1.2.13         // encapsulate params properly.
139 cananian 1.1.2.18         ArrayRef params=new ArrayRef(ss,ss.HCstringA,new int[]{args.length});
140 cananian 1.1.2.13         for (int i=0; i<args.length; i++)
141 cananian 1.1.2.13             params.update(i, ss.makeString(args[i]));
142 cananian 1.1.2.13         // run main() method.
143 cananian 1.1.2.13         ss.load(cls);
144 cananian 1.1.2.13         invoke(ss, method, new Object[] { params } );
145 cananian 1.1.2.19         // if profiling, force gc and finalization.
146 cananian 1.1.2.19         if (ss.prof!=null) {
147 cananian 1.1.2.19             System.gc(); System.runFinalization();
148 cananian 1.1.2.19         }
149 cananian 1.1.2.13     }
150 cananian 1.1.2.13     private static void prettyPrint(StaticState ss, InterpretedThrowable it) {
151 cananian 1.1.2.13         String msg = it.ex.type.getName();
152 cananian 1.1.2.13         try {
153 cananian 1.1.2.13             HMethod hm = it.ex.type.getMethod("toString",new HClass[0]);
154 cananian 1.1.2.13             ObjectRef obj =(ObjectRef)invoke(ss, hm, new Object[]{it.ex});
155 cananian 1.1.2.13             msg = ss.ref2str(obj);
156 cananian 1.1.2.13         } catch (InterpretedThrowable it0) { /* do nothing */ }
157 cananian 1.1.2.13         PrintWriter err = new PrintWriter(System.err, true);
158 cananian 1.1.2.13         err.println("Caught "+msg);
159 cananian 1.1.2.13         //StaticState.printStackTrace(err, it.stackTrace);
160 cananian 1.1.2.13         StaticState.printStackTrace(err, (String[]) it.ex.getClosure());
161 cananian 1.1.2.1      }
162 cananian 1.1.2.1  
163 cananian 1.1.2.1      /** invoke the specified method.  void methods return null. */
164 cananian 1.1.2.1      static final Object invoke(StaticState ss, HMethod method, Object[] params)
165 cananian 1.1.2.1          throws InterpretedThrowable {
166 cananian 1.3.2.1          assert params.length == numParams(method);
167 cananian 1.1.2.1  
168 cananian 1.1.2.1          if (!ss.isLoaded(method.getDeclaringClass()))
169 cananian 1.1.2.1              ss.load(method.getDeclaringClass());
170 cananian 1.1.2.1  
171 cananian 1.1.2.3          long start_count = ss.getInstructionCount();
172 cananian 1.1.2.3          try { // pop stack, end profiling, etc.
173 cananian 1.1.2.7              // easy to verify that every path through try leaves
174 cananian 1.1.2.7              // *exactly one* frame on the stack.
175 cananian 1.1.2.7              ss.pushStack(new NativeStackFrame(method));
176 cananian 1.1.2.3  
177 cananian 1.1.2.3              NativeMethod nm = ss.findNative(method);
178 cananian 1.1.2.3              if (nm!=null) {
179 cananian 1.1.2.3                  //ss.incrementInstructionCount(); //native methods take 0 time
180 cananian 1.1.2.2                  return nm.invoke(ss, params);
181 cananian 1.1.2.2              }
182 cananian 1.1.2.3              // non-native, interpret.
183 cananian 1.1.2.3              HCode c = ss.hcf.convert(method);
184 cananian 1.1.2.3              if (c==null) {
185 cananian 1.1.2.18                 ObjectRef obj = ss.makeThrowable(ss.HCunsatisfiedlinkErr,
186 cananian 1.1.2.3                                                   "No definition for "+method);
187 cananian 1.1.2.3                  throw new InterpretedThrowable(obj, ss);
188 cananian 1.1.2.3              }
189 cananian 1.1.2.3              QuadStackFrame sf = new QuadStackFrame((Quad)c.getRootElement());
190 cananian 1.1.2.7              ss.popStack(); // get rid of native stack frame
191 cananian 1.1.2.7              ss.pushStack(sf); // and replace with QuadStackFrame.
192 cananian 1.1.2.1  
193 cananian 1.1.2.3              Interpreter i;
194 cananian 1.1.2.3              if (c instanceof QuadWithTry)
195 cananian 1.1.2.3                  i = new ImplicitI(ss, sf, params);
196 cananian 1.1.2.23             else if (c instanceof QuadNoSSA || c instanceof QuadSSA ||
197 cananian 1.1.2.23                      c instanceof QuadRSSx || c instanceof QuadSSI)
198 cananian 1.1.2.3                  i = new ExplicitI(ss, sf, params);
199 cananian 1.1.2.3              else throw new Error("What kinda code is this!?");
200 cananian 1.1.2.3              
201 cananian 1.1.2.2          exec_loop:
202 cananian 1.1.2.3              while (!i.done)
203 cananian 1.1.2.3                  try {
204 cananian 1.1.2.15                     sf.pc.accept(i);
205 cananian 1.1.2.3                  } catch (InterpretedThrowable it) {
206 cananian 1.1.2.3                      // check HANDLERs
207 cananian 1.1.2.3                      for (Enumeration e=HandlerSet.elements(sf.pc.handlers());
208 cananian 1.1.2.3                           e.hasMoreElements(); ) {
209 cananian 1.1.2.3                          HANDLER h = (HANDLER) e.nextElement();
210 cananian 1.1.2.3                          if (h.isCaught(it.ex.type)) {
211 cananian 1.1.2.3                              i.advance(h, it.ex);
212 cananian 1.1.2.3                              continue exec_loop;
213 cananian 1.1.2.3                          }
214 cananian 1.1.2.2                      }
215 cananian 1.1.2.3                      // no handler caught it; rethrow.
216 cananian 1.1.2.24                     if (ss.TRACE)
217 cananian 1.1.2.3                      System.err.println("RETHROWING "+it.ex.type+" at "+
218 cananian 1.1.2.3                                         sf.pc.getSourceFile() + ":" +
219 cananian 1.1.2.3                                         sf.pc.getLineNumber());
220 cananian 1.1.2.3                      throw it;
221 cananian 1.1.2.2                  }
222 cananian 1.1.2.3          
223 cananian 1.1.2.3              // Return or throw.
224 cananian 1.1.2.3              if (i.Texc!=null) {
225 cananian 1.3.2.1                  assert sf.get(i.Texc)!=null : "Undefined throwable";
226 cananian 1.1.2.24                 if (ss.TRACE)
227 cananian 1.1.2.3                  System.err.println("THROWING " +
228 cananian 1.1.2.3                                     ((ObjectRef)sf.get(i.Texc)).type +
229 cananian 1.1.2.3                                     " at " + sf.pc.getSourceFile() + ":" +
230 cananian 1.1.2.3                                     sf.pc.getLineNumber());
231 cananian 1.1.2.3                  throw new InterpretedThrowable((ObjectRef)sf.get(i.Texc), ss);
232 cananian 1.1.2.2              }
233 cananian 1.1.2.3              if (method.getReturnType()==HClass.Void) return null;
234 cananian 1.1.2.3              return Interpreter.toExternal(sf.get(i.Tret),
235 cananian 1.1.2.3                                            method.getReturnType());
236 cananian 1.1.2.3          } finally { // pop stack & profile *always.*
237 cananian 1.1.2.3              ss.popStack();
238 cananian 1.1.2.3              long end_count = ss.getInstructionCount();
239 cananian 1.1.2.3              ss.profile(method, start_count, end_count);
240 cananian 1.1.2.3          }
241 cananian 1.1.2.1      }
242 cananian 1.1.2.1      private static int numParams(HMethod m) {
243 cananian 1.1.2.1          return m.getParameterTypes().length + (m.isStatic()?0:1);
244 cananian 1.1.2.1      }
245 cananian 1.1.2.1  
246 cananian 1.1.2.1      // interpreter superclass.
247 cananian 1.1.2.1      static private abstract class Interpreter extends QuadVisitor {
248 cananian 1.1.2.1          final StaticState ss;
249 cananian 1.1.2.1          final QuadStackFrame sf;
250 cananian 1.1.2.1          final Object[] params;
251 cananian 1.1.2.1          Temp Tret = null;
252 cananian 1.1.2.1          Temp Texc = null;
253 cananian 1.1.2.1          boolean done = false;
254 cananian 1.1.2.1          Interpreter(StaticState ss, QuadStackFrame sf, Object[] params) { 
255 cananian 1.1.2.1              this.ss = ss; this.sf = sf; this.params = params;
256 cananian 1.1.2.1          }
257 cananian 1.1.2.2          // advance to a handler
258 cananian 1.1.2.2          void advance(HANDLER h, ObjectRef ex) {
259 cananian 1.1.2.2              Edge e = h.nextEdge(0);
260 cananian 1.1.2.2              sf.pc = (Quad) e.to();
261 cananian 1.1.2.2              last_pred = e.which_pred();
262 cananian 1.1.2.2              sf.update(h.exceptionTemp(), ex);
263 cananian 1.1.2.24             if (ss.TRACE)
264 cananian 1.1.2.3              System.err.println("HANDLING "+ex.type+" at "+
265 cananian 1.1.2.3                                 sf.pc.getSourceFile() + ":" +
266 cananian 1.1.2.3                                 sf.pc.getLineNumber());
267 cananian 1.1.2.2              ss.incrementInstructionCount();
268 cananian 1.1.2.2          }
269 cananian 1.1.2.2          // advance to a successor
270 cananian 1.1.2.1          void advance(int which_succ) {
271 cananian 1.1.2.1              Edge e = sf.pc.nextEdge(which_succ);
272 cananian 1.1.2.1              sf.pc = (Quad) e.to();
273 cananian 1.1.2.1              last_pred = e.which_pred();
274 cananian 1.1.2.2              ss.incrementInstructionCount();
275 cananian 1.1.2.1          }
276 cananian 1.1.2.1          int last_pred = 0;
277 cananian 1.1.2.1          //------------------------------------------
278 cananian 1.1.2.1          final static Object toInternal(Object external) {
279 cananian 1.1.2.1              if (external instanceof Byte ||
280 cananian 1.1.2.1                  external instanceof Short)
281 cananian 1.1.2.1                  return new Integer(((Number)external).intValue());
282 cananian 1.1.2.1              if (external instanceof Character)
283 cananian 1.1.2.1                  return new Integer((int)((Character)external).charValue());
284 cananian 1.1.2.1              if (external instanceof Boolean)
285 cananian 1.1.2.1                  return new Integer(((Boolean)external).booleanValue()?1:0);
286 cananian 1.1.2.1              return external;
287 cananian 1.1.2.1          }
288 cananian 1.1.2.1          final static Object toExternal(Object internal, HClass type) {
289 cananian 1.1.2.1              if (type == HClass.Byte)
290 cananian 1.1.2.1                  return new Byte((byte)((Integer)internal).intValue());
291 cananian 1.1.2.1              if (type == HClass.Short)
292 cananian 1.1.2.1                  return new Short((short)((Integer)internal).intValue());
293 cananian 1.1.2.1              if (type == HClass.Char)
294 cananian 1.1.2.1                  return new Character((char)((Integer)internal).intValue());
295 cananian 1.1.2.1              if (type == HClass.Boolean)
296 cananian 1.1.2.1                  return new Boolean(((Integer)internal).intValue()!=0);
297 cananian 1.1.2.1              return internal;
298 cananian 1.1.2.1          }
299 cananian 1.1.2.1      }
300 cananian 1.1.2.1      // Interpreter with explicit exception handling.
301 cananian 1.1.2.1      static private class ExplicitI extends Interpreter {
302 cananian 1.1.2.1          ExplicitI(StaticState ss, QuadStackFrame sf, Object[] params) {
303 cananian 1.1.2.1              super(ss, sf, params);
304 cananian 1.1.2.1          }
305 cananian 1.1.2.9  
306 cananian 1.1.2.9          /** Check access permissions on member, accessed from current frame.
307 cananian 1.1.2.9           *  The <code>objtype</code> parameter is <code>null</code> if the
308 cananian 1.1.2.9           *  access is to a static member. */
309 cananian 1.1.2.9          void scopeCheck(HMember hm, HClass objtype) 
310 cananian 1.1.2.9              throws InterpretedThrowable {
311 cananian 1.1.2.9              int m = hm.getModifiers();
312 cananian 1.1.2.9              HClass from = sf.getMethod().getDeclaringClass();
313 cananian 1.1.2.9              HClass to = hm.getDeclaringClass();
314 cananian 1.1.2.9              if (Modifier.isProtected(m)) { // protected
315 cananian 1.1.2.9                  // from JVM ref on invokevirtual: if method is protected, then
316 cananian 1.1.2.9                  // it must be either a member of the current class or a member
317 cananian 1.1.2.9                  // of a superclass of the current class, and the class of
318 cananian 1.1.2.9                  // objectref must be either the current class or a subclass of
319 cananian 1.1.2.9                  // the current class.
320 cananian 1.1.2.9                  if (to.isSuperclassOf(from) && 
321 cananian 1.1.2.9                      (objtype==null || from.isSuperclassOf(objtype)))
322 cananian 1.1.2.9                      return; // all clear.
323 cananian 1.1.2.9                  // classes in the same package as some superclass can call
324 cananian 1.1.2.9                  // protected stuff, too. yuck.
325 cananian 1.1.2.9                  for (HClass sc=to; sc!=null; sc=sc.getSuperclass()) {
326 cananian 1.1.2.9                      if (from.getPackage().equals(sc.getPackage()))
327 cananian 1.1.2.9                          return; // all clear.
328 cananian 1.1.2.9                  }
329 cananian 1.1.2.9              } else if (Modifier.isPrivate(m)) { // private
330 cananian 1.1.2.9                  // check for private class called from outside its class.
331 cananian 1.1.2.9                  if (to.equals(from) &&
332 cananian 1.1.2.9                      (objtype==null || from.isSuperclassOf(objtype)))
333 cananian 1.1.2.9                      return; // all clear.
334 cananian 1.1.2.9              } else if (Modifier.isPublic(m)) { // public
335 cananian 1.1.2.9                  return; // always safe.
336 cananian 1.1.2.9              } else { // package scope
337 cananian 1.1.2.9                  // check for package scope called from outside its package
338 cananian 1.1.2.9                  if (from.getPackage().equals(to.getPackage()))
339 cananian 1.1.2.9                      return; // all clear.
340 cananian 1.1.2.9              }
341 cananian 1.1.2.9              // aha! an illegal access.
342 cananian 1.1.2.9              String msg=((objtype==null)?"":(objtype.getName()+": ")) +
343 cananian 1.1.2.9                  hm.toString();
344 cananian 1.1.2.18             ObjectRef eor = ss.makeThrowable(ss.HCillegalaccessErr, msg);
345 cananian 1.1.2.9              throw new InterpretedThrowable(eor, ss);
346 cananian 1.1.2.9          }
347 cananian 1.1.2.9  
348 cananian 1.1.2.1          public void visit(Quad q) {
349 cananian 1.1.2.1              throw new Error("Hello? No defaults here.");
350 cananian 1.1.2.1          }
351 cananian 1.1.2.1  
352 cananian 1.1.2.1          public void visit(AGET q) {
353 cananian 1.1.2.1              ArrayRef af = (ArrayRef) sf.get(q.objectref());
354 cananian 1.1.2.1              Integer ind = (Integer) sf.get(q.index());
355 cananian 1.1.2.1              sf.update(q.dst(), toInternal(af.get(ind.intValue())));
356 cananian 1.1.2.1              advance(0);
357 cananian 1.1.2.1          }
358 cananian 1.1.2.1          public void visit(ALENGTH q) {
359 cananian 1.1.2.1              ArrayRef af = (ArrayRef) sf.get(q.objectref());
360 cananian 1.1.2.1              sf.update(q.dst(), new Integer(af.length()));
361 cananian 1.1.2.1              advance(0);
362 cananian 1.1.2.1          }
363 cananian 1.1.2.1          public void visit(ANEW q) {
364 cananian 1.1.2.1              int[] dims = new int[q.dimsLength()];
365 cananian 1.1.2.1              for (int i=0; i<dims.length; i++)
366 cananian 1.1.2.1                  dims[i] = ((Integer)sf.get(q.dims(i))).intValue();
367 cananian 1.1.2.1              ArrayRef af = new ArrayRef(ss, q.hclass(), dims);
368 cananian 1.1.2.1              sf.update(q.dst(), af);
369 cananian 1.1.2.1              advance(0);
370 cananian 1.1.2.1          }
371 cananian 1.1.2.1          public void visit(ARRAYINIT q) {
372 cananian 1.1.2.1              ArrayRef af = (ArrayRef) sf.get(q.objectref());
373 cananian 1.1.2.1              Object[] v = q.value();
374 cananian 1.1.2.1              for (int i=0; i<v.length; i++)
375 cananian 1.1.2.1                  af.update(q.offset()+i,
376 cananian 1.1.2.18                           (q.type()!=ss.HCstring) ? v[i] :
377 cananian 1.1.2.1                            ss.makeStringIntern((String)v[i]));
378 cananian 1.1.2.1              advance(0);
379 cananian 1.1.2.1          }
380 cananian 1.1.2.1          public void visit(ASET q) {
381 cananian 1.1.2.1              ArrayRef af = (ArrayRef) sf.get(q.objectref());
382 cananian 1.1.2.1              Integer ind = (Integer) sf.get(q.index());
383 cananian 1.1.2.1              af.update(ind.intValue(),
384 cananian 1.1.2.1                        toExternal(sf.get(q.src()), af.type.getComponentType()));
385 cananian 1.1.2.1              advance(0);
386 cananian 1.1.2.1          }
387 cananian 1.1.2.1          public void visit(CALL q) {
388 cananian 1.1.2.1              Object[] params = new Object[q.paramsLength()];
389 cananian 1.1.2.1              for (int i=0; i<params.length; i++)
390 cananian 1.1.2.1                  params[i] = toExternal(sf.get(q.params(i)),q.paramType(i));
391 cananian 1.1.2.1              HMethod hm = q.method();
392 cananian 1.1.2.1              if (!q.isStatic() && q.isVirtual()) { // do virtual dispatch
393 cananian 1.1.2.6                  Ref obj = (Ref) params[0];
394 cananian 1.1.2.9                  try {
395 cananian 1.1.2.9                      hm = obj.type.getMethod(hm.getName(), hm.getDescriptor());
396 cananian 1.1.2.9                  } catch (NoSuchMethodError ex) {
397 cananian 1.1.2.9                      // duplicate java error message
398 cananian 1.1.2.9                      String msg = obj.type.getName()+": method "+
399 cananian 1.1.2.9                          hm.getName() + hm.getDescriptor() +" not found";
400 cananian 1.1.2.18                     ObjectRef eor = ss.makeThrowable(ss.HCnosuchmethodErr,msg);
401 cananian 1.1.2.9                      throw new InterpretedThrowable(eor, ss);
402 cananian 1.1.2.9                  }
403 cananian 1.1.2.9                  scopeCheck(hm, obj.type); // check virtual access perms
404 cananian 1.1.2.9              } else
405 cananian 1.1.2.9                  scopeCheck(hm, null); // check static access perms
406 cananian 1.1.2.9  
407 cananian 1.1.2.1              try {
408 cananian 1.1.2.1                  Object retval = toInternal(invoke(ss, hm, params));
409 cananian 1.1.2.4                  if (q.retval()!=null) sf.update(q.retval(), retval);
410 cananian 1.1.2.22                 if (q.retex()!=null && q.retval()!=q.retex())
411 cananian 1.1.2.22                     sf.undefine(q.retex()); // debugging support: "define both"
412 cananian 1.1.2.16                 visit((SIGMA)q, 0); // normal execution along 0 branch
413 cananian 1.1.2.1              } catch (InterpretedThrowable it) {
414 cananian 1.1.2.22                 if (q.retval()!=null && q.retval()!=q.retex())
415 cananian 1.1.2.22                     sf.undefine(q.retval());// debugging support: "define both"
416 cananian 1.1.2.4                  if (q.retex()!=null)  sf.update(q.retex(), it.ex);
417 cananian 1.1.2.4                  else throw it; // concession to expediency.
418 cananian 1.1.2.16                 visit((SIGMA)q, 1); // exeception; proceed along 1 branch
419 cananian 1.1.2.1              }
420 cananian 1.1.2.1          }
421 cananian 1.1.2.1          public void visit(CJMP q) {
422 cananian 1.1.2.17             Integer b = (Integer) sf.get(q.test());
423 cananian 1.1.2.17             if (b.intValue()!=0) // true branch.
424 cananian 1.1.2.1                  visit((SIGMA)q, 1);
425 cananian 1.1.2.1              else
426 cananian 1.1.2.1                  visit((SIGMA)q, 0);
427 cananian 1.1.2.1          }
428 cananian 1.1.2.1          public void visit(COMPONENTOF q) {
429 cananian 1.1.2.1              ArrayRef arr = (ArrayRef) sf.get(q.arrayref());
430 cananian 1.3.2.1              assert !arr.type.getComponentType().isPrimitive();
431 cananian 1.1.2.17             Ref obj = (Ref) sf.get(q.objectref());
432 cananian 1.3.2.1              assert obj!=null;
433 cananian 1.1.2.17             if (obj.type.isInstanceOf(arr.type.getComponentType()))
434 cananian 1.1.2.17                 sf.update(q.dst(), new Integer(1));
435 cananian 1.1.2.17             else
436 cananian 1.1.2.17                 sf.update(q.dst(), new Integer(0));
437 cananian 1.1.2.1              advance(0);
438 cananian 1.1.2.1          }
439 cananian 1.1.2.1          public void visit(CONST q) {
440 cananian 1.1.2.25             if (q.type()==ss.HCstring) {
441 cananian 1.1.2.1                  ObjectRef obj=ss.makeStringIntern((String)q.value());
442 cananian 1.1.2.1                  sf.update(q.dst(), obj);
443 cananian 1.1.2.25             } else if (q.type()==ss.HCclass) {
444 cananian 1.1.2.25                 ObjectRef obj=INClass.forClass(ss, (HClass)q.value());
445 cananian 1.1.2.25                 sf.update(q.dst(), obj);
446 cananian 1.1.2.25             } else if (!q.type().isPrimitive()) {
447 cananian 1.3.2.1                  assert false : "CONST type not (yet) supported: "+q.type();
448 cananian 1.1.2.25             } else
449 cananian 1.1.2.25                 sf.update(q.dst(), toInternal(q.value()));
450 cananian 1.1.2.1              advance(0);
451 cananian 1.1.2.1          }
452 cananian 1.1.2.1          public void visit(DEBUG q) {
453 cananian 1.1.2.24             if (ss.TRACE)
454 cananian 1.1.2.1              System.err.println(q.str());
455 cananian 1.1.2.1              advance(0);
456 cananian 1.1.2.1          }
457 cananian 1.1.2.1          public void visit(FOOTER q) {
458 cananian 1.1.2.1              throw new Error("Didn't stop!");
459 cananian 1.1.2.1          }
460 cananian 1.1.2.1          public void visit(GET q) {
461 cananian 1.1.2.9              HField hf = q.field();
462 cananian 1.1.2.1              if (q.objectref()==null) { // static
463 cananian 1.1.2.9                  scopeCheck(hf, null); // check static access perms
464 cananian 1.1.2.9                  sf.update(q.dst(), toInternal(ss.get(hf)));
465 cananian 1.1.2.1              } else { // non-static
466 cananian 1.1.2.6                  Ref obj = (Ref) sf.get(q.objectref());//arrays have fields too
467 cananian 1.1.2.9                  scopeCheck(hf, obj.type); // check virtual access perms.
468 cananian 1.1.2.9                  sf.update(q.dst(), toInternal(obj.get(hf)));
469 cananian 1.1.2.1              }
470 cananian 1.1.2.1              advance(0);
471 cananian 1.1.2.1          }
472 cananian 1.1.2.1          public void visit(HEADER q) {
473 cananian 1.1.2.1              advance(1); // towards METHOD.
474 cananian 1.1.2.1          }
475 cananian 1.1.2.1          public void visit(INSTANCEOF q) {
476 cananian 1.1.2.6              Ref obj = (Ref) sf.get(q.src());
477 cananian 1.3.2.1              assert obj!=null;// (null instanceof ...) not allowed
478 cananian 1.1.2.17             if (obj.type.isInstanceOf(q.hclass())) // true.
479 cananian 1.1.2.17                 sf.update(q.dst(), new Integer(1));
480 cananian 1.1.2.17             else
481 cananian 1.1.2.17                 sf.update(q.dst(), new Integer(0));
482 cananian 1.1.2.1              advance(0);
483 cananian 1.1.2.1          }
484 cananian 1.1.2.1          public void visit(LABEL q) {
485 cananian 1.1.2.1              visit((PHI)q);
486 cananian 1.1.2.1          }
487 cananian 1.1.2.1          public void visit(HANDLER q) {
488 cananian 1.1.2.1              throw new Error("HANDLERs cannot be directly executed!");
489 cananian 1.1.2.1          }
490 cananian 1.1.2.1          public void visit(METHOD q) {
491 cananian 1.1.2.1              for (int i=0; i<q.paramsLength(); i++)
492 cananian 1.1.2.1                  sf.update(q.params(i), toInternal(this.params[i]));
493 cananian 1.1.2.1              advance(0); // towards code, not handlers.
494 cananian 1.1.2.1          }
495 cananian 1.1.2.1          public void visit(MONITORENTER q) {
496 cananian 1.1.2.6              Ref obj = (Ref) sf.get(q.lock());
497 cananian 1.1.2.1              obj.lock();
498 cananian 1.1.2.1              advance(0);
499 cananian 1.1.2.1          }
500 cananian 1.1.2.1          public void visit(MONITOREXIT q) {
501 cananian 1.1.2.6              Ref obj = (Ref) sf.get(q.lock());
502 cananian 1.1.2.1              obj.unlock();
503 cananian 1.1.2.1              advance(0);
504 cananian 1.1.2.1          }           
505 cananian 1.1.2.1          public void visit(MOVE q) {
506 cananian 1.1.2.1              sf.update(q.dst(), sf.get(q.src()));
507 cananian 1.1.2.1              advance(0);
508 cananian 1.1.2.1          }
509 cananian 1.1.2.1          public void visit(NEW q) {
510 cananian 1.1.2.1              ObjectRef obj = new ObjectRef(ss, q.hclass());
511 cananian 1.1.2.1              sf.update(q.dst(), obj);
512 cananian 1.1.2.1              advance(0);
513 cananian 1.1.2.1          }
514 cananian 1.1.2.1          public void visit(NOP q) {
515 cananian 1.1.2.1              advance(0);
516 cananian 1.1.2.1          }
517 cananian 1.1.2.1          public void visit(OPER q) {
518 cananian 1.1.2.1              Object op[] = new Object[q.operandsLength()];
519 cananian 1.1.2.1              for (int i=0; i<op.length; i++)
520 cananian 1.1.2.1                  op[i] = sf.get(q.operands(i));
521 cananian 1.1.2.17             sf.update(q.dst(), toInternal(q.evalValue(op)));
522 cananian 1.1.2.1              advance(0);
523 cananian 1.1.2.1          }
524 cananian 1.1.2.1          public void visit(PHI q) {
525 cananian 1.1.2.1              // uses last pred info.
526 cananian 1.1.2.23             // Careful not to destroy sources until we've read them all!
527 cananian 1.1.2.23             // (dst and sources may conflict)
528 cananian 1.1.2.23             Object[] srcval = new Object[q.numPhis()];
529 cananian 1.1.2.1              for (int i=0; i<q.numPhis(); i++)
530 cananian 1.1.2.23                 srcval[i] = sf.get(q.src(i, last_pred));
531 cananian 1.1.2.23             for (int i=0; i<q.numPhis(); i++)
532 cananian 1.1.2.23                 sf.update(q.dst(i), srcval[i]);
533 cananian 1.1.2.1              advance(0);
534 cananian 1.1.2.1          }
535 cananian 1.1.2.1          public void visit(RETURN q) {
536 cananian 1.1.2.1              Tret = q.retval();
537 cananian 1.1.2.1              done = true;
538 cananian 1.1.2.1              advance(0); // may as well.
539 cananian 1.1.2.1          }
540 cananian 1.1.2.1          public void visit(SET q) {
541 cananian 1.1.2.9              HField hf = q.field();
542 cananian 1.1.2.1              Object src = sf.get(q.src());
543 cananian 1.1.2.1              if (q.objectref()==null) { // static
544 cananian 1.1.2.9                  scopeCheck(hf, null); // check static access perms.
545 cananian 1.1.2.9                  ss.update(hf, toExternal(src, hf.getType()));
546 cananian 1.1.2.1              } else { // non-static
547 cananian 1.1.2.1                  ObjectRef obj = (ObjectRef) sf.get(q.objectref());
548 cananian 1.1.2.9                  scopeCheck(hf, obj.type); // check virtual access perms
549 cananian 1.1.2.9                  obj.update(hf, toExternal(src, hf.getType()) );
550 cananian 1.1.2.1              }
551 cananian 1.1.2.1              advance(0);
552 cananian 1.1.2.1          }
553 cananian 1.1.2.1          public void visit(SIGMA q, int which_succ) {
554 cananian 1.1.2.1              for (int i=0; i<q.numSigmas(); i++)
555 cananian 1.1.2.1                  sf.update(q.dst(i, which_succ), sf.get(q.src(i)));
556 cananian 1.1.2.1              advance(which_succ);
557 cananian 1.1.2.1          }
558 cananian 1.1.2.1          public void visit(SWITCH q) {
559 cananian 1.1.2.1              Integer ind = (Integer) sf.get(q.index());
560 cananian 1.1.2.1              int match;
561 cananian 1.1.2.1              for (match=0; match<q.keysLength(); match++)
562 cananian 1.1.2.1                  if (ind.intValue() == q.keys(match)) break;
563 cananian 1.1.2.1              visit((SIGMA)q, match);
564 cananian 1.1.2.1          }
565 cananian 1.1.2.1          public void visit(THROW q) {
566 cananian 1.1.2.1              Texc = q.throwable();
567 cananian 1.1.2.1              done = true;
568 cananian 1.1.2.2              // don't advance: we want to preserve the stack state
569 cananian 1.1.2.2              // for line number info.
570 cananian 1.1.2.2          }
571 cananian 1.1.2.3          public void visit(TYPECAST q) { // typecast is nop in explicit form.
572 cananian 1.1.2.3              advance(0);
573 cananian 1.1.2.3          }
574 cananian 1.1.2.20         public void visit(TYPESWITCH q) {
575 cananian 1.1.2.20             Ref ind = (Ref) sf.get(q.index());
576 cananian 1.3.2.1              assert ind!=null; // null index not allowed.
577 cananian 1.1.2.20             int match;
578 cananian 1.1.2.20             for (match=0; match<q.keysLength(); match++)
579 cananian 1.1.2.20                 if (ind.type.isInstanceOf(q.keys(match))) break;
580 cananian 1.3.2.1              assert match < q.arity() : "no-default TYPESWITCH has no match";
581 cananian 1.1.2.20             visit((SIGMA)q, match);
582 cananian 1.1.2.20         }
583 cananian 1.1.2.2      }
584 cananian 1.1.2.2      // Interpreter with *implicit* exception handling.
585 cananian 1.1.2.2      static private class ImplicitI extends ExplicitI {
586 cananian 1.1.2.2          ImplicitI(StaticState ss, QuadStackFrame sf, Object[] params) {
587 cananian 1.1.2.2              super(ss, sf, params);
588 cananian 1.1.2.2          }
589 cananian 1.1.2.2          
590 cananian 1.1.2.3          void typeCheck(Temp src, HClass cls) throws InterpretedThrowable {
591 cananian 1.1.2.6              Ref of = (Ref) sf.get(src);
592 cananian 1.1.2.3              if (of==null || of.type.isInstanceOf(cls))
593 cananian 1.1.2.3                  return; // no problems.
594 cananian 1.1.2.8              String msg = // of.type.toString(); // for orthodoxy.
595 cananian 1.1.2.8                  "[is: "+of.type.toString()+"] "+ // for debugging
596 cananian 1.1.2.8                  "[supposed to be: "+cls.toString()+"]"; // for debugging
597 cananian 1.1.2.18             ObjectRef obj = ss.makeThrowable(ss.HCclasscastE, msg);
598 cananian 1.1.2.3              throw new InterpretedThrowable(obj, ss);
599 cananian 1.1.2.3          }
600 cananian 1.1.2.2          void componentCheck(Temp array, Temp src) throws InterpretedThrowable {
601 cananian 1.1.2.2              ArrayRef af = (ArrayRef) sf.get(array);
602 cananian 1.1.2.2              HClass afCT = af.type.getComponentType();
603 cananian 1.1.2.2              if (afCT.isPrimitive()) return; // statically typed.
604 cananian 1.1.2.6              Ref of = (Ref) sf.get(src);
605 cananian 1.1.2.3              if (of == null || of.type.isInstanceOf(afCT))
606 cananian 1.1.2.3                  return; // yay, no problemos.
607 cananian 1.1.2.18             ObjectRef obj = ss.makeThrowable(ss.HCarraystoreE,
608 cananian 1.1.2.3                                               of.type.toString() + " -> " +
609 cananian 1.1.2.3                                               af.type.toString());
610 cananian 1.1.2.2              throw new InterpretedThrowable(obj, ss);
611 cananian 1.1.2.2          }
612 cananian 1.1.2.2          void boundsCheck(Temp array, Temp index) throws InterpretedThrowable {
613 cananian 1.1.2.2              boundsCheck(array, ((Integer)sf.get(index)).intValue());
614 cananian 1.1.2.2          }
615 cananian 1.1.2.2          void boundsCheck(Temp array, int index) throws InterpretedThrowable {
616 cananian 1.1.2.2              ArrayRef af = (ArrayRef) sf.get(array);
617 cananian 1.1.2.2              if (0 <= index && index < af.length()) return; // a-ok
618 cananian 1.1.2.18             ObjectRef obj = ss.makeThrowable(ss.HCarrayindexE, 
619 cananian 1.1.2.3                                               Integer.toString(index));
620 cananian 1.1.2.2              throw new InterpretedThrowable(obj, ss);
621 cananian 1.1.2.2          }
622 cananian 1.1.2.2          void nullCheck(Temp t) throws InterpretedThrowable {
623 cananian 1.1.2.2              if (sf.get(t)!=null) return; // all's well.
624 cananian 1.1.2.18             ObjectRef obj = ss.makeThrowable(ss.HCnullpointerE);
625 cananian 1.1.2.2              throw new InterpretedThrowable(obj, ss);
626 cananian 1.1.2.2          }
627 cananian 1.1.2.2          void minusCheck(Temp t) throws InterpretedThrowable {
628 cananian 1.1.2.2              int i = ((Integer)sf.get(t)).intValue();
629 cananian 1.1.2.2              if (i >= 0) return; // a-ok.
630 cananian 1.1.2.18             ObjectRef obj = ss.makeThrowable(ss.HCnegativearrayE,
631 cananian 1.1.2.3                                               Integer.toString(i));
632 cananian 1.1.2.2              throw new InterpretedThrowable(obj, ss);
633 cananian 1.1.2.2          }
634 cananian 1.1.2.2          void zeroCheck(Temp t) throws InterpretedThrowable {
635 cananian 1.1.2.2              long z = ((Number)sf.get(t)).longValue();
636 cananian 1.1.2.2              if (z != 0) return; // a-ok.
637 cananian 1.1.2.18             ObjectRef obj = ss.makeThrowable(ss.HCarithmeticE);
638 cananian 1.1.2.2              throw new InterpretedThrowable(obj, ss);
639 cananian 1.1.2.2          }
640 cananian 1.1.2.2  
641 cananian 1.1.2.2          public void visit(AGET q) {
642 cananian 1.1.2.2              nullCheck(q.objectref());
643 cananian 1.1.2.2              boundsCheck(q.objectref(), q.index());
644 cananian 1.1.2.2              super.visit(q);
645 cananian 1.1.2.2          }
646 cananian 1.1.2.2          public void visit(ALENGTH q) {
647 cananian 1.1.2.2              nullCheck(q.objectref());
648 cananian 1.1.2.2              super.visit(q);
649 cananian 1.1.2.2          }
650 cananian 1.1.2.2          public void visit(ANEW q) {
651 cananian 1.1.2.2              for (int i=0; i<q.dimsLength(); i++)
652 cananian 1.1.2.2                  minusCheck(q.dims(i));
653 cananian 1.1.2.2              super.visit(q);
654 cananian 1.1.2.2          }
655 cananian 1.1.2.2          public void visit(ARRAYINIT q) {
656 cananian 1.1.2.2              nullCheck(q.objectref());
657 cananian 1.1.2.2              ArrayRef af = (ArrayRef) sf.get(q.objectref());
658 cananian 1.1.2.2              Object[] v = q.value();
659 cananian 1.1.2.2              for (int i=0; i<v.length; i++) {
660 cananian 1.1.2.2                  boundsCheck(q.objectref(), q.offset() + i);
661 cananian 1.1.2.2                  af.update(q.offset()+i,
662 cananian 1.1.2.18                           (q.type()!=ss.HCstring) ? v[i] :
663 cananian 1.1.2.2                            ss.makeStringIntern((String)v[i]));
664 cananian 1.1.2.2              }
665 cananian 1.1.2.2              advance(0);
666 cananian 1.1.2.2          }
667 cananian 1.1.2.2          public void visit(ASET q) {
668 cananian 1.1.2.2              nullCheck(q.objectref());
669 cananian 1.1.2.2              boundsCheck(q.objectref(), q.index());
670 cananian 1.1.2.2              componentCheck(q.objectref(), q.src());
671 cananian 1.1.2.2              super.visit(q);
672 cananian 1.1.2.2          }
673 cananian 1.1.2.2          public void visit(CALL q) {
674 cananian 1.1.2.2              if (!q.isStatic()) nullCheck(q.params(0));
675 cananian 1.1.2.2              super.visit(q);
676 cananian 1.1.2.17         }
677 cananian 1.1.2.17         public void visit(COMPONENTOF q) {
678 cananian 1.1.2.17             // object may be null in implicit case.
679 cananian 1.1.2.17             Ref obj = (Ref) sf.get(q.objectref());
680 cananian 1.1.2.17             if (obj==null) {
681 cananian 1.1.2.17                 sf.update(q.dst(), new Integer(1));
682 cananian 1.1.2.17                 advance(0);
683 cananian 1.1.2.17             } else super.visit(q);
684 cananian 1.1.2.17         }
685 cananian 1.1.2.17         public void visit(INSTANCEOF q) {
686 cananian 1.1.2.17             // object may be null in implicit case.
687 cananian 1.1.2.17             Ref obj = (Ref) sf.get(q.src());
688 cananian 1.1.2.17             if (obj==null) {
689 cananian 1.1.2.17                 sf.update(q.dst(), new Integer(0));
690 cananian 1.1.2.17                 advance(0);
691 cananian 1.1.2.17             } else super.visit(q);
692 cananian 1.1.2.2          }
693 cananian 1.1.2.2          public void visit(GET q) {
694 cananian 1.1.2.2              if (!q.isStatic()) nullCheck(q.objectref());
695 cananian 1.1.2.2              super.visit(q);
696 cananian 1.1.2.2          }
697 cananian 1.1.2.2          public void visit(MONITORENTER q) {
698 cananian 1.1.2.2              nullCheck(q.lock());
699 cananian 1.1.2.2              super.visit(q);
700 cananian 1.1.2.2          }
701 cananian 1.1.2.2          public void visit(MONITOREXIT q) {
702 cananian 1.1.2.2              nullCheck(q.lock());
703 cananian 1.1.2.2              super.visit(q);
704 cananian 1.1.2.2          }
705 cananian 1.1.2.2          public void visit(OPER q) {
706 cananian 1.1.2.2              switch (q.opcode()) {
707 cananian 1.1.2.2              case Qop.LDIV: case Qop.LREM: case Qop.IDIV: case Qop.IREM:
708 cananian 1.1.2.2                  zeroCheck(q.operands(1));
709 cananian 1.1.2.2              default: break;
710 cananian 1.1.2.2              }
711 cananian 1.1.2.2              super.visit(q);
712 cananian 1.1.2.2          }
713 cananian 1.1.2.2          public void visit(SET q) {
714 cananian 1.1.2.2              if (!q.isStatic()) nullCheck(q.objectref());
715 cananian 1.1.2.2              super.visit(q);
716 cananian 1.1.2.2          }
717 cananian 1.1.2.2          public void visit(THROW q) {
718 cananian 1.1.2.2              nullCheck(q.throwable());
719 cananian 1.1.2.11             ObjectRef obj = (ObjectRef) sf.get(q.throwable());
720 cananian 1.1.2.11             throw new InterpretedThrowable(obj, ss); // transfer to handler.
721 cananian 1.1.2.3          }
722 cananian 1.1.2.3          public void visit(TYPECAST q) {
723 cananian 1.1.2.3              typeCheck(q.objectref(), q.hclass());
724 cananian 1.1.2.2              super.visit(q);
725 cananian 1.1.2.20         }
726 cananian 1.1.2.20         public void visit(TYPESWITCH q) {
727 cananian 1.1.2.20             // object may be null in implicit case
728 cananian 1.1.2.20             Ref obj = (Ref) sf.get(q.index());
729 cananian 1.1.2.20             if (obj==null) {
730 cananian 1.3.2.1                  assert q.hasDefault();
731 cananian 1.1.2.20                 advance(q.keysLength()); // take default branch
732 cananian 1.1.2.20             } else super.visit(q);
733 cananian 1.1.2.1          }
734 cananian 1.1.2.1      }
735 cananian 1.2      }