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 }