Source code: Interpreter/BytecodeInterpreter.java
1 // BytecodeInterpreter.java, created Fri Aug 16 16:04:04 2002 by joewhaley
2 // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3 // Licensed under the terms of the GNU LGPL; see COPYING for details.
4 package Interpreter;
5
6 import Bootstrap.PrimordialClassLoader;
7 import Clazz.jq_Array;
8 import Clazz.jq_Class;
9 import Clazz.jq_InstanceField;
10 import Clazz.jq_InstanceMethod;
11 import Clazz.jq_Method;
12 import Clazz.jq_Primitive;
13 import Clazz.jq_Reference;
14 import Clazz.jq_StaticField;
15 import Clazz.jq_TryCatchBC;
16 import Clazz.jq_Type;
17 import Compil3r.BytecodeAnalysis.BytecodeVisitor;
18 import Memory.Address;
19 import Memory.HeapAddress;
20 import Run_Time.Reflection;
21 import Run_Time.Unsafe;
22 import Util.Assert;
23
24 /*
25 * @author John Whaley <jwhaley@alum.mit.edu>
26 * @version $Id: BytecodeInterpreter.java,v 1.10 2003/07/23 02:25:22 joewhaley Exp $
27 */
28 public abstract class BytecodeInterpreter {
29
30 public static /*final*/ boolean ALWAYS_TRACE = System.getProperty("interpreter.trace") != null;
31
32 /** Creates new Interpreter */
33 public BytecodeInterpreter(VMInterface vm, State state) {
34 this.vm = vm; this.state = state;
35 }
36
37 // create an Interpreter.State and call invokeMethod(m, state)
38 public abstract Object invokeMethod(jq_Method m) throws Throwable;
39 public abstract Object invokeUnsafeMethod(jq_Method m) throws Throwable;
40
41 // callee == null -> call compiled version
42 public Object invokeMethod(jq_Method m, State callee) throws Throwable {
43 //Run_Time.SystemInterface.debugwriteln("Invoking method "+m);
44 jq_Class k = m.getDeclaringClass();
45 Assert._assert(k.isClsInitialized());
46 Assert._assert(m.getBytecode() != null);
47 jq_Type[] paramTypes = m.getParamTypes();
48 Object[] params = new Object[paramTypes.length];
49 for (int i=paramTypes.length-1; i>=0; --i) {
50 jq_Type t = paramTypes[i];
51 if (t.isPrimitiveType()) {
52 if (t == jq_Primitive.LONG) {
53 params[i] = new Long(state.pop_L());
54 } else if (t == jq_Primitive.FLOAT) {
55 params[i] = new Float(state.pop_F());
56 } else if (t == jq_Primitive.DOUBLE) {
57 params[i] = new Double(state.pop_D());
58 } else {
59 params[i] = new Integer(state.pop_I());
60 }
61 } else {
62 params[i] = state.pop_A();
63 }
64 //System.out.println("Param "+i+": "+params[i]);
65 }
66 for (int i=0, j=0; i<paramTypes.length; ++i, ++j) {
67 jq_Type t = paramTypes[i];
68 if (t.isPrimitiveType()) {
69 if (t == jq_Primitive.LONG) {
70 long v = ((Long)params[i]).longValue();
71 if (callee == null) {
72 Unsafe.pushArg((int)(v>>32)); // hi
73 Unsafe.pushArg((int)v); // lo
74 } else callee.setLocal_L(j, v);
75 ++j;
76 } else if (t == jq_Primitive.FLOAT) {
77 float v = ((Float)params[i]).floatValue();
78 if (callee == null) {
79 Unsafe.pushArg(Float.floatToRawIntBits(v));
80 } else callee.setLocal_F(j, v);
81 } else if (t == jq_Primitive.DOUBLE) {
82 long v = Double.doubleToRawLongBits(((Double)params[i]).doubleValue());
83 if (callee == null) {
84 Unsafe.pushArg((int)(v>>32)); // hi
85 Unsafe.pushArg((int)v); // lo
86 } else callee.setLocal_D(j, Double.longBitsToDouble(v));
87 ++j;
88 } else {
89 int v = ((Integer)params[i]).intValue();
90 if (callee == null) {
91 Unsafe.pushArg(v);
92 } else callee.setLocal_I(j, v);
93 }
94 } else {
95 Object v = params[i];
96 if (callee == null) {
97 Unsafe.pushArgA(HeapAddress.addressOf(v));
98 } else callee.setLocal_A(j, v);
99 }
100 }
101 if (callee == null) {
102 jq_Type returnType = m.getReturnType();
103 if (returnType.isReferenceType()) {
104 Address result = Unsafe.invokeA(m.getDefaultCompiledVersion().getEntrypoint());
105 if (returnType.isAddressType()) return result;
106 return ((HeapAddress) result).asObject();
107 }
108 long result = Unsafe.invoke(m.getDefaultCompiledVersion().getEntrypoint());
109 if (returnType == jq_Primitive.VOID)
110 return null;
111 else if (returnType == jq_Primitive.LONG)
112 return new Long(result);
113 else if (returnType == jq_Primitive.FLOAT)
114 return new Float(Float.intBitsToFloat((int)(result)));
115 else if (returnType == jq_Primitive.DOUBLE)
116 return new Double(Double.longBitsToDouble(result));
117 else
118 return new Integer((int)(result));
119 } else {
120 State oldState = this.state;
121 this.state = callee;
122 MethodInterpreter mi = new MethodInterpreter(m);
123 Object synchobj = null;
124 try {
125 if (m.isSynchronized()) {
126 if (!m.isStatic()) {
127 if (mi.getTraceFlag()) mi.getTraceOut().println("synchronized instance method, locking 'this' object");
128 vm.monitorenter(synchobj = state.getLocal_A(0), mi);
129 } else {
130 if (mi.getTraceFlag()) mi.getTraceOut().println("synchronized static method, locking class object");
131 vm.monitorenter(synchobj = Reflection.getJDKType(m.getDeclaringClass()), mi);
132 }
133 }
134 mi.forwardTraversal();
135 this.state = oldState;
136 if (m.isSynchronized()) {
137 if (mi.getTraceFlag()) mi.getTraceOut().println("exiting synchronized method, unlocking object");
138 vm.monitorexit(synchobj);
139 }
140 jq_Type returnType = m.getReturnType();
141 Object retval;
142 if (returnType.isReferenceType()) {
143 retval = callee.getReturnVal_A();
144 } else if (returnType == jq_Primitive.VOID) {
145 retval = null;
146 } else if (returnType == jq_Primitive.LONG) {
147 retval = new Long(callee.getReturnVal_L());
148 } else if (returnType == jq_Primitive.FLOAT) {
149 retval = new Float(callee.getReturnVal_F());
150 } else if (returnType == jq_Primitive.DOUBLE) {
151 retval = new Double(callee.getReturnVal_D());
152 } else {
153 retval = new Integer(callee.getReturnVal_I());
154 }
155 if (mi.getTraceFlag())
156 mi.getTraceOut().println("Return value: "+retval);
157 return retval;
158 } catch (WrappedException ix) {
159 this.state = oldState;
160 if (m.isSynchronized()) {
161 if (mi.getTraceFlag()) mi.getTraceOut().println("exiting synchronized method, unlocking object");
162 vm.monitorexit(synchobj);
163 }
164 throw ix.t;
165 }
166 }
167 }
168 /*
169 int j = m.getParamWords();
170 int[] argVals = new int[j];
171 for (int i=paramTypes.length-1; i>=0; --i, --j) {
172 jq_Type t = paramTypes[i];
173 if (t.isPrimitiveType()) {
174 if (t == jq_Primitive.LONG) {
175 long v = state.pop_L();
176 argVals[ j] = (int)v; // lo
177 argVals[--j] = (int)(v>>32); // hi
178 } else if (t == jq_Primitive.FLOAT) {
179 argVals[j] = Float.floatToRawIntBits(state.pop_F());
180 } else if (t == jq_Primitive.DOUBLE) {
181 long v = Double.doubleToRawLongBits(state.pop_D());
182 argVals[ j] = (int)v; // lo
183 argVals[--j] = (int)(v>>32); // hi
184 } else {
185 argVals[j] = state.pop_I();
186 }
187 } else {
188 argVals[j] = Unsafe.addressOf(state.pop_A());
189 }
190 }
191 jq.Assert(j==0);
192 for (int i=0; i<argVals.length; ++i) {
193 if (callee == null) Unsafe.pushArg(argVals[i]);
194 else callee.push_I(argVals[i]);
195 }
196 if (callee == null) return Unsafe.invoke(m.getDefaultCompiledVersion().getEntrypoint());
197 else interpret(m, callee);
198 */
199
200 protected State state;
201 protected final VMInterface vm;
202
203 public abstract static class State {
204 public abstract void push_I(int v);
205 public abstract void push_L(long v);
206 public abstract void push_F(float v);
207 public abstract void push_D(double v);
208 public abstract void push_A(Object v);
209 public abstract void push(Object v);
210 public abstract int pop_I();
211 public abstract long pop_L();
212 public abstract float pop_F();
213 public abstract double pop_D();
214 public abstract Object pop_A();
215 public abstract Object pop();
216 public abstract void popAll();
217 public abstract Object peek_A(int depth);
218 public abstract void setLocal_I(int i, int v);
219 public abstract void setLocal_L(int i, long v);
220 public abstract void setLocal_F(int i, float v);
221 public abstract void setLocal_D(int i, double v);
222 public abstract void setLocal_A(int i, Object v);
223 public abstract int getLocal_I(int i);
224 public abstract long getLocal_L(int i);
225 public abstract float getLocal_F(int i);
226 public abstract double getLocal_D(int i);
227 public abstract Object getLocal_A(int i);
228 public abstract void return_I(int v);
229 public abstract void return_L(long v);
230 public abstract void return_F(float v);
231 public abstract void return_D(double v);
232 public abstract void return_A(Object v);
233 public abstract void return_V();
234 public abstract int getReturnVal_I();
235 public abstract long getReturnVal_L();
236 public abstract float getReturnVal_F();
237 public abstract double getReturnVal_D();
238 public abstract Object getReturnVal_A();
239 }
240
241 public abstract static class VMInterface {
242 public abstract Object new_obj(jq_Type t);
243 public abstract Object new_array(jq_Type t, int length);
244 public abstract Object checkcast(Object o, jq_Type t);
245 public abstract boolean instance_of(Object o, jq_Type t);
246 public abstract int arraylength(Object o);
247 public abstract void monitorenter(Object o, MethodInterpreter v);
248 public abstract void monitorexit(Object o);
249 public abstract Object multinewarray(int[] dims, jq_Type t);
250 }
251
252 public static class WrappedException extends RuntimeException {
253 Throwable t;
254 WrappedException(Throwable t) { this.t = t; }
255 public String toString() { return "WrappedException: "+t; }
256 }
257
258 class MethodInterpreter extends BytecodeVisitor {
259
260 MethodInterpreter(jq_Method method) {
261 super(method);
262 i_end = -1;
263 String s = method.getDeclaringClass().getName().toString();
264 int i = s.lastIndexOf('.');
265 name = s.substring(i+1)+"/"+method.getName();
266 TRACE = ALWAYS_TRACE;
267 out = System.err;
268 }
269
270 final String name;
271 public String toString() {
272 return name;
273 }
274
275 // Workaround for javac bug -> cannot access protected members of inner classes.
276 boolean getTraceFlag() { return TRACE; }
277 java.io.PrintStream getTraceOut() { return out; }
278
279 public void forwardTraversal() throws VerifyError, WrappedException {
280 if (this.TRACE) this.out.println(this+": Starting traversal.");
281 for (;;) {
282 i_start = i_end+1;
283 if (i_start >= bcs.length) break;
284 try {
285 super.visitBytecode();
286 } catch (WrappedException ix) {
287 if (this.TRACE) this.out.println(this+": Exception thrown! "+ix.t);
288 handleException(ix.t);
289 } catch (Throwable x) {
290 if (this.TRACE) this.out.println(this+": RuntimeException/Error thrown! "+x);
291 handleException(x);
292 }
293 }
294 if (this.TRACE) this.out.println(this+": Finished traversal.");
295 }
296
297 public void continueForwardTraversal() throws VerifyError, WrappedException, ReflectiveInterpreter.MonitorExit {
298 for (;;) {
299 i_start = i_end+1;
300 if (i_start >= bcs.length) break;
301 try {
302 super.visitBytecode();
303 } catch (ReflectiveInterpreter.MonitorExit x) {
304 throw x;
305 } catch (WrappedException ix) {
306 if (this.TRACE) this.out.println(this+": Exception thrown! "+ix.t);
307 handleException(ix.t);
308 } catch (Throwable x) {
309 if (this.TRACE) this.out.println(this+": RuntimeException/Error thrown! "+x);
310 handleException(x);
311 }
312 }
313 }
314
315 public void visitBytecode() throws WrappedException {
316 try {
317 super.visitBytecode();
318 } catch (WrappedException ix) {
319 if (this.TRACE) this.out.println(this+": Exception thrown! "+ix.t);
320 handleException(ix.t);
321 } catch (Throwable x) {
322 if (this.TRACE) this.out.println(this+": RuntimeException/Error thrown! "+x);
323 handleException(x);
324 }
325 }
326
327 private void handleException(Throwable x) throws WrappedException {
328 jq_Class t = (jq_Class)jq_Reference.getTypeOf(x);
329 t.prepare();
330 jq_TryCatchBC[] tc = method.getExceptionTable();
331 for (int i=0; i<tc.length; ++i) {
332 if (tc[i].catches(i_start, t)) {
333 state.popAll(); state.push_A(x);
334 branchTo(tc[i].getHandlerPC());
335 if (this.TRACE) this.out.println(this+": Branching to exception handler "+tc[i]);
336 return;
337 }
338 }
339 if (this.TRACE) this.out.println(this+": Uncaught exception, exiting method.");
340 throw new WrappedException(x);
341 }
342
343 protected void branchTo(int target) {
344 i_end = target-1;
345 }
346
347 public void visitNOP() {
348 super.visitNOP();
349 }
350 public void visitACONST(Object s) {
351 super.visitACONST(s);
352 state.push_A(s);
353 }
354 public void visitICONST(int c) {
355 super.visitICONST(c);
356 state.push_I(c);
357 }
358 public void visitLCONST(long c) {
359 super.visitLCONST(c);
360 state.push_L(c);
361 }
362 public void visitFCONST(float c) {
363 super.visitFCONST(c);
364 state.push_F(c);
365 }
366 public void visitDCONST(double c) {
367 super.visitDCONST(c);
368 state.push_D(c);
369 }
370 public void visitILOAD(int i) {
371 super.visitILOAD(i);
372 state.push_I(state.getLocal_I(i));
373 }
374 public void visitLLOAD(int i) {
375 super.visitLLOAD(i);
376 state.push_L(state.getLocal_L(i));
377 }
378 public void visitFLOAD(int i) {
379 super.visitFLOAD(i);
380 state.push_F(state.getLocal_F(i));
381 }
382 public void visitDLOAD(int i) {
383 super.visitDLOAD(i);
384 state.push_D(state.getLocal_D(i));
385 }
386 public void visitALOAD(int i) {
387 super.visitALOAD(i);
388 state.push_A(state.getLocal_A(i));
389 }
390 public void visitISTORE(int i) {
391 super.visitISTORE(i);
392 state.setLocal_I(i, state.pop_I());
393 }
394 public void visitLSTORE(int i) {
395 super.visitLSTORE(i);
396 state.setLocal_L(i, state.pop_L());
397 }
398 public void visitFSTORE(int i) {
399 super.visitFSTORE(i);
400 state.setLocal_F(i, state.pop_F());
401 }
402 public void visitDSTORE(int i) {
403 super.visitDSTORE(i);
404 state.setLocal_D(i, state.pop_D());
405 }
406 public void visitASTORE(int i) {
407 super.visitASTORE(i);
408 state.setLocal_A(i, state.pop_A());
409 }
410 public void visitIALOAD() {
411 super.visitIALOAD();
412 int index = state.pop_I();
413 int[] array = (int[])state.pop_A();
414 state.push_I(array[index]);
415 }
416 public void visitLALOAD() {
417 super.visitLALOAD();
418 int index = state.pop_I();
419 long[] array = (long[])state.pop_A();
420 state.push_L(array[index]);
421 }
422 public void visitFALOAD() {
423 super.visitFALOAD();
424 int index = state.pop_I();
425 float[] array = (float[])state.pop_A();
426 state.push_F(array[index]);
427 }
428 public void visitDALOAD() {
429 super.visitDALOAD();
430 int index = state.pop_I();
431 double[] array = (double[])state.pop_A();
432 state.push_D(array[index]);
433 }
434 public void visitAALOAD() {
435 super.visitAALOAD();
436 int index = state.pop_I();
437 Object[] array = (Object[])state.pop_A();
438 state.push_A(array[index]);
439 }
440 public void visitBALOAD() {
441 super.visitBALOAD();
442 int index = state.pop_I();
443 Object array = (Object)state.pop_A();
444 int val;
445 try {
446 if (array.getClass() == Class.forName("[Z")) val = ((boolean[])array)[index]?1:0;
447 else val = ((byte[])array)[index];
448 } catch (ClassNotFoundException x) { Assert.UNREACHABLE(); return; }
449 state.push_I(val);
450 }
451 public void visitCALOAD() {
452 super.visitCALOAD();
453 int index = state.pop_I();
454 char[] array = (char[])state.pop_A();
455 state.push_I(array[index]);
456 }
457 public void visitSALOAD() {
458 super.visitSALOAD();
459 int index = state.pop_I();
460 short[] array = (short[])state.pop_A();
461 state.push_I(array[index]);
462 }
463 public void visitIASTORE() {
464 super.visitIASTORE();
465 int val = state.pop_I();
466 int index = state.pop_I();
467 int[] array = (int[])state.pop_A();
468 array[index] = val;
469 }
470 public void visitLASTORE() {
471 super.visitLASTORE();
472 long val = state.pop_L();
473 int index = state.pop_I();
474 long[] array = (long[])state.pop_A();
475 array[index] = val;
476 }
477 public void visitFASTORE() {
478 super.visitFASTORE();
479 float val = state.pop_F();
480 int index = state.pop_I();
481 float[] array = (float[])state.pop_A();
482 array[index] = val;
483 }
484 public void visitDASTORE() {
485 super.visitDASTORE();
486 double val = state.pop_D();
487 int index = state.pop_I();
488 double[] array = (double[])state.pop_A();
489 array[index] = val;
490 }
491 public void visitAASTORE() {
492 super.visitAASTORE();
493 Object val = state.pop_A();
494 int index = state.pop_I();
495 Object[] array = (Object[])state.pop_A();
496 array[index] = val;
497 }
498 public void visitBASTORE() {
499 super.visitBASTORE();
500 int val = state.pop_I();
501 int index = state.pop_I();
502 Object array = (Object)state.pop_A();
503 try {
504 if (array.getClass() == Class.forName("[Z")) ((boolean[])array)[index] = val!=0;
505 else ((byte[])array)[index] = (byte)val;
506 } catch (ClassNotFoundException x) { Assert.UNREACHABLE(); }
507 }
508 public void visitCASTORE() {
509 super.visitCASTORE();
510 int val = state.pop_I();
511 int index = state.pop_I();
512 char[] array = (char[])state.pop_A();
513 array[index] = (char)val;
514 }
515 public void visitSASTORE() {
516 super.visitSASTORE();
517 int val = state.pop_I();
518 int index = state.pop_I();
519 short[] array = (short[])state.pop_A();
520 array[index] = (short)val;
521 }
522 public void visitPOP() {
523 super.visitPOP();
524 state.pop();
525 }
526 public void visitPOP2() {
527 super.visitPOP2();
528 state.pop();
529 state.pop();
530 }
531 public void visitDUP() {
532 super.visitDUP();
533 Object o = state.pop();
534 state.push(o);
535 state.push(o);
536 }
537 public void visitDUP_x1() {
538 super.visitDUP_x1();
539 Object o1 = state.pop();
540 Object o2 = state.pop();
541 state.push(o1);
542 state.push(o2);
543 state.push(o1);
544 }
545 public void visitDUP_x2() {
546 super.visitDUP_x2();
547 Object o1 = state.pop();
548 Object o2 = state.pop();
549 Object o3 = state.pop();
550 state.push(o1);
551 state.push(o3);
552 state.push(o2);
553 state.push(o1);
554 }
555 public void visitDUP2() {
556 super.visitDUP2();
557 Object o1 = state.pop();
558 Object o2 = state.pop();
559 state.push(o2);
560 state.push(o1);
561 state.push(o2);
562 state.push(o1);
563 }
564 public void visitDUP2_x1() {
565 super.visitDUP2_x1();
566 Object o1 = state.pop();
567 Object o2 = state.pop();
568 Object o3 = state.pop();
569 state.push(o2);
570 state.push(o1);
571 state.push(o3);
572 state.push(o2);
573 state.push(o1);
574 }
575 public void visitDUP2_x2() {
576 super.visitDUP2_x2();
577 Object o1 = state.pop();
578 Object o2 = state.pop();
579 Object o3 = state.pop();
580 Object o4 = state.pop();
581 state.push(o2);
582 state.push(o1);
583 state.push(o4);
584 state.push(o3);
585 state.push(o2);
586 state.push(o1);
587 }
588 public void visitSWAP() {
589 super.visitSWAP();
590 Object o1 = state.pop();
591 Object o2 = state.pop();
592 state.push(o1);
593 state.push(o2);
594 }
595 public void visitIBINOP(byte op) {
596 super.visitIBINOP(op);
597 int v1 = state.pop_I();
598 int v2 = state.pop_I();
599 switch(op) {
600 case BINOP_ADD:
601 state.push_I(v2+v1);
602 break;
603 case BINOP_SUB:
604 state.push_I(v2-v1);
605 break;
606 case BINOP_MUL:
607 state.push_I(v2*v1);
608 break;
609 case BINOP_DIV:
610 state.push_I(v2/v1);
611 break;
612 case BINOP_REM:
613 state.push_I(v2%v1);
614 break;
615 case BINOP_AND:
616 state.push_I(v2&v1);
617 break;
618 case BINOP_OR:
619 state.push_I(v2|v1);
620 break;
621 case BINOP_XOR:
622 state.push_I(v2^v1);
623 break;
624 default:
625 Assert.UNREACHABLE();
626 }
627 }
628 public void visitLBINOP(byte op) {
629 super.visitLBINOP(op);
630 long v1 = state.pop_L();
631 long v2 = state.pop_L();
632 switch(op) {
633 case BINOP_ADD:
634 state.push_L(v2+v1);
635 break;
636 case BINOP_SUB:
637 state.push_L(v2-v1);
638 break;
639 case BINOP_MUL:
640 state.push_L(v2*v1);
641 break;
642 case BINOP_DIV:
643 state.push_L(v2/v1);
644 break;
645 case BINOP_REM:
646 state.push_L(v2%v1);
647 break;
648 case BINOP_AND:
649 state.push_L(v2&v1);
650 break;
651 case BINOP_OR:
652 state.push_L(v2|v1);
653 break;
654 case BINOP_XOR:
655 state.push_L(v2^v1);
656 break;
657 default:
658 Assert.UNREACHABLE();
659 }
660 }
661 public void visitFBINOP(byte op) {
662 super.visitFBINOP(op);
663 float v1 = state.pop_F();
664 float v2 = state.pop_F();
665 switch(op) {
666 case BINOP_ADD:
667 state.push_F(v2+v1);
668 break;
669 case BINOP_SUB:
670 state.push_F(v2-v1);
671 break;
672 case BINOP_MUL:
673 state.push_F(v2*v1);
674 break;
675 case BINOP_DIV:
676 state.push_F(v2/v1);
677 break;
678 case BINOP_REM:
679 state.push_F(v2%v1);
680 break;
681 default:
682 Assert.UNREACHABLE();
683 }
684 }
685 public void visitDBINOP(byte op) {
686 super.visitDBINOP(op);
687 double v1 = state.pop_D();
688 double v2 = state.pop_D();
689 switch(op) {
690 case BINOP_ADD:
691 state.push_D(v2+v1);
692 break;
693 case BINOP_SUB:
694 state.push_D(v2-v1);
695 break;
696 case BINOP_MUL:
697 state.push_D(v2*v1);
698 break;
699 case BINOP_DIV:
700 state.push_D(v2/v1);
701 break;
702 case BINOP_REM:
703 state.push_D(v2%v1);
704 break;
705 default:
706 Assert.UNREACHABLE();
707 }
708 }
709 public void visitIUNOP(byte op) {
710 super.visitIUNOP(op);
711 Assert._assert(op == UNOP_NEG);
712 state.push_I(-state.pop_I());
713 }
714 public void visitLUNOP(byte op) {
715 super.visitLUNOP(op);
716 Assert._assert(op == UNOP_NEG);
717 state.push_L(-state.pop_L());
718 }
719 public void visitFUNOP(byte op) {
720 super.visitFUNOP(op);
721 Assert._assert(op == UNOP_NEG);
722 state.push_F(-state.pop_F());
723 }
724 public void visitDUNOP(byte op) {
725 super.visitDUNOP(op);
726 Assert._assert(op == UNOP_NEG);
727 state.push_D(-state.pop_D());
728 }
729 public void visitISHIFT(byte op) {
730 super.visitISHIFT(op);
731 int v1 = state.pop_I();
732 int v2 = state.pop_I();
733 switch(op) {
734 case SHIFT_LEFT:
735 state.push_I(v2 << v1);
736 break;
737 case SHIFT_RIGHT:
738 state.push_I(v2 >> v1);
739 break;
740 case SHIFT_URIGHT:
741 state.push_I(v2 >>> v1);
742 break;
743 default:
744 Assert.UNREACHABLE();
745 }
746 }
747 public void visitLSHIFT(byte op) {
748 super.visitLSHIFT(op);
749 int v1 = state.pop_I();
750 long v2 = state.pop_L();
751 switch(op) {
752 case SHIFT_LEFT:
753 state.push_L(v2 << v1);
754 break;
755 case SHIFT_RIGHT:
756 state.push_L(v2 >> v1);
757 break;
758 case SHIFT_URIGHT:
759 state.push_L(v2 >>> v1);
760 break;
761 default:
762 Assert.UNREACHABLE();
763 }
764 }
765 public void visitIINC(int i, int v) {
766 super.visitIINC(i, v);
767 state.setLocal_I(i, state.getLocal_I(i)+v);
768 }
769 public void visitI2L() {
770 super.visitI2L();
771 state.push_L((long)state.pop_I());
772 }
773 public void visitI2F() {
774 super.visitI2F();
775 state.push_F((float)state.pop_I());
776 }
777 public void visitI2D() {
778 super.visitI2D();
779 state.push_D((double)state.pop_I());
780 }
781 public void visitL2I() {
782 super.visitL2I();
783 state.push_I((int)state.pop_L());
784 }
785 public void visitL2F() {
786 super.visitL2F();
787 state.push_F((float)state.pop_L());
788 }
789 public void visitL2D() {
790 super.visitL2D();
791 state.push_D((double)state.pop_L());
792 }
793 public void visitF2I() {
794 super.visitF2I();
795 state.push_I((int)state.pop_F());
796 }
797 public void visitF2L() {
798 super.visitF2L();
799 state.push_L((long)state.pop_F());
800 }
801 public void visitF2D() {
802 super.visitF2D();
803 state.push_D((double)state.pop_F());
804 }
805 public void visitD2I() {
806 super.visitD2I();
807 state.push_I((int)state.pop_D());
808 }
809 public void visitD2L() {
810 super.visitD2L();
811 state.push_L((long)state.pop_D());
812 }
813 public void visitD2F() {
814 super.visitD2F();
815 state.push_F((float)state.pop_D());
816 }
817 public void visitI2B() {
818 super.visitI2B();
819 state.push_I((byte)state.pop_I());
820 }
821 public void visitI2C() {
822 super.visitI2C();
823 state.push_I((char)state.pop_I());
824 }
825 public void visitI2S() {
826 super.visitI2S();
827 state.push_I((short)state.pop_I());
828 }
829 public void visitLCMP2() {
830 super.visitLCMP2();
831 long v1 = state.pop_L();
832 long v2 = state.pop_L();
833 state.push_I((v2>v1)?1:((v2==v1)?0:-1));
834 }
835 public void visitFCMP2(byte op) {
836 super.visitFCMP2(op);
837 float v1 = state.pop_F();
838 float v2 = state.pop_F();
839 int val;
840 if (op == CMP_L)
841 val = ((v2>v1)?1:((v2==v1)?0:-1));
842 else
843 val = ((v2<v1)?-1:((v2==v1)?0:1));
844 state.push_I(val);
845 }
846 public void visitDCMP2(byte op) {
847 super.visitDCMP2(op);
848 double v1 = state.pop_D();
849 double v2 = state.pop_D();
850 int val;
851 if (op == CMP_L)
852 val = ((v2>v1)?1:((v2==v1)?0:-1));
853 else
854 val = ((v2<v1)?-1:((v2==v1)?0:1));
855 state.push_I(val);
856 }
857 public void visitIF(byte op, int target) {
858 super.visitIF(op, target);
859 int v = state.pop_I();
860 switch(op) {
861 case CMP_EQ: if (v==0) branchTo(target); break;
862 case CMP_NE: if (v!=0) branchTo(target); break;
863 case CMP_LT: if (v<0) branchTo(target); break;
864 case CMP_GE: if (v>=0) branchTo(target); break;
865 case CMP_LE: if (v<=0) branchTo(target); break;
866 case CMP_GT: if (v>0) branchTo(target); break;
867 default: Assert.UNREACHABLE();
868 }
869 }
870 public void visitIFREF(byte op, int target) {
871 super.visitIFREF(op, target);
872 Object v = state.pop_A();
873 switch(op) {
874 case CMP_EQ: if (v==null) branchTo(target); break;
875 case CMP_NE: if (v!=null) branchTo(target); break;
876 default: Assert.UNREACHABLE();
877 }
878 }
879 public void visitIFCMP(byte op, int target) {
880 super.visitIFCMP(op, target);
881 int v1 = state.pop_I();
882 int v2 = state.pop_I();
883 switch(op) {
884 case CMP_EQ: if (v2==v1) branchTo(target); break;
885 case CMP_NE: if (v2!=v1) branchTo(target); break;
886 case CMP_LT: if (v2<v1) branchTo(target); break;
887 case CMP_GE: if (v2>=v1) branchTo(target); break;
888 case CMP_LE: if (v2<=v1) branchTo(target); break;
889 case CMP_GT: if (v2>v1) branchTo(target); break;
890 default: Assert.UNREACHABLE();
891 }
892 }
893 public void visitIFREFCMP(byte op, int target) {
894 super.visitIFREFCMP(op, target);
895 Object v1 = state.pop_A();
896 Object v2 = state.pop_A();
897 switch(op) {
898 case CMP_EQ: if (v2==v1) branchTo(target); break;
899 case CMP_NE: if (v2!=v1) branchTo(target); break;
900 default: Assert.UNREACHABLE();
901 }
902 }
903 public void visitGOTO(int target) {
904 super.visitGOTO(target);
905 branchTo(target);
906 }
907 public void visitJSR(int target) {
908 super.visitJSR(target);
909 state.push_I(i_end+1);
910 branchTo(target);
911 }
912 public void visitRET(int i) {
913 super.visitRET(i);
914 branchTo(state.getLocal_I(i));
915 }
916 public void visitTABLESWITCH(int default_target, int low, int high, int[] targets) {
917 super.visitTABLESWITCH(default_target, low, high, targets);
918 int v = state.pop_I();
919 if ((v < low) || (v > high)) branchTo(default_target);
920 else branchTo(targets[v-low]);
921 }
922 public void visitLOOKUPSWITCH(int default_target, int[] values, int[] targets) {
923 super.visitLOOKUPSWITCH(default_target, values, targets);
924 int v = state.pop_I();
925 for (int i=0; i<values.length; ++i) {
926 if (v == values[i]) {
927 branchTo(targets[i]);
928 return;
929 }
930 }
931 branchTo(default_target);
932 }
933 public void visitIRETURN() {
934 super.visitIRETURN();
935 state.return_I(state.pop_I());
936 i_end = bcs.length;
937 }
938 public void visitLRETURN() {
939 super.visitLRETURN();
940 state.return_L(state.pop_L());
941 i_end = bcs.length;
942 }
943 public void visitFRETURN() {
944 super.visitFRETURN();
945 state.return_F(state.pop_F());
946 i_end = bcs.length;
947 }
948 public void visitDRETURN() {
949 super.visitDRETURN();
950 state.return_D(state.pop_D());
951 i_end = bcs.length;
952 }
953 public void visitARETURN() {
954 super.visitARETURN();
955 state.return_A(state.pop_A());
956 i_end = bcs.length;
957 }
958 public void visitVRETURN() {
959 super.visitVRETURN();
960 state.return_V();
961 i_end = bcs.length;
962 }
963 public void visitIGETSTATIC(jq_StaticField f) {
964 super.visitIGETSTATIC(f);
965 f = resolve(f);
966 f.getDeclaringClass().cls_initialize();
967 state.push_I(Reflection.getstatic_I(f));
968 }
969 public void visitLGETSTATIC(jq_StaticField f) {
970 super.visitLGETSTATIC(f);
971 f = resolve(f);
972 f.getDeclaringClass().cls_initialize();
973 state.push_L(Reflection.getstatic_L(f));
974 }
975 public void visitFGETSTATIC(jq_StaticField f) {
976 super.visitFGETSTATIC(f);
977 f = resolve(f);
978 f.getDeclaringClass().cls_initialize();
979 state.push_F(Reflection.getstatic_F(f));
980 }
981 public void visitDGETSTATIC(jq_StaticField f) {
982 super.visitDGETSTATIC(f);
983 f = resolve(f);
984 f.getDeclaringClass().cls_initialize();
985 state.push_D(Reflection.getstatic_D(f));
986 }
987 public void visitAGETSTATIC(jq_StaticField f) {
988 super.visitAGETSTATIC(f);
989 f = resolve(f);
990 f.getDeclaringClass().cls_initialize();
991 state.push_A(Reflection.getstatic_A(f));
992 }
993 public void visitZGETSTATIC(jq_StaticField f) {
994 super.visitZGETSTATIC(f);
995 f = resolve(f);
996 f.getDeclaringClass().cls_initialize();
997 state.push_I(Reflection.getstatic_Z(f)?1:0);
998 }
999 public void visitBGETSTATIC(jq_StaticField f) {
1000 super.visitBGETSTATIC(f);
1001 f = resolve(f);
1002 f.getDeclaringClass().cls_initialize();
1003 state.push_I(Reflection.getstatic_B(f));
1004 }
1005 public void visitCGETSTATIC(jq_StaticField f) {
1006 super.visitCGETSTATIC(f);
1007 f = resolve(f);
1008 f.getDeclaringClass().cls_initialize();
1009 state.push_I(Reflection.getstatic_C(f));
1010 }
1011 public void visitSGETSTATIC(jq_StaticField f) {
1012 super.visitSGETSTATIC(f);
1013 f = resolve(f);
1014 f.getDeclaringClass().cls_initialize();
1015 state.push_I(Reflection.getstatic_S(f));
1016 }
1017 public void visitIPUTSTATIC(jq_StaticField f) {
1018 super.visitIPUTSTATIC(f);
1019 f = resolve(f);
1020 f.getDeclaringClass().cls_initialize();
1021 Reflection.putstatic_I(f, state.pop_I());
1022 }
1023 public void visitLPUTSTATIC(jq_StaticField f) {
1024 super.visitLPUTSTATIC(f);
1025 f = resolve(f);
1026 f.getDeclaringClass().cls_initialize();
1027 Reflection.putstatic_L(f, state.pop_L());
1028 }
1029 public void visitFPUTSTATIC(jq_StaticField f) {
1030 super.visitFPUTSTATIC(f);
1031 f = resolve(f);
1032 f.getDeclaringClass().cls_initialize();
1033 Reflection.putstatic_F(f, state.pop_F());
1034 }
1035 public void visitDPUTSTATIC(jq_StaticField f) {
1036 super.visitDPUTSTATIC(f);
1037 f = resolve(f);
1038 f.getDeclaringClass().cls_initialize();
1039 Reflection.putstatic_D(f, state.pop_D());
1040 }
1041 public void visitAPUTSTATIC(jq_StaticField f) {
1042 super.visitAPUTSTATIC(f);
1043 f = resolve(f);
1044 f.getDeclaringClass().cls_initialize();
1045 Reflection.putstatic_A(f, state.pop_A());
1046 }
1047 public void visitZPUTSTATIC(jq_StaticField f) {
1048 super.visitZPUTSTATIC(f);
1049 f = resolve(f);
1050 f.getDeclaringClass().cls_initialize();
1051 Reflection.putstatic_Z(f, state.pop_I()!=0);
1052 }
1053 public void visitBPUTSTATIC(jq_StaticField f) {
1054 super.visitBPUTSTATIC(f);
1055 f = resolve(f);
1056 f.getDeclaringClass().cls_initialize();
1057 Reflection.putstatic_B(f, (byte)state.pop_I());
1058 }
1059 public void visitCPUTSTATIC(jq_StaticField f) {
1060 super.visitCPUTSTATIC(f);
1061 f = resolve(f);
1062 f.getDeclaringClass().cls_initialize();
1063 Reflection.putstatic_C(f, (char)state.pop_I());
1064 }
1065 public void visitSPUTSTATIC(jq_StaticField f) {
1066 super.visitSPUTSTATIC(f);
1067 f = resolve(f);
1068 f.getDeclaringClass().cls_initialize();
1069 Reflection.putstatic_S(f, (short)state.pop_I());
1070 }
1071 public void visitIGETFIELD(jq_InstanceField f) {
1072 super.visitIGETFIELD(f);
1073 f = resolve(f);
1074 state.push_I(Reflection.getfield_I(state.pop_A(), f));
1075 }
1076 public void visitLGETFIELD(jq_InstanceField f) {
1077 super.visitLGETFIELD(f);
1078 f = resolve(f);
1079 state.push_L(Reflection.getfield_L(state.pop_A(), f));
1080 }
1081 public void visitFGETFIELD(jq_InstanceField f) {
1082 super.visitFGETFIELD(f);
1083 f = resolve(f);
1084 state.push_F(Reflection.getfield_F(state.pop_A(), f));
1085 }
1086 public void visitDGETFIELD(jq_InstanceField f) {
1087 super.visitDGETFIELD(f);
1088 f = resolve(f);
1089 state.push_D(Reflection.getfield_D(state.pop_A(), f));
1090 }
1091 public void visitAGETFIELD(jq_InstanceField f) {
1092 super.visitAGETFIELD(f);
1093 f = resolve(f);
1094 state.push_A(Reflection.getfield_A(state.pop_A(), f));
1095 }
1096 public void visitBGETFIELD(jq_InstanceField f) {
1097 super.visitBGETFIELD(f);
1098 f = resolve(f);
1099 state.push_I(Reflection.getfield_B(state.pop_A(), f));
1100 }
1101 public void visitCGETFIELD(jq_InstanceField f) {
1102 super.visitCGETFIELD(f);
1103 f = resolve(f);
1104 state.push_I(Reflection.getfield_C(state.pop_A(), f));
1105 }
1106 public void visitSGETFIELD(jq_InstanceField f) {
1107 super.visitSGETFIELD(f);
1108 f = resolve(f);
1109 state.push_I(Reflection.getfield_S(state.pop_A(), f));
1110 }
1111 public void visitZGETFIELD(jq_InstanceField f) {
1112 super.visitZGETFIELD(f);
1113 f = resolve(f);
1114 state.push_I(Reflection.getfield_Z(state.pop_A(), f)?1:0);
1115 }
1116 public void visitIPUTFIELD(jq_InstanceField f) {
1117 super.visitIPUTFIELD(f);
1118 f = resolve(f);
1119 int v = state.pop_I();
1120 Reflection.putfield_I(state.pop_A(), f, v);
1121 }
1122 public void visitLPUTFIELD(jq_InstanceField f) {
1123 super.visitLPUTFIELD(f);
1124 f = resolve(f);
1125 long v = state.pop_L();
1126 Reflection.putfield_L(state.pop_A(), f, v);
1127 }
1128 public void visitFPUTFIELD(jq_InstanceField f) {
1129 super.visitFPUTFIELD(f);
1130 f = resolve(f);
1131 float v = state.pop_F();
1132 Reflection.putfield_F(state.pop_A(), f, v);
1133 }
1134 public void visitDPUTFIELD(jq_InstanceField f) {
1135 super.visitDPUTFIELD(f);
1136 f = resolve(f);
1137 double v = state.pop_D();
1138 Reflection.putfield_D(state.pop_A(), f, v);
1139 }
1140 public void visitAPUTFIELD(jq_InstanceField f) {
1141 super.visitAPUTFIELD(f);
1142 f = resolve(f);
1143 Object v = state.pop_A();
1144 Reflection.putfield_A(state.pop_A(), f, v);
1145 }
1146 public void visitBPUTFIELD(jq_InstanceField f) {
1147 super.visitBPUTFIELD(f);
1148 f = resolve(f);
1149 byte v = (byte)state.pop_I();
1150 Reflection.putfield_B(state.pop_A(), f, v);
1151 }
1152 public void visitCPUTFIELD(jq_InstanceField f) {
1153 super.visitCPUTFIELD(f);
1154 f = resolve(f);
1155 char v = (char)state.pop_I();
1156 Reflection.putfield_C(state.pop_A(), f, v);
1157 }
1158 public void visitSPUTFIELD(jq_InstanceField f) {
1159 super.visitSPUTFIELD(f);
1160 f = resolve(f);
1161 short v = (short)state.pop_I();
1162 Reflection.putfield_S(state.pop_A(), f, v);
1163 }
1164 public void visitZPUTFIELD(jq_InstanceField f) {
1165 super.visitZPUTFIELD(f);
1166 f = resolve(f);
1167 boolean v = state.pop_I()!=0;
1168 Reflection.putfield_Z(state.pop_A(), f, v);
1169 }
1170 protected Object INVOKEhelper(byte op, jq_Method f) {
1171 f = (