1 // interpret.cc - Code for the interpreter
2 
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
4 
5    This file is part of libgcj.
6 
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10 
11 /* Author: Kresten Krab Thorup <krab@gnu.org>  */
12 
13 #include <config.h>
14 
15 // Define this to get the direct-threaded interpreter.  If undefined,
16 // we revert to a basic bytecode interpreter.  The former is faster
17 // but uses more memory.
18 #define DIRECT_THREADED
19 
20 #pragma implementation "java-interp.h"
21 
22 #include <jvm.h>
23 #include <java-cpool.h>
24 #include <java-interp.h>
25 #include <java/lang/System.h>
26 #include <java/lang/String.h>
27 #include <java/lang/Integer.h>
28 #include <java/lang/Long.h>
29 #include <java/lang/StringBuffer.h>
30 #include <java/lang/Class.h>
31 #include <java/lang/reflect/Modifier.h>
32 #include <java/lang/ClassCastException.h>
33 #include <java/lang/VirtualMachineError.h>
34 #include <java/lang/InternalError.h>
35 #include <java/lang/NullPointerException.h>
36 #include <java/lang/ArithmeticException.h>
37 #include <java/lang/IncompatibleClassChangeError.h>
38 #include <java/lang/Thread.h>
39 #include <java-insns.h>
40 #include <java-signal.h>
41 
42 #ifdef INTERPRETER
43 
44 #include <stdlib.h>
45 
46 using namespace gcj;
47 
48 static void throw_internal_error (char *msg)
49   __attribute__ ((__noreturn__));
50 static void throw_incompatible_class_change_error (jstring msg)
51   __attribute__ ((__noreturn__));
52 #ifndef HANDLE_SEGV
53 static void throw_null_pointer_exception ()
54   __attribute__ ((__noreturn__));
55 #endif
56 
57 #ifdef DIRECT_THREADED
58 // Lock to ensure that methods are not compiled concurrently.
59 // We could use a finer-grained lock here, however it is not safe to use
60 // the Class monitor as user code in another thread could hold it.
61 static _Jv_Mutex_t compile_mutex;
62 
63 void
_Jv_InitInterpreter()64 _Jv_InitInterpreter()
65 {
66   _Jv_MutexInit (&compile_mutex);
67 }
68 #else
_Jv_InitInterpreter()69 void _Jv_InitInterpreter() {}
70 #endif
71 
72 extern "C" double __ieee754_fmod (double,double);
73 
74 // This represents a single slot in the "compiled" form of the
75 // bytecode.
76 union insn_slot
77 {
78   // Address of code.
79   void *insn;
80   // An integer value used by an instruction.
81   jint int_val;
82   // A pointer value used by an instruction.
83   void *datum;
84 };
85 
86 // The type of the PC depends on whether we're doing direct threading
87 // or a more ordinary bytecode interpreter.
88 #ifdef DIRECT_THREADED
89 typedef insn_slot *pc_t;
90 #else
91 typedef unsigned char *pc_t;
92 #endif
93 
dupx(_Jv_word * sp,int n,int x)94 static inline void dupx (_Jv_word *sp, int n, int x)
95 {
96   // first "slide" n+x elements n to the right
97   int top = n-1;
98   for (int i = 0; i < n+x; i++)
99     {
100       sp[(top-i)] = sp[(top-i)-n];
101     }
102 
103   // next, copy the n top elements, n+x down
104   for (int i = 0; i < n; i++)
105     {
106       sp[top-(n+x)-i] = sp[top-i];
107     }
108 
109 }
110 
111 // Used to convert from floating types to integral types.
112 template<typename TO, typename FROM>
113 static inline TO
convert(FROM val,TO min,TO max)114 convert (FROM val, TO min, TO max)
115 {
116   TO ret;
117   if (val >= (FROM) max)
118     ret = max;
119   else if (val <= (FROM) min)
120     ret = min;
121   else if (val != val)
122     ret = 0;
123   else
124     ret = (TO) val;
125   return ret;
126 }
127 
128 #define PUSHA(V)  (sp++)->o = (V)
129 #define PUSHI(V)  (sp++)->i = (V)
130 #define PUSHF(V)  (sp++)->f = (V)
131 #if SIZEOF_VOID_P == 8
132 # define PUSHL(V)   (sp->l = (V), sp += 2)
133 # define PUSHD(V)   (sp->d = (V), sp += 2)
134 #else
135 # define PUSHL(V)  do { _Jv_word2 w2; w2.l=(V); \
136                         (sp++)->ia[0] = w2.ia[0]; \
137                         (sp++)->ia[0] = w2.ia[1]; } while (0)
138 # define PUSHD(V)  do { _Jv_word2 w2; w2.d=(V); \
139                         (sp++)->ia[0] = w2.ia[0]; \
140                         (sp++)->ia[0] = w2.ia[1]; } while (0)
141 #endif
142 
143 #define POPA()    ((--sp)->o)
144 #define POPI()    ((jint) (--sp)->i) // cast since it may be promoted
145 #define POPF()    ((jfloat) (--sp)->f)
146 #if SIZEOF_VOID_P == 8
147 # define POPL()	  (sp -= 2, (jlong) sp->l)
148 # define POPD()	  (sp -= 2, (jdouble) sp->d)
149 #else
150 # define POPL()    ({ _Jv_word2 w2; \
151                      w2.ia[1] = (--sp)->ia[0]; \
152                      w2.ia[0] = (--sp)->ia[0]; w2.l; })
153 # define POPD()    ({ _Jv_word2 w2; \
154                      w2.ia[1] = (--sp)->ia[0]; \
155                      w2.ia[0] = (--sp)->ia[0]; w2.d; })
156 #endif
157 
158 #define LOADA(I)  (sp++)->o = locals[I].o
159 #define LOADI(I)  (sp++)->i = locals[I].i
160 #define LOADF(I)  (sp++)->f = locals[I].f
161 #if SIZEOF_VOID_P == 8
162 # define LOADL(I)  (sp->l = locals[I].l, sp += 2)
163 # define LOADD(I)  (sp->d = locals[I].d, sp += 2)
164 #else
165 # define LOADL(I)  do { jint __idx = (I); \
166     			(sp++)->ia[0] = locals[__idx].ia[0]; \
167     			(sp++)->ia[0] = locals[__idx+1].ia[0]; \
168  		   } while (0)
169 # define LOADD(I)  LOADL(I)
170 #endif
171 
172 #define STOREA(I) locals[I].o = (--sp)->o
173 #define STOREI(I) locals[I].i = (--sp)->i
174 #define STOREF(I) locals[I].f = (--sp)->f
175 #if SIZEOF_VOID_P == 8
176 # define STOREL(I) (sp -= 2, locals[I].l = sp->l)
177 # define STORED(I) (sp -= 2, locals[I].d = sp->d)
178 #else
179 # define STOREL(I) do { jint __idx = (I); \
180     		       locals[__idx+1].ia[0] = (--sp)->ia[0]; \
181     		       locals[__idx].ia[0] = (--sp)->ia[0]; \
182 		   } while (0)
183 # define STORED(I) STOREL(I)
184 #endif
185 
186 #define PEEKI(I)  (locals+(I))->i
187 #define PEEKA(I)  (locals+(I))->o
188 
189 #define POKEI(I,V)  ((locals+(I))->i = (V))
190 
191 
192 #define BINOPI(OP) { \
193    jint value2 = POPI(); \
194    jint value1 = POPI(); \
195    PUSHI(value1 OP value2); \
196 }
197 
198 #define BINOPF(OP) { \
199    jfloat value2 = POPF(); \
200    jfloat value1 = POPF(); \
201    PUSHF(value1 OP value2); \
202 }
203 
204 #define BINOPL(OP) { \
205    jlong value2 = POPL(); \
206    jlong value1 = POPL(); \
207    PUSHL(value1 OP value2); \
208 }
209 
210 #define BINOPD(OP) { \
211    jdouble value2 = POPD(); \
212    jdouble value1 = POPD(); \
213    PUSHD(value1 OP value2); \
214 }
215 
get1s(unsigned char * loc)216 static inline jint get1s(unsigned char* loc) {
217   return *(signed char*)loc;
218 }
219 
get1u(unsigned char * loc)220 static inline jint get1u(unsigned char* loc) {
221   return *loc;
222 }
223 
get2s(unsigned char * loc)224 static inline jint get2s(unsigned char* loc) {
225   return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
226 }
227 
get2u(unsigned char * loc)228 static inline jint get2u(unsigned char* loc) {
229   return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
230 }
231 
get4(unsigned char * loc)232 static jint get4(unsigned char* loc) {
233   return (((jint)(loc[0])) << 24)
234        | (((jint)(loc[1])) << 16)
235        | (((jint)(loc[2])) << 8)
236        | (((jint)(loc[3])) << 0);
237 }
238 
239 
240 #ifdef HANDLE_SEGV
241 #define NULLCHECK(X)
242 #define NULLARRAYCHECK(X)
243 #else
244 #define NULLCHECK(X) \
245   do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
246 #define NULLARRAYCHECK(X) \
247   do { if ((X)==NULL) { throw_null_pointer_exception (); } } while (0)
248 #endif
249 
250 #define ARRAYBOUNDSCHECK(array, index)					      \
251   do									      \
252     {									      \
253       if (((unsigned) index) >= (unsigned) (array->length))		      \
254 	_Jv_ThrowBadArrayIndex (index);					      \
255     }									      \
256   while (0)
257 
258 void
run_normal(ffi_cif *,void * ret,ffi_raw * args,void * __this)259 _Jv_InterpMethod::run_normal (ffi_cif *,
260 			      void* ret,
261 			      ffi_raw * args,
262 			      void* __this)
263 {
264   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
265   _this->run (ret, args);
266 }
267 
268 void
run_synch_object(ffi_cif *,void * ret,ffi_raw * args,void * __this)269 _Jv_InterpMethod::run_synch_object (ffi_cif *,
270 				    void* ret,
271 				    ffi_raw * args,
272 				    void* __this)
273 {
274   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
275 
276   jobject rcv = (jobject) args[0].ptr;
277   JvSynchronize mutex (rcv);
278 
279   _this->run (ret, args);
280 }
281 
282 void
run_class(ffi_cif *,void * ret,ffi_raw * args,void * __this)283 _Jv_InterpMethod::run_class (ffi_cif *,
284 			     void* ret,
285 			     ffi_raw * args,
286 			     void* __this)
287 {
288   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
289   _Jv_InitClass (_this->defining_class);
290   _this->run (ret, args);
291 }
292 
293 void
run_synch_class(ffi_cif *,void * ret,ffi_raw * args,void * __this)294 _Jv_InterpMethod::run_synch_class (ffi_cif *,
295 				   void* ret,
296 				   ffi_raw * args,
297 				   void* __this)
298 {
299   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
300 
301   jclass sync = _this->defining_class;
302   _Jv_InitClass (sync);
303   JvSynchronize mutex (sync);
304 
305   _this->run (ret, args);
306 }
307 
308 #ifdef DIRECT_THREADED
309 // "Compile" a method by turning it from bytecode to direct-threaded
310 // code.
311 void
compile(const void * const * insn_targets)312 _Jv_InterpMethod::compile (const void * const *insn_targets)
313 {
314   insn_slot *insns = NULL;
315   int next = 0;
316   unsigned char *codestart = bytecode ();
317   unsigned char *end = codestart + code_length;
318   _Jv_word *pool_data = defining_class->constants.data;
319 
320 #define SET_ONE(Field, Value)						      \
321   do									      \
322     {									      \
323       if (first_pass)							      \
324 	++next;								      \
325       else								      \
326 	insns[next++].Field = Value;					      \
327     }									      \
328   while (0)
329 
330 #define SET_INSN(Value) SET_ONE (insn, (void *) Value)
331 #define SET_INT(Value) SET_ONE (int_val, Value)
332 #define SET_DATUM(Value) SET_ONE (datum, Value)
333 
334   // Map from bytecode PC to slot in INSNS.
335   int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
336   for (int i = 0; i < code_length; ++i)
337     pc_mapping[i] = -1;
338 
339   for (int i = 0; i < 2; ++i)
340     {
341       jboolean first_pass = i == 0;
342 
343       if (! first_pass)
344 	{
345 	  insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
346 	  next = 0;
347 	}
348 
349       unsigned char *pc = codestart;
350       while (pc < end)
351 	{
352 	  int base_pc_val = pc - codestart;
353 	  if (first_pass)
354 	    pc_mapping[base_pc_val] = next;
355 
356 	  java_opcode opcode = (java_opcode) *pc++;
357 	  // Just elide NOPs.
358 	  if (opcode == op_nop)
359 	    continue;
360 	  SET_INSN (insn_targets[opcode]);
361 
362 	  switch (opcode)
363 	    {
364 	    case op_nop:
365 	    case op_aconst_null:
366 	    case op_iconst_m1:
367 	    case op_iconst_0:
368 	    case op_iconst_1:
369 	    case op_iconst_2:
370 	    case op_iconst_3:
371 	    case op_iconst_4:
372 	    case op_iconst_5:
373 	    case op_lconst_0:
374 	    case op_lconst_1:
375 	    case op_fconst_0:
376 	    case op_fconst_1:
377 	    case op_fconst_2:
378 	    case op_dconst_0:
379 	    case op_dconst_1:
380 	    case op_iload_0:
381 	    case op_iload_1:
382 	    case op_iload_2:
383 	    case op_iload_3:
384 	    case op_lload_0:
385 	    case op_lload_1:
386 	    case op_lload_2:
387 	    case op_lload_3:
388 	    case op_fload_0:
389 	    case op_fload_1:
390 	    case op_fload_2:
391 	    case op_fload_3:
392 	    case op_dload_0:
393 	    case op_dload_1:
394 	    case op_dload_2:
395 	    case op_dload_3:
396 	    case op_aload_0:
397 	    case op_aload_1:
398 	    case op_aload_2:
399 	    case op_aload_3:
400 	    case op_iaload:
401 	    case op_laload:
402 	    case op_faload:
403 	    case op_daload:
404 	    case op_aaload:
405 	    case op_baload:
406 	    case op_caload:
407 	    case op_saload:
408 	    case op_istore_0:
409 	    case op_istore_1:
410 	    case op_istore_2:
411 	    case op_istore_3:
412 	    case op_lstore_0:
413 	    case op_lstore_1:
414 	    case op_lstore_2:
415 	    case op_lstore_3:
416 	    case op_fstore_0:
417 	    case op_fstore_1:
418 	    case op_fstore_2:
419 	    case op_fstore_3:
420 	    case op_dstore_0:
421 	    case op_dstore_1:
422 	    case op_dstore_2:
423 	    case op_dstore_3:
424 	    case op_astore_0:
425 	    case op_astore_1:
426 	    case op_astore_2:
427 	    case op_astore_3:
428 	    case op_iastore:
429 	    case op_lastore:
430 	    case op_fastore:
431 	    case op_dastore:
432 	    case op_aastore:
433 	    case op_bastore:
434 	    case op_castore:
435 	    case op_sastore:
436 	    case op_pop:
437 	    case op_pop2:
438 	    case op_dup:
439 	    case op_dup_x1:
440 	    case op_dup_x2:
441 	    case op_dup2:
442 	    case op_dup2_x1:
443 	    case op_dup2_x2:
444 	    case op_swap:
445 	    case op_iadd:
446 	    case op_isub:
447 	    case op_imul:
448 	    case op_idiv:
449 	    case op_irem:
450 	    case op_ishl:
451 	    case op_ishr:
452 	    case op_iushr:
453 	    case op_iand:
454 	    case op_ior:
455 	    case op_ixor:
456 	    case op_ladd:
457 	    case op_lsub:
458 	    case op_lmul:
459 	    case op_ldiv:
460 	    case op_lrem:
461 	    case op_lshl:
462 	    case op_lshr:
463 	    case op_lushr:
464 	    case op_land:
465 	    case op_lor:
466 	    case op_lxor:
467 	    case op_fadd:
468 	    case op_fsub:
469 	    case op_fmul:
470 	    case op_fdiv:
471 	    case op_frem:
472 	    case op_dadd:
473 	    case op_dsub:
474 	    case op_dmul:
475 	    case op_ddiv:
476 	    case op_drem:
477 	    case op_ineg:
478 	    case op_i2b:
479 	    case op_i2c:
480 	    case op_i2s:
481 	    case op_lneg:
482 	    case op_fneg:
483 	    case op_dneg:
484 	    case op_i2l:
485 	    case op_i2f:
486 	    case op_i2d:
487 	    case op_l2i:
488 	    case op_l2f:
489 	    case op_l2d:
490 	    case op_f2i:
491 	    case op_f2l:
492 	    case op_f2d:
493 	    case op_d2i:
494 	    case op_d2l:
495 	    case op_d2f:
496 	    case op_lcmp:
497 	    case op_fcmpl:
498 	    case op_fcmpg:
499 	    case op_dcmpl:
500 	    case op_dcmpg:
501 	    case op_monitorenter:
502 	    case op_monitorexit:
503 	    case op_ireturn:
504 	    case op_lreturn:
505 	    case op_freturn:
506 	    case op_dreturn:
507 	    case op_areturn:
508 	    case op_return:
509 	    case op_athrow:
510 	    case op_arraylength:
511 	      // No argument, nothing else to do.
512 	      break;
513 
514 	    case op_bipush:
515 	      SET_INT (get1s (pc));
516 	      ++pc;
517 	      break;
518 
519 	    case op_ldc:
520 	      {
521 		int index = get1u (pc);
522 		++pc;
523 		SET_DATUM (pool_data[index].o);
524 	      }
525 	      break;
526 
527 	    case op_ret:
528 	    case op_iload:
529 	    case op_lload:
530 	    case op_fload:
531 	    case op_dload:
532 	    case op_aload:
533 	    case op_istore:
534 	    case op_lstore:
535 	    case op_fstore:
536 	    case op_dstore:
537 	    case op_astore:
538 	    case op_newarray:
539 	      SET_INT (get1u (pc));
540 	      ++pc;
541 	      break;
542 
543 	    case op_iinc:
544 	      SET_INT (get1u (pc));
545 	      SET_INT (get1s (pc + 1));
546 	      pc += 2;
547 	      break;
548 
549 	    case op_ldc_w:
550 	      {
551 		int index = get2u (pc);
552 		pc += 2;
553 		SET_DATUM (pool_data[index].o);
554 	      }
555 	      break;
556 
557 	    case op_ldc2_w:
558 	      {
559 		int index = get2u (pc);
560 		pc += 2;
561 		SET_DATUM (&pool_data[index]);
562 	      }
563 	      break;
564 
565 	    case op_sipush:
566 	      SET_INT (get2s (pc));
567 	      pc += 2;
568 	      break;
569 
570 	    case op_new:
571 	    case op_getstatic:
572 	    case op_getfield:
573 	    case op_putfield:
574 	    case op_putstatic:
575 	    case op_anewarray:
576 	    case op_instanceof:
577 	    case op_checkcast:
578 	    case op_invokespecial:
579 	    case op_invokestatic:
580 	    case op_invokevirtual:
581 	      SET_INT (get2u (pc));
582 	      pc += 2;
583 	      break;
584 
585 	    case op_multianewarray:
586 	      SET_INT (get2u (pc));
587 	      SET_INT (get1u (pc + 2));
588 	      pc += 3;
589 	      break;
590 
591 	    case op_jsr:
592 	    case op_ifeq:
593 	    case op_ifne:
594 	    case op_iflt:
595 	    case op_ifge:
596 	    case op_ifgt:
597 	    case op_ifle:
598 	    case op_if_icmpeq:
599 	    case op_if_icmpne:
600 	    case op_if_icmplt:
601 	    case op_if_icmpge:
602 	    case op_if_icmpgt:
603 	    case op_if_icmple:
604 	    case op_if_acmpeq:
605 	    case op_if_acmpne:
606 	    case op_ifnull:
607 	    case op_ifnonnull:
608 	    case op_goto:
609 	      {
610 		int offset = get2s (pc);
611 		pc += 2;
612 
613 		int new_pc = base_pc_val + offset;
614 
615 		bool orig_was_goto = opcode == op_goto;
616 
617 		// Thread jumps.  We limit the loop count; this lets
618 		// us avoid infinite loops if the bytecode contains
619 		// such.  `10' is arbitrary.
620 		int count = 10;
621 		while (codestart[new_pc] == op_goto && count-- > 0)
622 		  new_pc += get2s (&codestart[new_pc + 1]);
623 
624 		// If the jump takes us to a `return' instruction and
625 		// the original branch was an unconditional goto, then
626 		// we hoist the return.
627 		opcode = (java_opcode) codestart[new_pc];
628 		if (orig_was_goto
629 		    && (opcode == op_ireturn || opcode == op_lreturn
630 			|| opcode == op_freturn || opcode == op_dreturn
631 			|| opcode == op_areturn || opcode == op_return))
632 		  {
633 		    --next;
634 		    SET_INSN (insn_targets[opcode]);
635 		  }
636 		else
637 		  SET_DATUM (&insns[pc_mapping[new_pc]]);
638 	      }
639 	      break;
640 
641 	    case op_tableswitch:
642 	      {
643 		while ((pc - codestart) % 4 != 0)
644 		  ++pc;
645 
646 		jint def = get4 (pc);
647 		SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
648 		pc += 4;
649 
650 		int low = get4 (pc);
651 		SET_INT (low);
652 		pc += 4;
653 		int high = get4 (pc);
654 		SET_INT (high);
655 		pc += 4;
656 
657 		for (int i = low; i <= high; ++i)
658 		  {
659 		    SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
660 		    pc += 4;
661 		  }
662 	      }
663 	      break;
664 
665 	    case op_lookupswitch:
666 	      {
667 		while ((pc - codestart) % 4 != 0)
668 		  ++pc;
669 
670 		jint def = get4 (pc);
671 		SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
672 		pc += 4;
673 
674 		jint npairs = get4 (pc);
675 		pc += 4;
676 		SET_INT (npairs);
677 
678 		while (npairs-- > 0)
679 		  {
680 		    jint match = get4 (pc);
681 		    jint offset = get4 (pc + 4);
682 		    SET_INT (match);
683 		    SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
684 		    pc += 8;
685 		  }
686 	      }
687 	      break;
688 
689 	    case op_invokeinterface:
690 	      {
691 		jint index = get2u (pc);
692 		pc += 2;
693 		// We ignore the next two bytes.
694 		pc += 2;
695 		SET_INT (index);
696 	      }
697 	      break;
698 
699 	    case op_wide:
700 	      {
701 		opcode = (java_opcode) get1u (pc);
702 		pc += 1;
703 		jint val = get2u (pc);
704 		pc += 2;
705 
706 		// We implement narrow and wide instructions using the
707 		// same code in the interpreter.  So we rewrite the
708 		// instruction slot here.
709 		if (! first_pass)
710 		  insns[next - 1].insn = (void *) insn_targets[opcode];
711 		SET_INT (val);
712 
713 		if (opcode == op_iinc)
714 		  {
715 		    SET_INT (get2s (pc));
716 		    pc += 2;
717 		  }
718 	      }
719 	      break;
720 
721 	    case op_jsr_w:
722 	    case op_goto_w:
723 	      {
724 		jint offset = get4 (pc);
725 		pc += 4;
726 		SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
727 	      }
728 	      break;
729 
730 	    // Some "can't happen" cases that we include for
731 	    // error-checking purposes.
732 	    case op_putfield_1:
733 	    case op_putfield_2:
734 	    case op_putfield_4:
735 	    case op_putfield_8:
736 	    case op_putfield_a:
737 	    case op_putstatic_1:
738 	    case op_putstatic_2:
739 	    case op_putstatic_4:
740 	    case op_putstatic_8:
741 	    case op_putstatic_a:
742 	    case op_getfield_1:
743 	    case op_getfield_2s:
744 	    case op_getfield_2u:
745 	    case op_getfield_4:
746 	    case op_getfield_8:
747 	    case op_getfield_a:
748 	    case op_getstatic_1:
749 	    case op_getstatic_2s:
750 	    case op_getstatic_2u:
751 	    case op_getstatic_4:
752 	    case op_getstatic_8:
753 	    case op_getstatic_a:
754 	    default:
755 	      // Fail somehow.
756 	      break;
757 	    }
758 	}
759     }
760 
761   // Now update exceptions.
762   _Jv_InterpException *exc = exceptions ();
763   for (int i = 0; i < exc_count; ++i)
764     {
765       exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
766       exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
767       exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
768       jclass handler = (_Jv_ResolvePoolEntry (defining_class,
769 					      exc[i].handler_type.i)).clazz;
770       exc[i].handler_type.p = handler;
771     }
772 
773   prepared = insns;
774 }
775 #endif /* DIRECT_THREADED */
776 
777 // This function exists so that the stack-tracing code can find the
778 // boundaries of the interpreter.
779 void
_Jv_StartOfInterpreter(void)780 _Jv_StartOfInterpreter (void)
781 {
782 }
783 
784 void
run(void * retp,ffi_raw * args)785 _Jv_InterpMethod::run (void *retp, ffi_raw *args)
786 {
787   using namespace java::lang::reflect;
788 
789   // FRAME_DESC registers this particular invocation as the top-most
790   // interpreter frame.  This lets the stack tracing code (for
791   // Throwable) print information about the method being interpreted
792   // rather than about the interpreter itself.  FRAME_DESC has a
793   // destructor so it cleans up automatically when the interpreter
794   // returns.
795   java::lang::Thread *thread = java::lang::Thread::currentThread();
796   _Jv_MethodChain frame_desc (this,
797 			      (_Jv_MethodChain **) &thread->interp_frame);
798 
799   _Jv_word stack[max_stack];
800   _Jv_word *sp = stack;
801 
802   _Jv_word locals[max_locals];
803 
804   /* Go straight at it!  the ffi raw format matches the internal
805      stack representation exactly.  At least, that's the idea.
806   */
807   memcpy ((void*) locals, (void*) args, args_raw_size);
808 
809   _Jv_word *pool_data = defining_class->constants.data;
810 
811   /* These three are temporaries for common code used by several
812      instructions.  */
813   void (*fun)();
814   _Jv_ResolvedMethod* rmeth;
815   int tmpval;
816 
817 #define INSN_LABEL(op) &&insn_##op
818 
819   static const void *const insn_target[] =
820   {
821     INSN_LABEL(nop),
822     INSN_LABEL(aconst_null),
823     INSN_LABEL(iconst_m1),
824     INSN_LABEL(iconst_0),
825     INSN_LABEL(iconst_1),
826     INSN_LABEL(iconst_2),
827     INSN_LABEL(iconst_3),
828     INSN_LABEL(iconst_4),
829     INSN_LABEL(iconst_5),
830     INSN_LABEL(lconst_0),
831     INSN_LABEL(lconst_1),
832     INSN_LABEL(fconst_0),
833     INSN_LABEL(fconst_1),
834     INSN_LABEL(fconst_2),
835     INSN_LABEL(dconst_0),
836     INSN_LABEL(dconst_1),
837     INSN_LABEL(bipush),
838     INSN_LABEL(sipush),
839     INSN_LABEL(ldc),
840     INSN_LABEL(ldc_w),
841     INSN_LABEL(ldc2_w),
842     INSN_LABEL(iload),
843     INSN_LABEL(lload),
844     INSN_LABEL(fload),
845     INSN_LABEL(dload),
846     INSN_LABEL(aload),
847     INSN_LABEL(iload_0),
848     INSN_LABEL(iload_1),
849     INSN_LABEL(iload_2),
850     INSN_LABEL(iload_3),
851     INSN_LABEL(lload_0),
852     INSN_LABEL(lload_1),
853     INSN_LABEL(lload_2),
854     INSN_LABEL(lload_3),
855     INSN_LABEL(fload_0),
856     INSN_LABEL(fload_1),
857     INSN_LABEL(fload_2),
858     INSN_LABEL(fload_3),
859     INSN_LABEL(dload_0),
860     INSN_LABEL(dload_1),
861     INSN_LABEL(dload_2),
862     INSN_LABEL(dload_3),
863     INSN_LABEL(aload_0),
864     INSN_LABEL(aload_1),
865     INSN_LABEL(aload_2),
866     INSN_LABEL(aload_3),
867     INSN_LABEL(iaload),
868     INSN_LABEL(laload),
869     INSN_LABEL(faload),
870     INSN_LABEL(daload),
871     INSN_LABEL(aaload),
872     INSN_LABEL(baload),
873     INSN_LABEL(caload),
874     INSN_LABEL(saload),
875     INSN_LABEL(istore),
876     INSN_LABEL(lstore),
877     INSN_LABEL(fstore),
878     INSN_LABEL(dstore),
879     INSN_LABEL(astore),
880     INSN_LABEL(istore_0),
881     INSN_LABEL(istore_1),
882     INSN_LABEL(istore_2),
883     INSN_LABEL(istore_3),
884     INSN_LABEL(lstore_0),
885     INSN_LABEL(lstore_1),
886     INSN_LABEL(lstore_2),
887     INSN_LABEL(lstore_3),
888     INSN_LABEL(fstore_0),
889     INSN_LABEL(fstore_1),
890     INSN_LABEL(fstore_2),
891     INSN_LABEL(fstore_3),
892     INSN_LABEL(dstore_0),
893     INSN_LABEL(dstore_1),
894     INSN_LABEL(dstore_2),
895     INSN_LABEL(dstore_3),
896     INSN_LABEL(astore_0),
897     INSN_LABEL(astore_1),
898     INSN_LABEL(astore_2),
899     INSN_LABEL(astore_3),
900     INSN_LABEL(iastore),
901     INSN_LABEL(lastore),
902     INSN_LABEL(fastore),
903     INSN_LABEL(dastore),
904     INSN_LABEL(aastore),
905     INSN_LABEL(bastore),
906     INSN_LABEL(castore),
907     INSN_LABEL(sastore),
908     INSN_LABEL(pop),
909     INSN_LABEL(pop2),
910     INSN_LABEL(dup),
911     INSN_LABEL(dup_x1),
912     INSN_LABEL(dup_x2),
913     INSN_LABEL(dup2),
914     INSN_LABEL(dup2_x1),
915     INSN_LABEL(dup2_x2),
916     INSN_LABEL(swap),
917     INSN_LABEL(iadd),
918     INSN_LABEL(ladd),
919     INSN_LABEL(fadd),
920     INSN_LABEL(dadd),
921     INSN_LABEL(isub),
922     INSN_LABEL(lsub),
923     INSN_LABEL(fsub),
924     INSN_LABEL(dsub),
925     INSN_LABEL(imul),
926     INSN_LABEL(lmul),
927     INSN_LABEL(fmul),
928     INSN_LABEL(dmul),
929     INSN_LABEL(idiv),
930     INSN_LABEL(ldiv),
931     INSN_LABEL(fdiv),
932     INSN_LABEL(ddiv),
933     INSN_LABEL(irem),
934     INSN_LABEL(lrem),
935     INSN_LABEL(frem),
936     INSN_LABEL(drem),
937     INSN_LABEL(ineg),
938     INSN_LABEL(lneg),
939     INSN_LABEL(fneg),
940     INSN_LABEL(dneg),
941     INSN_LABEL(ishl),
942     INSN_LABEL(lshl),
943     INSN_LABEL(ishr),
944     INSN_LABEL(lshr),
945     INSN_LABEL(iushr),
946     INSN_LABEL(lushr),
947     INSN_LABEL(iand),
948     INSN_LABEL(land),
949     INSN_LABEL(ior),
950     INSN_LABEL(lor),
951     INSN_LABEL(ixor),
952     INSN_LABEL(lxor),
953     INSN_LABEL(iinc),
954     INSN_LABEL(i2l),
955     INSN_LABEL(i2f),
956     INSN_LABEL(i2d),
957     INSN_LABEL(l2i),
958     INSN_LABEL(l2f),
959     INSN_LABEL(l2d),
960     INSN_LABEL(f2i),
961     INSN_LABEL(f2l),
962     INSN_LABEL(f2d),
963     INSN_LABEL(d2i),
964     INSN_LABEL(d2l),
965     INSN_LABEL(d2f),
966     INSN_LABEL(i2b),
967     INSN_LABEL(i2c),
968     INSN_LABEL(i2s),
969     INSN_LABEL(lcmp),
970     INSN_LABEL(fcmpl),
971     INSN_LABEL(fcmpg),
972     INSN_LABEL(dcmpl),
973     INSN_LABEL(dcmpg),
974     INSN_LABEL(ifeq),
975     INSN_LABEL(ifne),
976     INSN_LABEL(iflt),
977     INSN_LABEL(ifge),
978     INSN_LABEL(ifgt),
979     INSN_LABEL(ifle),
980     INSN_LABEL(if_icmpeq),
981     INSN_LABEL(if_icmpne),
982     INSN_LABEL(if_icmplt),
983     INSN_LABEL(if_icmpge),
984     INSN_LABEL(if_icmpgt),
985     INSN_LABEL(if_icmple),
986     INSN_LABEL(if_acmpeq),
987     INSN_LABEL(if_acmpne),
988     INSN_LABEL(goto),
989     INSN_LABEL(jsr),
990     INSN_LABEL(ret),
991     INSN_LABEL(tableswitch),
992     INSN_LABEL(lookupswitch),
993     INSN_LABEL(ireturn),
994     INSN_LABEL(lreturn),
995     INSN_LABEL(freturn),
996     INSN_LABEL(dreturn),
997     INSN_LABEL(areturn),
998     INSN_LABEL(return),
999     INSN_LABEL(getstatic),
1000     INSN_LABEL(putstatic),
1001     INSN_LABEL(getfield),
1002     INSN_LABEL(putfield),
1003     INSN_LABEL(invokevirtual),
1004     INSN_LABEL(invokespecial),
1005     INSN_LABEL(invokestatic),
1006     INSN_LABEL(invokeinterface),
1007     0, /* Unused.  */
1008     INSN_LABEL(new),
1009     INSN_LABEL(newarray),
1010     INSN_LABEL(anewarray),
1011     INSN_LABEL(arraylength),
1012     INSN_LABEL(athrow),
1013     INSN_LABEL(checkcast),
1014     INSN_LABEL(instanceof),
1015     INSN_LABEL(monitorenter),
1016     INSN_LABEL(monitorexit),
1017 #ifdef DIRECT_THREADED
1018     0, // wide
1019 #else
1020     INSN_LABEL(wide),
1021 #endif
1022     INSN_LABEL(multianewarray),
1023     INSN_LABEL(ifnull),
1024     INSN_LABEL(ifnonnull),
1025     INSN_LABEL(goto_w),
1026     INSN_LABEL(jsr_w),
1027     0
1028   };
1029 
1030   pc_t pc;
1031 
1032 #ifdef DIRECT_THREADED
1033 
1034 #define NEXT_INSN goto *((pc++)->insn)
1035 #define INTVAL() ((pc++)->int_val)
1036 #define AVAL() ((pc++)->datum)
1037 
1038 #define GET1S() INTVAL ()
1039 #define GET2S() INTVAL ()
1040 #define GET1U() INTVAL ()
1041 #define GET2U() INTVAL ()
1042 #define AVAL1U() AVAL ()
1043 #define AVAL2U() AVAL ()
1044 #define AVAL2UP() AVAL ()
1045 #define SKIP_GOTO ++pc
1046 #define GOTO_VAL() (insn_slot *) pc->datum
1047 #define PCVAL(unionval) unionval.p
1048 #define AMPAMP(label) &&label
1049 
1050   // Compile if we must. NOTE: Double-check locking.
1051   if (prepared == NULL)
1052     {
1053       _Jv_MutexLock (&compile_mutex);
1054       if (prepared == NULL)
1055 	compile (insn_target);
1056       _Jv_MutexUnlock (&compile_mutex);
1057     }
1058   pc = (insn_slot *) prepared;
1059 
1060 #else
1061 
1062 #define NEXT_INSN goto *(insn_target[*pc++])
1063 
1064 #define GET1S() get1s (pc++)
1065 #define GET2S() (pc += 2, get2s (pc- 2))
1066 #define GET1U() get1u (pc++)
1067 #define GET2U() (pc += 2, get2u (pc - 2))
1068 #define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; })
1069 #define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; })
1070 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
1071 #define SKIP_GOTO pc += 2
1072 #define GOTO_VAL() pc - 1 + get2s (pc)
1073 #define PCVAL(unionval) unionval.i
1074 #define AMPAMP(label) NULL
1075 
1076   pc = bytecode ();
1077 
1078 #endif /* DIRECT_THREADED */
1079 
1080 #define TAKE_GOTO pc = GOTO_VAL ()
1081 
1082   try
1083     {
1084       // We keep nop around.  It is used if we're interpreting the
1085       // bytecodes and not doing direct threading.
1086     insn_nop:
1087       NEXT_INSN;
1088 
1089       /* The first few instructions here are ordered according to their
1090 	 frequency, in the hope that this will improve code locality a
1091 	 little.  */
1092 
1093     insn_aload_0:		// 0x2a
1094       LOADA (0);
1095       NEXT_INSN;
1096 
1097     insn_iload:		// 0x15
1098       LOADI (GET1U ());
1099       NEXT_INSN;
1100 
1101     insn_iload_1:		// 0x1b
1102       LOADI (1);
1103       NEXT_INSN;
1104 
1105     insn_invokevirtual:	// 0xb6
1106       {
1107 	int index = GET2U ();
1108 
1109 	/* _Jv_ResolvePoolEntry returns immediately if the value already
1110 	 * is resolved.  If we want to clutter up the code here to gain
1111 	 * a little performance, then we can check the corresponding bit
1112 	 * JV_CONSTANT_ResolvedFlag in the tag directly.  For now, I
1113 	 * don't think it is worth it.  */
1114 
1115 	rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
1116 
1117 	sp -= rmeth->stack_item_count;
1118 	// We don't use NULLCHECK here because we can't rely on that
1119 	// working if the method is final.  So instead we do an
1120 	// explicit test.
1121 	if (! sp[0].o)
1122 	  throw new java::lang::NullPointerException;
1123 
1124 	if (rmeth->vtable_index == -1)
1125 	  {
1126 	    // final methods do not appear in the vtable,
1127 	    // if it does not appear in the superclass.
1128 	    fun = (void (*)()) rmeth->method->ncode;
1129 	  }
1130 	else
1131 	  {
1132 	    jobject rcv = sp[0].o;
1133 	    _Jv_VTable *table = *(_Jv_VTable**) rcv;
1134 	    fun = (void (*)()) table->get_method (rmeth->vtable_index);
1135 	  }
1136 
1137 #ifdef DIRECT_THREADED
1138 	// Rewrite instruction so that we use a faster pre-resolved
1139 	// method.
1140 	pc[-2].insn = &&invokevirtual_resolved;
1141 	pc[-1].datum = rmeth;
1142 #endif /* DIRECT_THREADED */
1143       }
1144       goto perform_invoke;
1145 
1146 #ifdef DIRECT_THREADED
1147     invokevirtual_resolved:
1148       {
1149 	rmeth = (_Jv_ResolvedMethod *) AVAL ();
1150 	sp -= rmeth->stack_item_count;
1151 	// We don't use NULLCHECK here because we can't rely on that
1152 	// working if the method is final.  So instead we do an
1153 	// explicit test.
1154 	if (! sp[0].o)
1155 	  throw new java::lang::NullPointerException;
1156 
1157 	if (rmeth->vtable_index == -1)
1158 	  {
1159 	    // final methods do not appear in the vtable,
1160 	    // if it does not appear in the superclass.
1161 	    fun = (void (*)()) rmeth->method->ncode;
1162 	  }
1163 	else
1164 	  {
1165 	    jobject rcv = sp[0].o;
1166 	    _Jv_VTable *table = *(_Jv_VTable**) rcv;
1167 	    fun = (void (*)()) table->get_method (rmeth->vtable_index);
1168 	  }
1169       }
1170       goto perform_invoke;
1171 #endif /* DIRECT_THREADED */
1172 
1173     perform_invoke:
1174       {
1175 	/* here goes the magic again... */
1176 	ffi_cif *cif = &rmeth->cif;
1177 	ffi_raw *raw = (ffi_raw*) sp;
1178 
1179 	jdouble rvalue;
1180 
1181 #if FFI_NATIVE_RAW_API
1182 	/* We assume that this is only implemented if it's correct	*/
1183 	/* to use it here.  On a 64 bit machine, it never is.		*/
1184 	ffi_raw_call (cif, fun, (void*)&rvalue, raw);
1185 #else
1186 	ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
1187 #endif
1188 
1189 	int rtype = cif->rtype->type;
1190 
1191 	/* the likelyhood of object, int, or void return is very high,
1192 	 * so those are checked before the switch */
1193 	if (rtype == FFI_TYPE_POINTER)
1194 	  {
1195 	    PUSHA (*(jobject*)&rvalue);
1196 	  }
1197 	else if (rtype == FFI_TYPE_SINT32)
1198 	  {
1199 	    PUSHI (*(jint*)&rvalue);
1200 	  }
1201 	else if (rtype == FFI_TYPE_VOID)
1202 	  {
1203 	    /* skip */
1204 	  }
1205 	else
1206 	  {
1207 	    switch (rtype)
1208 	      {
1209 	      case FFI_TYPE_SINT8:
1210 		{
1211 		  jbyte value = (*(jint*)&rvalue) & 0xff;
1212 		  PUSHI (value);
1213 		}
1214 		break;
1215 
1216 	      case FFI_TYPE_SINT16:
1217 		{
1218 		  jshort value = (*(jint*)&rvalue) & 0xffff;
1219 		  PUSHI (value);
1220 		}
1221 		break;
1222 
1223 	      case FFI_TYPE_UINT16:
1224 		{
1225 		  jint value = (*(jint*)&rvalue) & 0xffff;
1226 		  PUSHI (value);
1227 		}
1228 		break;
1229 
1230 	      case FFI_TYPE_FLOAT:
1231 		PUSHF (*(jfloat*)&rvalue);
1232 		break;
1233 
1234 	      case FFI_TYPE_DOUBLE:
1235 		PUSHD (rvalue);
1236 		break;
1237 
1238 	      case FFI_TYPE_SINT64:
1239 		PUSHL (*(jlong*)&rvalue);
1240 		break;
1241 
1242 	      default:
1243 		throw_internal_error ("unknown return type in invokeXXX");
1244 	      }
1245 	  }
1246       }
1247       NEXT_INSN;
1248 
1249     insn_aconst_null:
1250       PUSHA (NULL);
1251       NEXT_INSN;
1252 
1253     insn_iconst_m1:
1254       PUSHI (-1);
1255       NEXT_INSN;
1256 
1257     insn_iconst_0:
1258       PUSHI (0);
1259       NEXT_INSN;
1260 
1261     insn_iconst_1:
1262       PUSHI (1);
1263       NEXT_INSN;
1264 
1265     insn_iconst_2:
1266       PUSHI (2);
1267       NEXT_INSN;
1268 
1269     insn_iconst_3:
1270       PUSHI (3);
1271       NEXT_INSN;
1272 
1273     insn_iconst_4:
1274       PUSHI (4);
1275       NEXT_INSN;
1276 
1277     insn_iconst_5:
1278       PUSHI (5);
1279       NEXT_INSN;
1280 
1281     insn_lconst_0:
1282       PUSHL (0);
1283       NEXT_INSN;
1284 
1285     insn_lconst_1:
1286       PUSHL (1);
1287       NEXT_INSN;
1288 
1289     insn_fconst_0:
1290       PUSHF (0);
1291       NEXT_INSN;
1292 
1293     insn_fconst_1:
1294       PUSHF (1);
1295       NEXT_INSN;
1296 
1297     insn_fconst_2:
1298       PUSHF (2);
1299       NEXT_INSN;
1300 
1301     insn_dconst_0:
1302       PUSHD (0);
1303       NEXT_INSN;
1304 
1305     insn_dconst_1:
1306       PUSHD (1);
1307       NEXT_INSN;
1308 
1309     insn_bipush:
1310       // For direct threaded, bipush and sipush are the same.
1311 #ifndef DIRECT_THREADED
1312       PUSHI (GET1S ());
1313       NEXT_INSN;
1314 #endif /* DIRECT_THREADED */
1315     insn_sipush:
1316       PUSHI (GET2S ());
1317       NEXT_INSN;
1318 
1319     insn_ldc:
1320       // For direct threaded, ldc and ldc_w are the same.
1321 #ifndef DIRECT_THREADED
1322       PUSHA ((jobject) AVAL1U ());
1323       NEXT_INSN;
1324 #endif /* DIRECT_THREADED */
1325     insn_ldc_w:
1326       PUSHA ((jobject) AVAL2U ());
1327       NEXT_INSN;
1328 
1329     insn_ldc2_w:
1330       {
1331 	void *where = AVAL2UP ();
1332 	memcpy (sp, where, 2*sizeof (_Jv_word));
1333 	sp += 2;
1334       }
1335       NEXT_INSN;
1336 
1337     insn_lload:
1338       LOADL (GET1U ());
1339       NEXT_INSN;
1340 
1341     insn_fload:
1342       LOADF (GET1U ());
1343       NEXT_INSN;
1344 
1345     insn_dload:
1346       LOADD (GET1U ());
1347       NEXT_INSN;
1348 
1349     insn_aload:
1350       LOADA (GET1U ());
1351       NEXT_INSN;
1352 
1353     insn_iload_0:
1354       LOADI (0);
1355       NEXT_INSN;
1356 
1357     insn_iload_2:
1358       LOADI (2);
1359       NEXT_INSN;
1360 
1361     insn_iload_3:
1362       LOADI (3);
1363       NEXT_INSN;
1364 
1365     insn_lload_0:
1366       LOADL (0);
1367       NEXT_INSN;
1368 
1369     insn_lload_1:
1370       LOADL (1);
1371       NEXT_INSN;
1372 
1373     insn_lload_2:
1374       LOADL (2);
1375       NEXT_INSN;
1376 
1377     insn_lload_3:
1378       LOADL (3);
1379       NEXT_INSN;
1380 
1381     insn_fload_0:
1382       LOADF (0);
1383       NEXT_INSN;
1384 
1385     insn_fload_1:
1386       LOADF (1);
1387       NEXT_INSN;
1388 
1389     insn_fload_2:
1390       LOADF (2);
1391       NEXT_INSN;
1392 
1393     insn_fload_3:
1394       LOADF (3);
1395       NEXT_INSN;
1396 
1397     insn_dload_0:
1398       LOADD (0);
1399       NEXT_INSN;
1400 
1401     insn_dload_1:
1402       LOADD (1);
1403       NEXT_INSN;
1404 
1405     insn_dload_2:
1406       LOADD (2);
1407       NEXT_INSN;
1408 
1409     insn_dload_3:
1410       LOADD (3);
1411       NEXT_INSN;
1412 
1413     insn_aload_1:
1414       LOADA(1);
1415       NEXT_INSN;
1416 
1417     insn_aload_2:
1418       LOADA(2);
1419       NEXT_INSN;
1420 
1421     insn_aload_3:
1422       LOADA(3);
1423       NEXT_INSN;
1424 
1425     insn_iaload:
1426       {
1427 	jint index = POPI();
1428 	jintArray arr = (jintArray) POPA();
1429 	NULLARRAYCHECK (arr);
1430 	ARRAYBOUNDSCHECK (arr, index);
1431 	PUSHI( elements(arr)[index] );
1432       }
1433       NEXT_INSN;
1434 
1435     insn_laload:
1436       {
1437 	jint index = POPI();
1438 	jlongArray arr = (jlongArray) POPA();
1439 	NULLARRAYCHECK (arr);
1440 	ARRAYBOUNDSCHECK (arr, index);
1441 	PUSHL( elements(arr)[index] );
1442       }
1443       NEXT_INSN;
1444 
1445     insn_faload:
1446       {
1447 	jint index = POPI();
1448 	jfloatArray arr = (jfloatArray) POPA();
1449 	NULLARRAYCHECK (arr);
1450 	ARRAYBOUNDSCHECK (arr, index);
1451 	PUSHF( elements(arr)[index] );
1452       }
1453       NEXT_INSN;
1454 
1455     insn_daload:
1456       {
1457 	jint index = POPI();
1458 	jdoubleArray arr = (jdoubleArray) POPA();
1459 	NULLARRAYCHECK (arr);
1460 	ARRAYBOUNDSCHECK (arr, index);
1461 	PUSHD( elements(arr)[index] );
1462       }
1463       NEXT_INSN;
1464 
1465     insn_aaload:
1466       {
1467 	jint index = POPI();
1468 	jobjectArray arr = (jobjectArray) POPA();
1469 	NULLARRAYCHECK (arr);
1470 	ARRAYBOUNDSCHECK (arr, index);
1471 	PUSHA( elements(arr)[index] );
1472       }
1473       NEXT_INSN;
1474 
1475     insn_baload:
1476       {
1477 	jint index = POPI();
1478 	jbyteArray arr = (jbyteArray) POPA();
1479 	NULLARRAYCHECK (arr);
1480 	ARRAYBOUNDSCHECK (arr, index);
1481 	PUSHI( elements(arr)[index] );
1482       }
1483       NEXT_INSN;
1484 
1485     insn_caload:
1486       {
1487 	jint index = POPI();
1488 	jcharArray arr = (jcharArray) POPA();
1489 	NULLARRAYCHECK (arr);
1490 	ARRAYBOUNDSCHECK (arr, index);
1491 	PUSHI( elements(arr)[index] );
1492       }
1493       NEXT_INSN;
1494 
1495     insn_saload:
1496       {
1497 	jint index = POPI();
1498 	jshortArray arr = (jshortArray) POPA();
1499 	NULLARRAYCHECK (arr);
1500 	ARRAYBOUNDSCHECK (arr, index);
1501 	PUSHI( elements(arr)[index] );
1502       }
1503       NEXT_INSN;
1504 
1505     insn_istore:
1506       STOREI (GET1U ());
1507       NEXT_INSN;
1508 
1509     insn_lstore:
1510       STOREL (GET1U ());
1511       NEXT_INSN;
1512 
1513     insn_fstore:
1514       STOREF (GET1U ());
1515       NEXT_INSN;
1516 
1517     insn_dstore:
1518       STORED (GET1U ());
1519       NEXT_INSN;
1520 
1521     insn_astore:
1522       STOREA (GET1U ());
1523       NEXT_INSN;
1524 
1525     insn_istore_0:
1526       STOREI (0);
1527       NEXT_INSN;
1528 
1529     insn_istore_1:
1530       STOREI (1);
1531       NEXT_INSN;
1532 
1533     insn_istore_2:
1534       STOREI (2);
1535       NEXT_INSN;
1536 
1537     insn_istore_3:
1538       STOREI (3);
1539       NEXT_INSN;
1540 
1541     insn_lstore_0:
1542       STOREL (0);
1543       NEXT_INSN;
1544 
1545     insn_lstore_1:
1546       STOREL (1);
1547       NEXT_INSN;
1548 
1549     insn_lstore_2:
1550       STOREL (2);
1551       NEXT_INSN;
1552 
1553     insn_lstore_3:
1554       STOREL (3);
1555       NEXT_INSN;
1556 
1557     insn_fstore_0:
1558       STOREF (0);
1559       NEXT_INSN;
1560 
1561     insn_fstore_1:
1562       STOREF (1);
1563       NEXT_INSN;
1564 
1565     insn_fstore_2:
1566       STOREF (2);
1567       NEXT_INSN;
1568 
1569     insn_fstore_3:
1570       STOREF (3);
1571       NEXT_INSN;
1572 
1573     insn_dstore_0:
1574       STORED (0);
1575       NEXT_INSN;
1576 
1577     insn_dstore_1:
1578       STORED (1);
1579       NEXT_INSN;
1580 
1581     insn_dstore_2:
1582       STORED (2);
1583       NEXT_INSN;
1584 
1585     insn_dstore_3:
1586       STORED (3);
1587       NEXT_INSN;
1588 
1589     insn_astore_0:
1590       STOREA(0);
1591       NEXT_INSN;
1592 
1593     insn_astore_1:
1594       STOREA(1);
1595       NEXT_INSN;
1596 
1597     insn_astore_2:
1598       STOREA(2);
1599       NEXT_INSN;
1600 
1601     insn_astore_3:
1602       STOREA(3);
1603       NEXT_INSN;
1604 
1605     insn_iastore:
1606       {
1607 	jint value = POPI();
1608 	jint index  = POPI();
1609 	jintArray arr = (jintArray) POPA();
1610 	NULLARRAYCHECK (arr);
1611 	ARRAYBOUNDSCHECK (arr, index);
1612 	elements(arr)[index] = value;
1613       }
1614       NEXT_INSN;
1615 
1616     insn_lastore:
1617       {
1618 	jlong value = POPL();
1619 	jint index  = POPI();
1620 	jlongArray arr = (jlongArray) POPA();
1621 	NULLARRAYCHECK (arr);
1622 	ARRAYBOUNDSCHECK (arr, index);
1623 	elements(arr)[index] = value;
1624       }
1625       NEXT_INSN;
1626 
1627     insn_fastore:
1628       {
1629 	jfloat value = POPF();
1630 	jint index  = POPI();
1631 	jfloatArray arr = (jfloatArray) POPA();
1632 	NULLARRAYCHECK (arr);
1633 	ARRAYBOUNDSCHECK (arr, index);
1634 	elements(arr)[index] = value;
1635       }
1636       NEXT_INSN;
1637 
1638     insn_dastore:
1639       {
1640 	jdouble value = POPD();
1641 	jint index  = POPI();
1642 	jdoubleArray arr = (jdoubleArray) POPA();
1643 	NULLARRAYCHECK (arr);
1644 	ARRAYBOUNDSCHECK (arr, index);
1645 	elements(arr)[index] = value;
1646       }
1647       NEXT_INSN;
1648 
1649     insn_aastore:
1650       {
1651 	jobject value = POPA();
1652 	jint index  = POPI();
1653 	jobjectArray arr = (jobjectArray) POPA();
1654 	NULLARRAYCHECK (arr);
1655 	ARRAYBOUNDSCHECK (arr, index);
1656 	_Jv_CheckArrayStore (arr, value);
1657 	elements(arr)[index] = value;
1658       }
1659       NEXT_INSN;
1660 
1661     insn_bastore:
1662       {
1663 	jbyte value = (jbyte) POPI();
1664 	jint index  = POPI();
1665 	jbyteArray arr = (jbyteArray) POPA();
1666 	NULLARRAYCHECK (arr);
1667 	ARRAYBOUNDSCHECK (arr, index);
1668 	elements(arr)[index] = value;
1669       }
1670       NEXT_INSN;
1671 
1672     insn_castore:
1673       {
1674 	jchar value = (jchar) POPI();
1675 	jint index  = POPI();
1676 	jcharArray arr = (jcharArray) POPA();
1677 	NULLARRAYCHECK (arr);
1678 	ARRAYBOUNDSCHECK (arr, index);
1679 	elements(arr)[index] = value;
1680       }
1681       NEXT_INSN;
1682 
1683     insn_sastore:
1684       {
1685 	jshort value = (jshort) POPI();
1686 	jint index  = POPI();
1687 	jshortArray arr = (jshortArray) POPA();
1688 	NULLARRAYCHECK (arr);
1689 	ARRAYBOUNDSCHECK (arr, index);
1690 	elements(arr)[index] = value;
1691       }
1692       NEXT_INSN;
1693 
1694     insn_pop:
1695       sp -= 1;
1696       NEXT_INSN;
1697 
1698     insn_pop2:
1699       sp -= 2;
1700       NEXT_INSN;
1701 
1702     insn_dup:
1703       sp[0] = sp[-1];
1704       sp += 1;
1705       NEXT_INSN;
1706 
1707     insn_dup_x1:
1708       dupx (sp, 1, 1); sp+=1;
1709       NEXT_INSN;
1710 
1711     insn_dup_x2:
1712       dupx (sp, 1, 2); sp+=1;
1713       NEXT_INSN;
1714 
1715     insn_dup2:
1716       sp[0] = sp[-2];
1717       sp[1] = sp[-1];
1718       sp += 2;
1719       NEXT_INSN;
1720 
1721     insn_dup2_x1:
1722       dupx (sp, 2, 1); sp+=2;
1723       NEXT_INSN;
1724 
1725     insn_dup2_x2:
1726       dupx (sp, 2, 2); sp+=2;
1727       NEXT_INSN;
1728 
1729     insn_swap:
1730       {
1731 	jobject tmp1 = POPA();
1732 	jobject tmp2 = POPA();
1733 	PUSHA (tmp1);
1734 	PUSHA (tmp2);
1735       }
1736       NEXT_INSN;
1737 
1738     insn_iadd:
1739       BINOPI(+);
1740       NEXT_INSN;
1741 
1742     insn_ladd:
1743       BINOPL(+);
1744       NEXT_INSN;
1745 
1746     insn_fadd:
1747       BINOPF(+);
1748       NEXT_INSN;
1749 
1750     insn_dadd:
1751       BINOPD(+);
1752       NEXT_INSN;
1753 
1754     insn_isub:
1755       BINOPI(-);
1756       NEXT_INSN;
1757 
1758     insn_lsub:
1759       BINOPL(-);
1760       NEXT_INSN;
1761 
1762     insn_fsub:
1763       BINOPF(-);
1764       NEXT_INSN;
1765 
1766     insn_dsub:
1767       BINOPD(-);
1768       NEXT_INSN;
1769 
1770     insn_imul:
1771       BINOPI(*);
1772       NEXT_INSN;
1773 
1774     insn_lmul:
1775       BINOPL(*);
1776       NEXT_INSN;
1777 
1778     insn_fmul:
1779       BINOPF(*);
1780       NEXT_INSN;
1781 
1782     insn_dmul:
1783       BINOPD(*);
1784       NEXT_INSN;
1785 
1786     insn_idiv:
1787       {
1788 	jint value2 = POPI();
1789 	jint value1 = POPI();
1790 	jint res = _Jv_divI (value1, value2);
1791 	PUSHI (res);
1792       }
1793       NEXT_INSN;
1794 
1795     insn_ldiv:
1796       {
1797 	jlong value2 = POPL();
1798 	jlong value1 = POPL();
1799 	jlong res = _Jv_divJ (value1, value2);
1800 	PUSHL (res);
1801       }
1802       NEXT_INSN;
1803 
1804     insn_fdiv:
1805       {
1806 	jfloat value2 = POPF();
1807 	jfloat value1 = POPF();
1808 	jfloat res = value1 / value2;
1809 	PUSHF (res);
1810       }
1811       NEXT_INSN;
1812 
1813     insn_ddiv:
1814       {
1815 	jdouble value2 = POPD();
1816 	jdouble value1 = POPD();
1817 	jdouble res = value1 / value2;
1818 	PUSHD (res);
1819       }
1820       NEXT_INSN;
1821 
1822     insn_irem:
1823       {
1824 	jint value2 = POPI();
1825 	jint value1 =  POPI();
1826 	jint res = _Jv_remI (value1, value2);
1827 	PUSHI (res);
1828       }
1829       NEXT_INSN;
1830 
1831     insn_lrem:
1832       {
1833 	jlong value2 = POPL();
1834 	jlong value1 = POPL();
1835 	jlong res = _Jv_remJ (value1, value2);
1836 	PUSHL (res);
1837       }
1838       NEXT_INSN;
1839 
1840     insn_frem:
1841       {
1842 	jfloat value2 = POPF();
1843 	jfloat value1 = POPF();
1844 	jfloat res    = __ieee754_fmod (value1, value2);
1845 	PUSHF (res);
1846       }
1847       NEXT_INSN;
1848 
1849     insn_drem:
1850       {
1851 	jdouble value2 = POPD();
1852 	jdouble value1 = POPD();
1853 	jdouble res    = __ieee754_fmod (value1, value2);
1854 	PUSHD (res);
1855       }
1856       NEXT_INSN;
1857 
1858     insn_ineg:
1859       {
1860 	jint value = POPI();
1861 	PUSHI (value * -1);
1862       }
1863       NEXT_INSN;
1864 
1865     insn_lneg:
1866       {
1867 	jlong value = POPL();
1868 	PUSHL (value * -1);
1869       }
1870       NEXT_INSN;
1871 
1872     insn_fneg:
1873       {
1874 	jfloat value = POPF();
1875 	PUSHF (value * -1);
1876       }
1877       NEXT_INSN;
1878 
1879     insn_dneg:
1880       {
1881 	jdouble value = POPD();
1882 	PUSHD (value * -1);
1883       }
1884       NEXT_INSN;
1885 
1886     insn_ishl:
1887       {
1888 	jint shift = (POPI() & 0x1f);
1889 	jint value = POPI();
1890 	PUSHI (value << shift);
1891       }
1892       NEXT_INSN;
1893 
1894     insn_lshl:
1895       {
1896 	jint shift = (POPI() & 0x3f);
1897 	jlong value = POPL();
1898 	PUSHL (value << shift);
1899       }
1900       NEXT_INSN;
1901 
1902     insn_ishr:
1903       {
1904 	jint shift = (POPI() & 0x1f);
1905 	jint value = POPI();
1906 	PUSHI (value >> shift);
1907       }
1908       NEXT_INSN;
1909 
1910     insn_lshr:
1911       {
1912 	jint shift = (POPI() & 0x3f);
1913 	jlong value = POPL();
1914 	PUSHL (value >> shift);
1915       }
1916       NEXT_INSN;
1917 
1918     insn_iushr:
1919       {
1920 	jint shift = (POPI() & 0x1f);
1921 	_Jv_uint value = (_Jv_uint) POPI();
1922 	PUSHI ((jint) (value >> shift));
1923       }
1924       NEXT_INSN;
1925 
1926     insn_lushr:
1927       {
1928 	jint shift = (POPI() & 0x3f);
1929 	_Jv_ulong value = (_Jv_ulong) POPL();
1930 	PUSHL ((jlong) (value >> shift));
1931       }
1932       NEXT_INSN;
1933 
1934     insn_iand:
1935       BINOPI (&);
1936       NEXT_INSN;
1937 
1938     insn_land:
1939       BINOPL (&);
1940       NEXT_INSN;
1941 
1942     insn_ior:
1943       BINOPI (|);
1944       NEXT_INSN;
1945 
1946     insn_lor:
1947       BINOPL (|);
1948       NEXT_INSN;
1949 
1950     insn_ixor:
1951       BINOPI (^);
1952       NEXT_INSN;
1953 
1954     insn_lxor:
1955       BINOPL (^);
1956       NEXT_INSN;
1957 
1958     insn_iinc:
1959       {
1960 	jint index  = GET1U ();
1961 	jint amount = GET1S ();
1962 	locals[index].i += amount;
1963       }
1964       NEXT_INSN;
1965 
1966     insn_i2l:
1967       {jlong value = POPI(); PUSHL (value);}
1968       NEXT_INSN;
1969 
1970     insn_i2f:
1971       {jfloat value = POPI(); PUSHF (value);}
1972       NEXT_INSN;
1973 
1974     insn_i2d:
1975       {jdouble value = POPI(); PUSHD (value);}
1976       NEXT_INSN;
1977 
1978     insn_l2i:
1979       {jint value = POPL(); PUSHI (value);}
1980       NEXT_INSN;
1981 
1982     insn_l2f:
1983       {jfloat value = POPL(); PUSHF (value);}
1984       NEXT_INSN;
1985 
1986     insn_l2d:
1987       {jdouble value = POPL(); PUSHD (value);}
1988       NEXT_INSN;
1989 
1990     insn_f2i:
1991       {
1992 	using namespace java::lang;
1993 	jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1994 	PUSHI(value);
1995       }
1996       NEXT_INSN;
1997 
1998     insn_f2l:
1999       {
2000 	using namespace java::lang;
2001 	jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
2002 	PUSHL(value);
2003       }
2004       NEXT_INSN;
2005 
2006     insn_f2d:
2007       { jdouble value = POPF (); PUSHD(value); }
2008       NEXT_INSN;
2009 
2010     insn_d2i:
2011       {
2012 	using namespace java::lang;
2013 	jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
2014 	PUSHI(value);
2015       }
2016       NEXT_INSN;
2017 
2018     insn_d2l:
2019       {
2020 	using namespace java::lang;
2021 	jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
2022 	PUSHL(value);
2023       }
2024       NEXT_INSN;
2025 
2026     insn_d2f:
2027       { jfloat value = POPD (); PUSHF(value); }
2028       NEXT_INSN;
2029 
2030     insn_i2b:
2031       { jbyte value = POPI (); PUSHI(value); }
2032       NEXT_INSN;
2033 
2034     insn_i2c:
2035       { jchar value = POPI (); PUSHI(value); }
2036       NEXT_INSN;
2037 
2038     insn_i2s:
2039       { jshort value = POPI (); PUSHI(value); }
2040       NEXT_INSN;
2041 
2042     insn_lcmp:
2043       {
2044 	jlong value2 = POPL ();
2045 	jlong value1 = POPL ();
2046 	if (value1 > value2)
2047 	  { PUSHI (1); }
2048 	else if (value1 == value2)
2049 	  { PUSHI (0); }
2050 	else
2051 	  { PUSHI (-1); }
2052       }
2053       NEXT_INSN;
2054 
2055     insn_fcmpl:
2056       tmpval = -1;
2057       goto fcmp;
2058 
2059     insn_fcmpg:
2060       tmpval = 1;
2061 
2062     fcmp:
2063       {
2064 	jfloat value2 = POPF ();
2065 	jfloat value1 = POPF ();
2066 	if (value1 > value2)
2067 	  PUSHI (1);
2068 	else if (value1 == value2)
2069 	  PUSHI (0);
2070 	else if (value1 < value2)
2071 	  PUSHI (-1);
2072 	else
2073 	  PUSHI (tmpval);
2074       }
2075       NEXT_INSN;
2076 
2077     insn_dcmpl:
2078       tmpval = 1;
2079       goto dcmp;
2080 
2081     insn_dcmpg:
2082       tmpval = -1;
2083 
2084     dcmp:
2085       {
2086 	jdouble value2 = POPD ();
2087 	jdouble value1 = POPD ();
2088 	if (value1 > value2)
2089 	  PUSHI (1);
2090 	else if (value1 == value2)
2091 	  PUSHI (0);
2092 	else if (value1 < value2)
2093 	  PUSHI (-1);
2094 	else
2095 	  PUSHI (tmpval);
2096       }
2097       NEXT_INSN;
2098 
2099     insn_ifeq:
2100       {
2101 	if (POPI() == 0)
2102 	  TAKE_GOTO;
2103 	else
2104 	  SKIP_GOTO;
2105       }
2106       NEXT_INSN;
2107 
2108     insn_ifne:
2109       {
2110 	if (POPI() != 0)
2111 	  TAKE_GOTO;
2112 	else
2113 	  SKIP_GOTO;
2114       }
2115       NEXT_INSN;
2116 
2117     insn_iflt:
2118       {
2119 	if (POPI() < 0)
2120 	  TAKE_GOTO;
2121 	else
2122 	  SKIP_GOTO;
2123       }
2124       NEXT_INSN;
2125 
2126     insn_ifge:
2127       {
2128 	if (POPI() >= 0)
2129 	  TAKE_GOTO;
2130 	else
2131 	  SKIP_GOTO;
2132       }
2133       NEXT_INSN;
2134 
2135     insn_ifgt:
2136       {
2137 	if (POPI() > 0)
2138 	  TAKE_GOTO;
2139 	else
2140 	  SKIP_GOTO;
2141       }
2142       NEXT_INSN;
2143 
2144     insn_ifle:
2145       {
2146 	if (POPI() <= 0)
2147 	  TAKE_GOTO;
2148 	else
2149 	  SKIP_GOTO;
2150       }
2151       NEXT_INSN;
2152 
2153     insn_if_icmpeq:
2154       {
2155 	jint value2 = POPI();
2156 	jint value1 = POPI();
2157 	if (value1 == value2)
2158 	  TAKE_GOTO;
2159 	else
2160 	  SKIP_GOTO;
2161       }
2162       NEXT_INSN;
2163 
2164     insn_if_icmpne:
2165       {
2166 	jint value2 = POPI();
2167 	jint value1 = POPI();
2168 	if (value1 != value2)
2169 	  TAKE_GOTO;
2170 	else
2171 	  SKIP_GOTO;
2172       }
2173       NEXT_INSN;
2174 
2175     insn_if_icmplt:
2176       {
2177 	jint value2 = POPI();
2178 	jint value1 = POPI();
2179 	if (value1 < value2)
2180 	  TAKE_GOTO;
2181 	else
2182 	  SKIP_GOTO;
2183       }
2184       NEXT_INSN;
2185 
2186     insn_if_icmpge:
2187       {
2188 	jint value2 = POPI();
2189 	jint value1 = POPI();
2190 	if (value1 >= value2)
2191 	  TAKE_GOTO;
2192 	else
2193 	  SKIP_GOTO;
2194       }
2195       NEXT_INSN;
2196 
2197     insn_if_icmpgt:
2198       {
2199 	jint value2 = POPI();
2200 	jint value1 = POPI();
2201 	if (value1 > value2)
2202 	  TAKE_GOTO;
2203 	else
2204 	  SKIP_GOTO;
2205       }
2206       NEXT_INSN;
2207 
2208     insn_if_icmple:
2209       {
2210 	jint value2 = POPI();
2211 	jint value1 = POPI();
2212 	if (value1 <= value2)
2213 	  TAKE_GOTO;
2214 	else
2215 	  SKIP_GOTO;
2216       }
2217       NEXT_INSN;
2218 
2219     insn_if_acmpeq:
2220       {
2221 	jobject value2 = POPA();
2222 	jobject value1 = POPA();
2223 	if (value1 == value2)
2224 	  TAKE_GOTO;
2225 	else
2226 	  SKIP_GOTO;
2227       }
2228       NEXT_INSN;
2229 
2230     insn_if_acmpne:
2231       {
2232 	jobject value2 = POPA();
2233 	jobject value1 = POPA();
2234 	if (value1 != value2)
2235 	  TAKE_GOTO;
2236 	else
2237 	  SKIP_GOTO;
2238       }
2239       NEXT_INSN;
2240 
2241     insn_goto_w:
2242 #ifndef DIRECT_THREADED
2243       // For direct threaded, goto and goto_w are the same.
2244       pc = pc - 1 + get4 (pc);
2245       NEXT_INSN;
2246 #endif /* DIRECT_THREADED */
2247     insn_goto:
2248       TAKE_GOTO;
2249       NEXT_INSN;
2250 
2251     insn_jsr_w:
2252 #ifndef DIRECT_THREADED
2253       // For direct threaded, jsr and jsr_w are the same.
2254       {
2255 	pc_t next = pc - 1 + get4 (pc);
2256 	pc += 4;
2257 	PUSHA ((jobject) pc);
2258 	pc = next;
2259       }
2260       NEXT_INSN;
2261 #endif /* DIRECT_THREADED */
2262     insn_jsr:
2263       {
2264 	pc_t next = GOTO_VAL();
2265 	SKIP_GOTO;
2266 	PUSHA ((jobject) pc);
2267 	pc = next;
2268       }
2269       NEXT_INSN;
2270 
2271     insn_ret:
2272       {
2273 	jint index = GET1U ();
2274 	pc = (pc_t) PEEKA (index);
2275       }
2276       NEXT_INSN;
2277 
2278     insn_tableswitch:
2279       {
2280 #ifdef DIRECT_THREADED
2281 	void *def = (pc++)->datum;
2282 
2283 	int index = POPI();
2284 
2285 	jint low = INTVAL ();
2286 	jint high = INTVAL ();
2287 
2288 	if (index < low || index > high)
2289 	  pc = (insn_slot *) def;
2290 	else
2291 	  pc = (insn_slot *) ((pc + index - low)->datum);
2292 #else
2293 	pc_t base_pc = pc - 1;
2294 	int index = POPI ();
2295 
2296 	pc_t base = (pc_t) bytecode ();
2297 	while ((pc - base) % 4 != 0)
2298 	  ++pc;
2299 
2300 	jint def = get4 (pc);
2301 	jint low = get4 (pc + 4);
2302 	jint high = get4 (pc + 8);
2303 	if (index < low || index > high)
2304 	  pc = base_pc + def;
2305 	else
2306 	  pc = base_pc + get4 (pc + 4 * (index - low + 3));
2307 #endif /* DIRECT_THREADED */
2308       }
2309       NEXT_INSN;
2310 
2311     insn_lookupswitch:
2312       {
2313 #ifdef DIRECT_THREADED
2314 	void *def = (pc++)->insn;
2315 
2316 	int index = POPI();
2317 
2318 	jint npairs = INTVAL ();
2319 
2320 	int max = npairs - 1;
2321 	int min = 0;
2322 
2323 	// Simple binary search...
2324 	while (min < max)
2325 	  {
2326 	    int half = (min + max) / 2;
2327 	    int match = pc[2 * half].int_val;
2328 
2329 	    if (index == match)
2330 	      {
2331 		// Found it.
2332 		pc = (insn_slot *) pc[2 * half + 1].datum;
2333 		NEXT_INSN;
2334 	      }
2335 	    else if (index < match)
2336 	      // We can use HALF - 1 here because we check again on
2337 	      // loop exit.
2338 	      max = half - 1;
2339 	    else
2340 	      // We can use HALF + 1 here because we check again on
2341 	      // loop exit.
2342 	      min = half + 1;
2343 	  }
2344 	if (index == pc[2 * min].int_val)
2345 	  pc = (insn_slot *) pc[2 * min + 1].datum;
2346 	else
2347 	  pc = (insn_slot *) def;
2348 #else
2349 	unsigned char *base_pc = pc-1;
2350 	int index = POPI();
2351 
2352 	unsigned char* base = bytecode ();
2353 	while ((pc-base) % 4 != 0)
2354 	  ++pc;
2355 
2356 	jint def     = get4 (pc);
2357 	jint npairs  = get4 (pc+4);
2358 
2359 	int max = npairs-1;
2360 	int min = 0;
2361 
2362 	// Simple binary search...
2363 	while (min < max)
2364 	  {
2365 	    int half = (min+max)/2;
2366 	    int match = get4 (pc+ 4*(2 + 2*half));
2367 
2368 	    if (index == match)
2369 	      min = max = half;
2370 	    else if (index < match)
2371 	      // We can use HALF - 1 here because we check again on
2372 	      // loop exit.
2373 	      max = half - 1;
2374 	    else
2375 	      // We can use HALF + 1 here because we check again on
2376 	      // loop exit.
2377 	      min = half + 1;
2378 	  }
2379 
2380 	if (index == get4 (pc+ 4*(2 + 2*min)))
2381 	  pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
2382 	else
2383 	  pc = base_pc + def;
2384 #endif /* DIRECT_THREADED */
2385       }
2386       NEXT_INSN;
2387 
2388     insn_areturn:
2389       *(jobject *) retp = POPA ();
2390       return;
2391 
2392     insn_lreturn:
2393       *(jlong *) retp = POPL ();
2394       return;
2395 
2396     insn_freturn:
2397       *(jfloat *) retp = POPF ();
2398       return;
2399 
2400     insn_dreturn:
2401       *(jdouble *) retp = POPD ();
2402       return;
2403 
2404     insn_ireturn:
2405       *(jint *) retp = POPI ();
2406       return;
2407 
2408     insn_return:
2409       return;
2410 
2411     insn_getstatic:
2412       {
2413 	jint fieldref_index = GET2U ();
2414 	_Jv_ResolvePoolEntry (defining_class, fieldref_index);
2415 	_Jv_Field *field = pool_data[fieldref_index].field;
2416 
2417 	if ((field->flags & Modifier::STATIC) == 0)
2418 	  throw_incompatible_class_change_error
2419 	    (JvNewStringLatin1 ("field no longer static"));
2420 
2421 	jclass type = field->type;
2422 
2423 	// We rewrite the instruction once we discover what it refers
2424 	// to.
2425 	void *newinsn = NULL;
2426 	if (type->isPrimitive ())
2427 	  {
2428 	    switch (type->size_in_bytes)
2429 	      {
2430 	      case 1:
2431 		PUSHI (*(jbyte*) (field->u.addr));
2432 		newinsn = AMPAMP (getstatic_resolved_1);
2433 		break;
2434 
2435 	      case 2:
2436 		if (type == JvPrimClass (char))
2437 		  {
2438 		    PUSHI(*(jchar*) (field->u.addr));
2439 		    newinsn = AMPAMP (getstatic_resolved_char);
2440 		  }
2441 		else
2442 		  {
2443 		    PUSHI(*(jshort*) (field->u.addr));
2444 		    newinsn = AMPAMP (getstatic_resolved_short);
2445 		  }
2446 		break;
2447 
2448 	      case 4:
2449 		PUSHI(*(jint*) (field->u.addr));
2450 		newinsn = AMPAMP (getstatic_resolved_4);
2451 		break;
2452 
2453 	      case 8:
2454 		PUSHL(*(jlong*) (field->u.addr));
2455 		newinsn = AMPAMP (getstatic_resolved_8);
2456 		break;
2457 	      }
2458 	  }
2459 	else
2460 	  {
2461 	    PUSHA(*(jobject*) (field->u.addr));
2462 	    newinsn = AMPAMP (getstatic_resolved_obj);
2463 	  }
2464 
2465 #ifdef DIRECT_THREADED
2466 	pc[-2].insn = newinsn;
2467 	pc[-1].datum = field->u.addr;
2468 #endif /* DIRECT_THREADED */
2469       }
2470       NEXT_INSN;
2471 
2472 #ifdef DIRECT_THREADED
2473     getstatic_resolved_1:
2474       PUSHI (*(jbyte *) AVAL ());
2475       NEXT_INSN;
2476 
2477     getstatic_resolved_char:
2478       PUSHI (*(jchar *) AVAL ());
2479       NEXT_INSN;
2480 
2481     getstatic_resolved_short:
2482       PUSHI (*(jshort *) AVAL ());
2483       NEXT_INSN;
2484 
2485     getstatic_resolved_4:
2486       PUSHI (*(jint *) AVAL ());
2487       NEXT_INSN;
2488 
2489     getstatic_resolved_8:
2490       PUSHL (*(jlong *) AVAL ());
2491       NEXT_INSN;
2492 
2493     getstatic_resolved_obj:
2494       PUSHA (*(jobject *) AVAL ());
2495       NEXT_INSN;
2496 #endif /* DIRECT_THREADED */
2497 
2498     insn_getfield:
2499       {
2500 	jint fieldref_index = GET2U ();
2501 	_Jv_ResolvePoolEntry (defining_class, fieldref_index);
2502 	_Jv_Field *field = pool_data[fieldref_index].field;
2503 
2504 	if ((field->flags & Modifier::STATIC) != 0)
2505 	  throw_incompatible_class_change_error
2506 	    (JvNewStringLatin1 ("field is static"));
2507 
2508 	jclass type = field->type;
2509 	jint field_offset = field->u.boffset;
2510 	if (field_offset > 0xffff)
2511 	  throw new java::lang::VirtualMachineError;
2512 
2513 	jobject obj   = POPA();
2514 	NULLCHECK(obj);
2515 
2516 	void *newinsn = NULL;
2517 	if (type->isPrimitive ())
2518 	  {
2519 	    switch (type->size_in_bytes)
2520 	      {
2521 	      case 1:
2522 		PUSHI (*(jbyte*) ((char*)obj + field_offset));
2523 		newinsn = AMPAMP (getfield_resolved_1);
2524 		break;
2525 
2526 	      case 2:
2527 		if (type == JvPrimClass (char))
2528 		  {
2529 		    PUSHI (*(jchar*) ((char*)obj + field_offset));
2530 		    newinsn = AMPAMP (getfield_resolved_char);
2531 		  }
2532 		else
2533 		  {
2534 		    PUSHI (*(jshort*) ((char*)obj + field_offset));
2535 		    newinsn = AMPAMP (getfield_resolved_short);
2536 		  }
2537 		break;
2538 
2539 	      case 4:
2540 		PUSHI (*(jint*) ((char*)obj + field_offset));
2541 		newinsn = AMPAMP (getfield_resolved_4);
2542 		break;
2543 
2544 	      case 8:
2545 		PUSHL(*(jlong*) ((char*)obj + field_offset));
2546 		newinsn = AMPAMP (getfield_resolved_8);
2547 		break;
2548 	      }
2549 	  }
2550 	else
2551 	  {
2552 	    PUSHA(*(jobject*) ((char*)obj + field_offset));
2553 	    newinsn = AMPAMP (getfield_resolved_obj);
2554 	  }
2555 
2556 #ifdef DIRECT_THREADED
2557 	pc[-2].insn = newinsn;
2558 	pc[-1].int_val = field_offset;
2559 #endif /* DIRECT_THREADED */
2560       }
2561       NEXT_INSN;
2562 
2563 #ifdef DIRECT_THREADED
2564     getfield_resolved_1:
2565       {
2566 	char *obj = (char *) POPA ();
2567 	NULLCHECK (obj);
2568 	PUSHI (*(jbyte *) (obj + INTVAL ()));
2569       }
2570       NEXT_INSN;
2571 
2572     getfield_resolved_char:
2573       {
2574 	char *obj = (char *) POPA ();
2575 	NULLCHECK (obj);
2576 	PUSHI (*(jchar *) (obj + INTVAL ()));
2577       }
2578       NEXT_INSN;
2579 
2580     getfield_resolved_short:
2581       {
2582 	char *obj = (char *) POPA ();
2583 	NULLCHECK (obj);
2584 	PUSHI (*(jshort *) (obj + INTVAL ()));
2585       }
2586       NEXT_INSN;
2587 
2588     getfield_resolved_4:
2589       {
2590 	char *obj = (char *) POPA ();
2591 	NULLCHECK (obj);
2592 	PUSHI (*(jint *) (obj + INTVAL ()));
2593       }
2594       NEXT_INSN;
2595 
2596     getfield_resolved_8:
2597       {
2598 	char *obj = (char *) POPA ();
2599 	NULLCHECK (obj);
2600 	PUSHL (*(jlong *) (obj + INTVAL ()));
2601       }
2602       NEXT_INSN;
2603 
2604     getfield_resolved_obj:
2605       {
2606 	char *obj = (char *) POPA ();
2607 	NULLCHECK (obj);
2608 	PUSHA (*(jobject *) (obj + INTVAL ()));
2609       }
2610       NEXT_INSN;
2611 #endif /* DIRECT_THREADED */
2612 
2613     insn_putstatic:
2614       {
2615 	jint fieldref_index = GET2U ();
2616 	_Jv_ResolvePoolEntry (defining_class, fieldref_index);
2617 	_Jv_Field *field = pool_data[fieldref_index].field;
2618 
2619 	jclass type = field->type;
2620 
2621 	// ResolvePoolEntry cannot check this
2622 	if ((field->flags & Modifier::STATIC) == 0)
2623 	  throw_incompatible_class_change_error
2624 	    (JvNewStringLatin1 ("field no longer static"));
2625 
2626 	void *newinsn = NULL;
2627 	if (type->isPrimitive ())
2628 	  {
2629 	    switch (type->size_in_bytes)
2630 	      {
2631 	      case 1:
2632 		{
2633 		  jint value = POPI();
2634 		  *(jbyte*) (field->u.addr) = value;
2635 		  newinsn = AMPAMP (putstatic_resolved_1);
2636 		  break;
2637 		}
2638 
2639 	      case 2:
2640 		{
2641 		  jint value = POPI();
2642 		  *(jchar*) (field->u.addr) = value;
2643 		  newinsn = AMPAMP (putstatic_resolved_2);
2644 		  break;
2645 		}
2646 
2647 	      case 4:
2648 		{
2649 		  jint value = POPI();
2650 		  *(jint*) (field->u.addr) = value;
2651 		  newinsn = AMPAMP (putstatic_resolved_4);
2652 		  break;
2653 		}
2654 
2655 	      case 8:
2656 		{
2657 		  jlong value = POPL();
2658 		  *(jlong*) (field->u.addr) = value;
2659 		  newinsn = AMPAMP (putstatic_resolved_8);
2660 		  break;
2661 		}
2662 	      }
2663 	  }
2664 	else
2665 	  {
2666 	    jobject value = POPA();
2667 	    *(jobject*) (field->u.addr) = value;
2668 	    newinsn = AMPAMP (putstatic_resolved_obj);
2669 	  }
2670 
2671 #ifdef DIRECT_THREADED
2672 	pc[-2].insn = newinsn;
2673 	pc[-1].datum = field->u.addr;
2674 #endif /* DIRECT_THREADED */
2675       }
2676       NEXT_INSN;
2677 
2678 #ifdef DIRECT_THREADED
2679     putstatic_resolved_1:
2680       *(jbyte *) AVAL () = POPI ();
2681       NEXT_INSN;
2682 
2683     putstatic_resolved_2:
2684       *(jchar *) AVAL () = POPI ();
2685       NEXT_INSN;
2686 
2687     putstatic_resolved_4:
2688       *(jint *) AVAL () = POPI ();
2689       NEXT_INSN;
2690 
2691     putstatic_resolved_8:
2692       *(jlong *) AVAL () = POPL ();
2693       NEXT_INSN;
2694 
2695     putstatic_resolved_obj:
2696       *(jobject *) AVAL () = POPA ();
2697       NEXT_INSN;
2698 #endif /* DIRECT_THREADED */
2699 
2700     insn_putfield:
2701       {
2702 	jint fieldref_index = GET2U ();
2703 	_Jv_ResolvePoolEntry (defining_class, fieldref_index);
2704 	_Jv_Field *field = pool_data[fieldref_index].field;
2705 
2706 	jclass type = field->type;
2707 
2708 	if ((field->flags & Modifier::STATIC) != 0)
2709 	  throw_incompatible_class_change_error
2710 	    (JvNewStringLatin1 ("field is static"));
2711 
2712 	jint field_offset = field->u.boffset;
2713 	if (field_offset > 0xffff)
2714 	  throw new java::lang::VirtualMachineError;
2715 
2716 	void *newinsn = NULL;
2717 	if (type->isPrimitive ())
2718 	  {
2719 	    switch (type->size_in_bytes)
2720 	      {
2721 	      case 1:
2722 		{
2723 		  jint    value = POPI();
2724 		  jobject obj   = POPA();
2725 		  NULLCHECK(obj);
2726 		  *(jbyte*) ((char*)obj + field_offset) = value;
2727 		  newinsn = AMPAMP (putfield_resolved_1);
2728 		  break;
2729 		}
2730 
2731 	      case 2:
2732 		{
2733 		  jint    value = POPI();
2734 		  jobject obj   = POPA();
2735 		  NULLCHECK(obj);
2736 		  *(jchar*) ((char*)obj + field_offset) = value;
2737 		  newinsn = AMPAMP (putfield_resolved_2);
2738 		  break;
2739 		}
2740 
2741 	      case 4:
2742 		{
2743 		  jint    value = POPI();
2744 		  jobject obj   = POPA();
2745 		  NULLCHECK(obj);
2746 		  *(jint*) ((char*)obj + field_offset) = value;
2747 		  newinsn = AMPAMP (putfield_resolved_4);
2748 		  break;
2749 		}
2750 
2751 	      case 8:
2752 		{
2753 		  jlong   value = POPL();
2754 		  jobject obj   = POPA();
2755 		  NULLCHECK(obj);
2756 		  *(jlong*) ((char*)obj + field_offset) = value;
2757 		  newinsn = AMPAMP (putfield_resolved_8);
2758 		  break;
2759 		}
2760 	      }
2761 	  }
2762 	else
2763 	  {
2764 	    jobject value = POPA();
2765 	    jobject obj   = POPA();
2766 	    NULLCHECK(obj);
2767 	    *(jobject*) ((char*)obj + field_offset) = value;
2768 	    newinsn = AMPAMP (putfield_resolved_obj);
2769 	  }
2770 
2771 #ifdef DIRECT_THREADED
2772 	pc[-2].insn = newinsn;
2773 	pc[-1].int_val = field_offset;
2774 #endif /* DIRECT_THREADED */
2775       }
2776       NEXT_INSN;
2777 
2778 #ifdef DIRECT_THREADED
2779     putfield_resolved_1:
2780       {
2781 	jint val = POPI ();
2782 	char *obj = (char *) POPA ();
2783 	NULLCHECK (obj);
2784 	*(jbyte *) (obj + INTVAL ()) = val;
2785       }
2786       NEXT_INSN;
2787 
2788     putfield_resolved_2:
2789       {
2790 	jint val = POPI ();
2791 	char *obj = (char *) POPA ();
2792 	NULLCHECK (obj);
2793 	*(jchar *) (obj + INTVAL ()) = val;
2794       }
2795       NEXT_INSN;
2796 
2797     putfield_resolved_4:
2798       {
2799 	jint val = POPI ();
2800 	char *obj = (char *) POPA ();
2801 	NULLCHECK (obj);
2802 	*(jint *) (obj + INTVAL ()) = val;
2803       }
2804       NEXT_INSN;
2805 
2806     putfield_resolved_8:
2807       {
2808 	jlong val = POPL ();
2809 	char *obj = (char *) POPA ();
2810 	NULLCHECK (obj);
2811 	*(jlong *) (obj + INTVAL ()) = val;
2812       }
2813       NEXT_INSN;
2814 
2815     putfield_resolved_obj:
2816       {
2817 	jobject val = POPA ();
2818 	char *obj = (char *) POPA ();
2819 	NULLCHECK (obj);
2820 	*(jobject *) (obj + INTVAL ()) = val;
2821       }
2822       NEXT_INSN;
2823 #endif /* DIRECT_THREADED */
2824 
2825     insn_invokespecial:
2826       {
2827 	int index = GET2U ();
2828 
2829 	rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2830 
2831 	sp -= rmeth->stack_item_count;
2832 
2833 	// We don't use NULLCHECK here because we can't rely on that
2834 	// working for <init>.  So instead we do an explicit test.
2835 	if (! sp[0].o)
2836 	  throw new java::lang::NullPointerException;
2837 
2838 	fun = (void (*)()) rmeth->method->ncode;
2839 
2840 #ifdef DIRECT_THREADED
2841 	// Rewrite instruction so that we use a faster pre-resolved
2842 	// method.
2843 	pc[-2].insn = &&invokespecial_resolved;
2844 	pc[-1].datum = rmeth;
2845 #endif /* DIRECT_THREADED */
2846       }
2847       goto perform_invoke;
2848 
2849 #ifdef DIRECT_THREADED
2850     invokespecial_resolved:
2851       {
2852 	rmeth = (_Jv_ResolvedMethod *) AVAL ();
2853 	sp -= rmeth->stack_item_count;
2854 	// We don't use NULLCHECK here because we can't rely on that
2855 	// working for <init>.  So instead we do an explicit test.
2856 	if (! sp[0].o)
2857 	  throw new java::lang::NullPointerException;
2858 	fun = (void (*)()) rmeth->method->ncode;
2859       }
2860       goto perform_invoke;
2861 #endif /* DIRECT_THREADED */
2862 
2863     insn_invokestatic:
2864       {
2865 	int index = GET2U ();
2866 
2867 	rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2868 
2869 	sp -= rmeth->stack_item_count;
2870 
2871 	fun = (void (*)()) rmeth->method->ncode;
2872 
2873 #ifdef DIRECT_THREADED
2874 	// Rewrite instruction so that we use a faster pre-resolved
2875 	// method.
2876 	pc[-2].insn = &&invokestatic_resolved;
2877 	pc[-1].datum = rmeth;
2878 #endif /* DIRECT_THREADED */
2879       }
2880       goto perform_invoke;
2881 
2882 #ifdef DIRECT_THREADED
2883     invokestatic_resolved:
2884       {
2885 	rmeth = (_Jv_ResolvedMethod *) AVAL ();
2886 	sp -= rmeth->stack_item_count;
2887 	fun = (void (*)()) rmeth->method->ncode;
2888       }
2889       goto perform_invoke;
2890 #endif /* DIRECT_THREADED */
2891 
2892     insn_invokeinterface:
2893       {
2894 	int index = GET2U ();
2895 
2896 	rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2897 
2898 	sp -= rmeth->stack_item_count;
2899 
2900 	jobject rcv = sp[0].o;
2901 
2902 	NULLCHECK (rcv);
2903 
2904 	fun = (void (*)())
2905 	  _Jv_LookupInterfaceMethod (rcv->getClass (),
2906 				     rmeth->method->name,
2907 				     rmeth->method->signature);
2908 
2909 #ifdef DIRECT_THREADED
2910 	// Rewrite instruction so that we use a faster pre-resolved
2911 	// method.
2912 	pc[-2].insn = &&invokeinterface_resolved;
2913 	pc[-1].datum = rmeth;
2914 #else
2915 	// Skip dummy bytes.
2916 	pc += 2;
2917 #endif /* DIRECT_THREADED */
2918       }
2919       goto perform_invoke;
2920 
2921 #ifdef DIRECT_THREADED
2922     invokeinterface_resolved:
2923       {
2924 	rmeth = (_Jv_ResolvedMethod *) AVAL ();
2925 	sp -= rmeth->stack_item_count;
2926 	jobject rcv = sp[0].o;
2927 	NULLCHECK (rcv);
2928 	fun = (void (*)())
2929 	  _Jv_LookupInterfaceMethod (rcv->getClass (),
2930 				     rmeth->method->name,
2931 				     rmeth->method->signature);
2932       }
2933       goto perform_invoke;
2934 #endif /* DIRECT_THREADED */
2935 
2936     insn_new:
2937       {
2938 	int index = GET2U ();
2939 	jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2940 	// We initialize here because otherwise `size_in_bytes' may
2941 	// not be set correctly, leading us to pass `0' as the size.
2942 	// FIXME: fix in the allocator?  There is a PR for this.
2943 	_Jv_InitClass (klass);
2944 	jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
2945 	PUSHA (res);
2946 
2947 #ifdef DIRECT_THREADED
2948 	pc[-2].insn = &&new_resolved;
2949 	pc[-1].datum = klass;
2950 #endif /* DIRECT_THREADED */
2951       }
2952       NEXT_INSN;
2953 
2954 #ifdef DIRECT_THREADED
2955     new_resolved:
2956       {
2957 	jclass klass = (jclass) AVAL ();
2958 	jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
2959 	PUSHA (res);
2960       }
2961       NEXT_INSN;
2962 #endif /* DIRECT_THREADED */
2963 
2964     insn_newarray:
2965       {
2966 	int atype = GET1U ();
2967 	int size  = POPI();
2968 	jobject result = _Jv_NewArray (atype, size);
2969 	PUSHA (result);
2970       }
2971       NEXT_INSN;
2972 
2973     insn_anewarray:
2974       {
2975 	int index = GET2U ();
2976 	jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2977 	int size  = POPI();
2978 	jobject result = _Jv_NewObjectArray (size, klass, 0);
2979 	PUSHA (result);
2980 
2981 #ifdef DIRECT_THREADED
2982 	pc[-2].insn = &&anewarray_resolved;
2983 	pc[-1].datum = klass;
2984 #endif /* DIRECT_THREADED */
2985       }
2986       NEXT_INSN;
2987 
2988 #ifdef DIRECT_THREADED
2989     anewarray_resolved:
2990       {
2991 	jclass klass = (jclass) AVAL ();
2992 	int size = POPI ();
2993 	jobject result = _Jv_NewObjectArray (size, klass, 0);
2994 	PUSHA (result);
2995       }
2996       NEXT_INSN;
2997 #endif /* DIRECT_THREADED */
2998 
2999     insn_arraylength:
3000       {
3001 	__JArray *arr = (__JArray*)POPA();
3002 	NULLARRAYCHECK (arr);
3003 	PUSHI (arr->length);
3004       }
3005       NEXT_INSN;
3006 
3007     insn_athrow:
3008       {
3009 	jobject value = POPA();
3010 	throw static_cast<jthrowable>(value);
3011       }
3012       NEXT_INSN;
3013 
3014     insn_checkcast:
3015       {
3016 	jobject value = POPA();
3017 	jint index = GET2U ();
3018 	jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
3019 
3020 	if (value != NULL && ! to->isInstance (value))
3021 	  throw new java::lang::ClassCastException (to->getName());
3022 
3023 	PUSHA (value);
3024 
3025 #ifdef DIRECT_THREADED
3026 	pc[-2].insn = &&checkcast_resolved;
3027 	pc[-1].datum = to;
3028 #endif /* DIRECT_THREADED */
3029       }
3030       NEXT_INSN;
3031 
3032 #ifdef DIRECT_THREADED
3033     checkcast_resolved:
3034       {
3035 	jobject value = POPA ();
3036 	jclass to = (jclass) AVAL ();
3037 	if (value != NULL && ! to->isInstance (value))
3038 	  throw new java::lang::ClassCastException (to->getName());
3039 	PUSHA (value);
3040       }
3041       NEXT_INSN;
3042 #endif /* DIRECT_THREADED */
3043 
3044     insn_instanceof:
3045       {
3046 	jobject value = POPA();
3047 	jint index = GET2U ();
3048 	jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
3049 	PUSHI (to->isInstance (value));
3050 
3051 #ifdef DIRECT_THREADED
3052 	pc[-2].insn = &&instanceof_resolved;
3053 	pc[-1].datum = to;
3054 #endif /* DIRECT_THREADED */
3055       }
3056       NEXT_INSN;
3057 
3058 #ifdef DIRECT_THREADED
3059     instanceof_resolved:
3060       {
3061 	jobject value = POPA ();
3062 	jclass to = (jclass) AVAL ();
3063 	PUSHI (to->isInstance (value));
3064       }
3065       NEXT_INSN;
3066 #endif /* DIRECT_THREADED */
3067 
3068     insn_monitorenter:
3069       {
3070 	jobject value = POPA();
3071 	NULLCHECK(value);
3072 	_Jv_MonitorEnter (value);
3073       }
3074       NEXT_INSN;
3075 
3076     insn_monitorexit:
3077       {
3078 	jobject value = POPA();
3079 	NULLCHECK(value);
3080 	_Jv_MonitorExit (value);
3081       }
3082       NEXT_INSN;
3083 
3084     insn_ifnull:
3085       {
3086 	jobject val = POPA();
3087 	if (val == NULL)
3088 	  TAKE_GOTO;
3089 	else
3090 	  SKIP_GOTO;
3091       }
3092       NEXT_INSN;
3093 
3094     insn_ifnonnull:
3095       {
3096 	jobject val = POPA();
3097 	if (val != NULL)
3098 	  TAKE_GOTO;
3099 	else
3100 	  SKIP_GOTO;
3101       }
3102       NEXT_INSN;
3103 
3104     insn_multianewarray:
3105       {
3106 	int kind_index = GET2U ();
3107 	int dim        = GET1U ();
3108 
3109 	jclass type
3110 	  = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
3111 	jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
3112 
3113 	for (int i = dim - 1; i >= 0; i--)
3114 	  {
3115 	    sizes[i] = POPI ();
3116 	  }
3117 
3118 	jobject res    = _Jv_NewMultiArray (type,dim, sizes);
3119 
3120 	PUSHA (res);
3121       }
3122       NEXT_INSN;
3123 
3124 #ifndef DIRECT_THREADED
3125     insn_wide:
3126       {
3127 	jint the_mod_op = get1u (pc++);
3128 	jint wide       = get2u (pc); pc += 2;
3129 
3130 	switch (the_mod_op)
3131 	  {
3132 	  case op_istore:
3133 	    STOREI (wide);
3134 	    NEXT_INSN;
3135 
3136 	  case op_fstore:
3137 	    STOREF (wide);
3138 	    NEXT_INSN;
3139 
3140 	  case op_astore:
3141 	    STOREA (wide);
3142 	    NEXT_INSN;
3143 
3144 	  case op_lload:
3145 	    LOADL (wide);
3146 	    NEXT_INSN;
3147 
3148 	  case op_dload:
3149 	    LOADD (wide);
3150 	    NEXT_INSN;
3151 
3152 	  case op_iload:
3153 	    LOADI (wide);
3154 	    NEXT_INSN;
3155 
3156 	  case op_aload:
3157 	    LOADA (wide);
3158 	    NEXT_INSN;
3159 
3160 	  case op_lstore:
3161 	    STOREL (wide);
3162 	    NEXT_INSN;
3163 
3164 	  case op_dstore:
3165 	    STORED (wide);
3166 	    NEXT_INSN;
3167 
3168 	  case op_ret:
3169 	    pc = (unsigned char*) PEEKA (wide);
3170 	    NEXT_INSN;
3171 
3172 	  case op_iinc:
3173 	    {
3174 	      jint amount = get2s (pc); pc += 2;
3175 	      jint value = PEEKI (wide);
3176 	      POKEI (wide, value+amount);
3177 	    }
3178 	    NEXT_INSN;
3179 
3180 	  default:
3181 	    throw_internal_error ("illegal bytecode modified by wide");
3182 	  }
3183 
3184       }
3185 #endif /* DIRECT_THREADED */
3186     }
3187   catch (java::lang::Throwable *ex)
3188     {
3189 #ifdef DIRECT_THREADED
3190       void *logical_pc = (void *) ((insn_slot *) pc - 1);
3191 #else
3192       int logical_pc = pc - 1 - bytecode ();
3193 #endif
3194       _Jv_InterpException *exc = exceptions ();
3195       jclass exc_class = ex->getClass ();
3196 
3197       for (int i = 0; i < exc_count; i++)
3198 	{
3199 	  if (PCVAL (exc[i].start_pc) <= logical_pc
3200 	      && logical_pc < PCVAL (exc[i].end_pc))
3201 	    {
3202 #ifdef DIRECT_THREADED
3203 	      jclass handler = (jclass) exc[i].handler_type.p;
3204 #else
3205 	      jclass handler = NULL;
3206 	      if (exc[i].handler_type.i != 0)
3207 		handler = (_Jv_ResolvePoolEntry (defining_class,
3208 						 exc[i].handler_type.i)).clazz;
3209 #endif /* DIRECT_THREADED */
3210 
3211 	      if (handler == NULL || handler->isAssignableFrom (exc_class))
3212 		{
3213 #ifdef DIRECT_THREADED
3214 		  pc = (insn_slot *) exc[i].handler_pc.p;
3215 #else
3216 		  pc = bytecode () + exc[i].handler_pc.i;
3217 #endif /* DIRECT_THREADED */
3218 		  sp = stack;
3219 		  sp++->o = ex; // Push exception.
3220 		  NEXT_INSN;
3221 		}
3222 	    }
3223 	}
3224 
3225       // No handler, so re-throw.
3226       throw ex;
3227     }
3228 }
3229 
3230 // This function exists so that the stack-tracing code can find the
3231 // boundaries of the interpreter.
3232 void
_Jv_EndOfInterpreter(void)3233 _Jv_EndOfInterpreter (void)
3234 {
3235 }
3236 
3237 static void
throw_internal_error(char * msg)3238 throw_internal_error (char *msg)
3239 {
3240   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
3241 }
3242 
3243 static void
throw_incompatible_class_change_error(jstring msg)3244 throw_incompatible_class_change_error (jstring msg)
3245 {
3246   throw new java::lang::IncompatibleClassChangeError (msg);
3247 }
3248 
3249 #ifndef HANDLE_SEGV
3250 static java::lang::NullPointerException *null_pointer_exc;
3251 static void
throw_null_pointer_exception()3252 throw_null_pointer_exception ()
3253 {
3254   if (null_pointer_exc == NULL)
3255     null_pointer_exc = new java::lang::NullPointerException;
3256 
3257   throw null_pointer_exc;
3258 }
3259 #endif
3260 
3261 #endif // INTERPRETER
3262