OSDN Git Service

2008-08-22 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / interpret-run.cc
1 // interpret-run.cc - Code to interpret bytecode
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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 /* This file is meant only to be included in interpret.cc, it should not be
12  * compiled directly.   */
13
14   using namespace java::lang::reflect;
15   
16   pc_t pc = NULL;
17
18   // FRAME_DESC registers this particular invocation as the top-most
19   // interpreter frame.  This lets the stack tracing code (for
20   // Throwable) print information about the method being interpreted
21   // rather than about the interpreter itself.  FRAME_DESC has a
22   // destructor so it cleans up automatically when the interpreter
23   // returns.
24   java::lang::Thread *thread = java::lang::Thread::currentThread();
25   
26 #ifdef DEBUG
27   _Jv_InterpFrame frame_desc (meth, thread, NULL, &pc);
28 #else
29   _Jv_InterpFrame frame_desc (meth, thread);
30 #endif
31
32   _Jv_word stack[meth->max_stack];
33   _Jv_word *sp = stack;
34
35   _Jv_word locals[meth->max_locals];
36
37 #ifdef DEBUG
38   // This is the information needed to get and set local variables with
39   // proper type checking.
40   frame_desc.locals = locals;
41   char locals_type[meth->max_locals];
42   frame_desc.locals_type = locals_type;
43   
44   // Set all slots as invalid until they are written to.
45   memset (locals_type, 'x', meth->max_locals);
46   
47   // We need to set the local variable types for the method arguments since
48   // they are valid at invocation.
49   
50   _Jv_Method *method = meth->get_method ();
51   int type_ctr = 0;
52   
53   // If the method is non-static, we need to set the type for the "this" pointer.
54   if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
55     {
56       if (args)
57         {
58           // Set the "this" pointer for this frame.
59           _Jv_word *this_ptr = reinterpret_cast<_Jv_word *> (args);
60           frame_desc.obj_ptr = this_ptr[0].o;
61         }
62
63       frame_desc.locals_type[0] = 'o';
64       type_ctr++;
65     }
66   
67   // Now parse the method signature to set the types of the other arguments.  
68   int sig_len = method->signature->len ();
69   char *signature = method->signature->chars ();
70   for (int i = 1; signature[i] != ')' && i <= sig_len; i++)
71     {
72       if (signature[i] == 'Z' || signature[i] == 'B' || signature[i] == 'C' 
73           || signature[i] == 'S' || signature[i] == 'I')
74         {
75           frame_desc.locals_type[type_ctr] = 'i';
76           type_ctr++;
77           continue;
78         }
79       else if (signature[i] == 'F')
80         {
81           frame_desc.locals_type[type_ctr] = 'f';
82           type_ctr++;
83           continue;
84         }
85       else if (signature[i] == 'J')
86         {
87           frame_desc.locals_type[type_ctr] = 'l';
88           frame_desc.locals_type[type_ctr+1] = 'x';
89           type_ctr += 2;
90           continue;
91         }
92       else if (signature[i] == 'D')
93         {
94           frame_desc.locals_type[type_ctr] = 'd';
95           frame_desc.locals_type[type_ctr+1] = 'x';
96           type_ctr += 2;
97           continue;
98         }
99       else if (signature[i] == 'L')
100         {
101           frame_desc.locals_type[type_ctr] = 'o';
102           type_ctr++;
103           while (signature[i] != ';')
104             i++;
105           continue;
106         }
107       else if (signature[i] == '[')
108         {
109           frame_desc.locals_type[type_ctr] = 'o';
110           type_ctr++;
111           
112           // Ignore multi-dimensional arrays.
113           while (signature[i] == '[')
114             i++;
115           
116           // Check for an object array
117           if (signature[i] == 'L')
118             {
119               while (signature[i] != ';')
120                 i++;
121             }
122           continue;
123         }
124     }
125 #endif /* DEBUG */
126
127 #define INSN_LABEL(op) &&insn_##op
128
129   static const void *const insn_target[] = 
130   {
131     INSN_LABEL(nop),
132     INSN_LABEL(aconst_null),
133     INSN_LABEL(iconst_m1),
134     INSN_LABEL(iconst_0),
135     INSN_LABEL(iconst_1),
136     INSN_LABEL(iconst_2),
137     INSN_LABEL(iconst_3),
138     INSN_LABEL(iconst_4),
139     INSN_LABEL(iconst_5),
140     INSN_LABEL(lconst_0),
141     INSN_LABEL(lconst_1),
142     INSN_LABEL(fconst_0),
143     INSN_LABEL(fconst_1),
144     INSN_LABEL(fconst_2),
145     INSN_LABEL(dconst_0),
146     INSN_LABEL(dconst_1),
147     INSN_LABEL(bipush),
148     INSN_LABEL(sipush),
149     INSN_LABEL(ldc),
150     INSN_LABEL(ldc_w),
151     INSN_LABEL(ldc2_w),
152     INSN_LABEL(iload),
153     INSN_LABEL(lload),
154     INSN_LABEL(fload),
155     INSN_LABEL(dload),
156     INSN_LABEL(aload),
157     INSN_LABEL(iload_0),
158     INSN_LABEL(iload_1),
159     INSN_LABEL(iload_2),
160     INSN_LABEL(iload_3),
161     INSN_LABEL(lload_0),
162     INSN_LABEL(lload_1),
163     INSN_LABEL(lload_2),
164     INSN_LABEL(lload_3),
165     INSN_LABEL(fload_0),
166     INSN_LABEL(fload_1),
167     INSN_LABEL(fload_2),
168     INSN_LABEL(fload_3),
169     INSN_LABEL(dload_0),
170     INSN_LABEL(dload_1),
171     INSN_LABEL(dload_2),
172     INSN_LABEL(dload_3),
173     INSN_LABEL(aload_0),
174     INSN_LABEL(aload_1),
175     INSN_LABEL(aload_2),
176     INSN_LABEL(aload_3),
177     INSN_LABEL(iaload),
178     INSN_LABEL(laload),
179     INSN_LABEL(faload),
180     INSN_LABEL(daload),
181     INSN_LABEL(aaload),
182     INSN_LABEL(baload),
183     INSN_LABEL(caload),
184     INSN_LABEL(saload),
185     INSN_LABEL(istore),
186     INSN_LABEL(lstore),
187     INSN_LABEL(fstore),
188     INSN_LABEL(dstore),
189     INSN_LABEL(astore),
190     INSN_LABEL(istore_0),
191     INSN_LABEL(istore_1),
192     INSN_LABEL(istore_2),
193     INSN_LABEL(istore_3),
194     INSN_LABEL(lstore_0),
195     INSN_LABEL(lstore_1),
196     INSN_LABEL(lstore_2),
197     INSN_LABEL(lstore_3),
198     INSN_LABEL(fstore_0),
199     INSN_LABEL(fstore_1),
200     INSN_LABEL(fstore_2),
201     INSN_LABEL(fstore_3),
202     INSN_LABEL(dstore_0),
203     INSN_LABEL(dstore_1),
204     INSN_LABEL(dstore_2),
205     INSN_LABEL(dstore_3),
206     INSN_LABEL(astore_0),
207     INSN_LABEL(astore_1),
208     INSN_LABEL(astore_2),
209     INSN_LABEL(astore_3),
210     INSN_LABEL(iastore),
211     INSN_LABEL(lastore),
212     INSN_LABEL(fastore),
213     INSN_LABEL(dastore),
214     INSN_LABEL(aastore),
215     INSN_LABEL(bastore),
216     INSN_LABEL(castore),
217     INSN_LABEL(sastore),
218     INSN_LABEL(pop),
219     INSN_LABEL(pop2),
220     INSN_LABEL(dup),
221     INSN_LABEL(dup_x1),
222     INSN_LABEL(dup_x2),
223     INSN_LABEL(dup2),
224     INSN_LABEL(dup2_x1),
225     INSN_LABEL(dup2_x2),
226     INSN_LABEL(swap),
227     INSN_LABEL(iadd),
228     INSN_LABEL(ladd),
229     INSN_LABEL(fadd),
230     INSN_LABEL(dadd),
231     INSN_LABEL(isub),
232     INSN_LABEL(lsub),
233     INSN_LABEL(fsub),
234     INSN_LABEL(dsub),
235     INSN_LABEL(imul),
236     INSN_LABEL(lmul),
237     INSN_LABEL(fmul),
238     INSN_LABEL(dmul),
239     INSN_LABEL(idiv),
240     INSN_LABEL(ldiv),
241     INSN_LABEL(fdiv),
242     INSN_LABEL(ddiv),
243     INSN_LABEL(irem),
244     INSN_LABEL(lrem),
245     INSN_LABEL(frem),
246     INSN_LABEL(drem),
247     INSN_LABEL(ineg),
248     INSN_LABEL(lneg),
249     INSN_LABEL(fneg),
250     INSN_LABEL(dneg),
251     INSN_LABEL(ishl),
252     INSN_LABEL(lshl),
253     INSN_LABEL(ishr),
254     INSN_LABEL(lshr),
255     INSN_LABEL(iushr),
256     INSN_LABEL(lushr),
257     INSN_LABEL(iand),
258     INSN_LABEL(land),
259     INSN_LABEL(ior),
260     INSN_LABEL(lor),
261     INSN_LABEL(ixor),
262     INSN_LABEL(lxor),
263     INSN_LABEL(iinc),
264     INSN_LABEL(i2l),
265     INSN_LABEL(i2f),
266     INSN_LABEL(i2d),
267     INSN_LABEL(l2i),
268     INSN_LABEL(l2f),
269     INSN_LABEL(l2d),
270     INSN_LABEL(f2i),
271     INSN_LABEL(f2l),
272     INSN_LABEL(f2d),
273     INSN_LABEL(d2i),
274     INSN_LABEL(d2l),
275     INSN_LABEL(d2f),
276     INSN_LABEL(i2b),
277     INSN_LABEL(i2c),
278     INSN_LABEL(i2s),
279     INSN_LABEL(lcmp),
280     INSN_LABEL(fcmpl),
281     INSN_LABEL(fcmpg),
282     INSN_LABEL(dcmpl),
283     INSN_LABEL(dcmpg),
284     INSN_LABEL(ifeq),
285     INSN_LABEL(ifne),
286     INSN_LABEL(iflt),
287     INSN_LABEL(ifge),
288     INSN_LABEL(ifgt),
289     INSN_LABEL(ifle),
290     INSN_LABEL(if_icmpeq),
291     INSN_LABEL(if_icmpne),
292     INSN_LABEL(if_icmplt),
293     INSN_LABEL(if_icmpge),
294     INSN_LABEL(if_icmpgt),
295     INSN_LABEL(if_icmple),
296     INSN_LABEL(if_acmpeq),
297     INSN_LABEL(if_acmpne),
298     INSN_LABEL(goto), 
299     INSN_LABEL(jsr),
300     INSN_LABEL(ret),
301     INSN_LABEL(tableswitch),
302     INSN_LABEL(lookupswitch),
303     INSN_LABEL(ireturn),
304     INSN_LABEL(lreturn),
305     INSN_LABEL(freturn),
306     INSN_LABEL(dreturn),
307     INSN_LABEL(areturn),
308     INSN_LABEL(return),
309     INSN_LABEL(getstatic),
310     INSN_LABEL(putstatic),
311     INSN_LABEL(getfield),
312     INSN_LABEL(putfield),
313     INSN_LABEL(invokevirtual),
314     INSN_LABEL(invokespecial),
315     INSN_LABEL(invokestatic),
316     INSN_LABEL(invokeinterface),
317     INSN_LABEL(breakpoint),
318     INSN_LABEL(new),
319     INSN_LABEL(newarray),
320     INSN_LABEL(anewarray),
321     INSN_LABEL(arraylength),
322     INSN_LABEL(athrow),
323     INSN_LABEL(checkcast),
324     INSN_LABEL(instanceof),
325     INSN_LABEL(monitorenter),
326     INSN_LABEL(monitorexit),
327 #ifdef DIRECT_THREADED
328     0, // wide
329 #else
330     INSN_LABEL(wide),
331 #endif
332     INSN_LABEL(multianewarray),
333     INSN_LABEL(ifnull),
334     INSN_LABEL(ifnonnull),
335     INSN_LABEL(goto_w),
336     INSN_LABEL(jsr_w),
337 #ifdef DIRECT_THREADED
338     INSN_LABEL (ldc_class)
339 #else
340     0
341 #endif
342   };
343
344 #ifdef DIRECT_THREADED
345
346 #ifdef DEBUG
347 #undef NEXT_INSN
348 #define NEXT_INSN                                                       \
349   do                                                                    \
350     {                                                                   \
351       pc_t insn = pc++;                                                 \
352       if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
353         {                                                               \
354           JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
355           jmethodID method = meth->self;                                \
356           jlocation loc = meth->insn_index (insn);                      \
357           _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
358                                env, method, loc);                       \
359         }                                                               \
360       goto *(insn->insn);                                               \
361     }                                                                   \
362   while (0)
363
364 #undef REWRITE_INSN
365 #define REWRITE_INSN(INSN,SLOT,VALUE)                                   \
366   do {                                                                  \
367     if (pc[-2].insn == breakpoint_insn->insn)                           \
368       {                                                                 \
369         using namespace ::gnu::gcj::jvmti;                              \
370         jlocation location = meth->insn_index (pc - 2);                 \
371         _Jv_RewriteBreakpointInsn (meth->self, location, (pc_t) INSN);  \
372       }                                                                 \
373     else                                                                \
374       pc[-2].insn = INSN;                                               \
375                                                                         \
376     pc[-1].SLOT = VALUE;                                                \
377   }                                                                     \
378   while (0)
379
380 #undef INTERP_REPORT_EXCEPTION
381 #define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
382 #else // !DEBUG
383 #undef NEXT_INSN
384 #define NEXT_INSN goto *((pc++)->insn)
385
386 // REWRITE_INSN does nothing.
387 //
388 // Rewriting a multi-word instruction in the presence of multiple
389 // threads leads to a data race if a thread reads part of an
390 // instruction while some other thread is rewriting that instruction.
391 // For example, an invokespecial instruction may be rewritten to
392 // invokespecial_resolved and its operand changed from an index to a
393 // pointer while another thread is executing invokespecial.  This
394 // other thread then reads the pointer that is now the operand of
395 // invokespecial_resolved and tries to use it as an index.
396 //
397 // Fixing this requires either spinlocks, a more elaborate data
398 // structure, or even per-thread allocated pages.  It's clear from the
399 // locking in meth->compile below that the presence of multiple
400 // threads was contemplated when this code was written, but the full
401 // consequences were not fully appreciated.
402 #define REWRITE_INSN(INSN,SLOT,VALUE)
403
404 #undef INTERP_REPORT_EXCEPTION
405 #define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
406 #endif // !DEBUG
407
408 #define INTVAL() ((pc++)->int_val)
409 #define AVAL() ((pc++)->datum)
410
411 #define GET1S() INTVAL ()
412 #define GET2S() INTVAL ()
413 #define GET1U() INTVAL ()
414 #define GET2U() INTVAL ()
415 #define AVAL1U() AVAL ()
416 #define AVAL2U() AVAL ()
417 #define AVAL2UP() AVAL ()
418 #define SKIP_GOTO ++pc
419 #define GOTO_VAL() (insn_slot *) pc->datum
420 #define PCVAL(unionval) unionval.p
421 #define AMPAMP(label) &&label
422
423   // Compile if we must. NOTE: Double-check locking.
424   if (meth->prepared == NULL)
425     {
426       _Jv_MutexLock (&compile_mutex);
427       if (meth->prepared == NULL)
428         meth->compile (insn_target);
429       _Jv_MutexUnlock (&compile_mutex);
430     }
431
432   // If we're only compiling, stop here
433   if (args == NULL)
434     return;
435
436   pc = (insn_slot *) meth->prepared;
437
438 #else
439
440 #ifdef DEBUG
441 #define NEXT_INSN                                                       \
442   do                                                                    \
443     {                                                                   \
444       if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
445         {                                                               \
446           JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
447           jmethodID method = meth->self;                                \
448           jlocation loc = meth->insn_index (pc);                        \
449           _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
450                                env, method, loc);                       \
451         }                                                               \
452       goto *(insn_target[*pc++])
453 #else
454 #define NEXT_INSN goto *(insn_target[*pc++])
455 #endif
456
457 #define GET1S() get1s (pc++)
458 #define GET2S() (pc += 2, get2s (pc- 2))
459 #define GET1U() get1u (pc++)
460 #define GET2U() (pc += 2, get2u (pc - 2))
461   // Note that these could be more efficient when not handling 'ldc
462   // class'.
463 #define AVAL1U()                                                \
464   ({ int index = get1u (pc++);                                  \
465     _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
466 #define AVAL2U()                                                \
467   ({ int index = get2u (pc); pc += 2;                           \
468     _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
469   // Note that we don't need to resolve the pool entry here as class
470   // constants are never wide.
471 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
472 #define SKIP_GOTO pc += 2
473 #define GOTO_VAL() pc - 1 + get2s (pc)
474 #define PCVAL(unionval) unionval.i
475 #define AMPAMP(label) NULL
476
477   pc = meth->bytecode ();
478
479 #endif /* DIRECT_THREADED */
480
481 #define TAKE_GOTO pc = GOTO_VAL ()
482
483   /* Go straight at it!  the ffi raw format matches the internal
484      stack representation exactly.  At least, that's the idea.
485   */
486   memcpy ((void*) locals, (void*) args, meth->args_raw_size);
487
488   _Jv_word *pool_data = meth->defining_class->constants.data;
489
490   /* These three are temporaries for common code used by several
491      instructions.  */
492   void (*fun)();
493   _Jv_ResolvedMethod* rmeth;
494   int tmpval;
495
496   try
497     {
498       // We keep nop around.  It is used if we're interpreting the
499       // bytecodes and not doing direct threading.
500     insn_nop:
501       NEXT_INSN;
502
503       /* The first few instructions here are ordered according to their
504          frequency, in the hope that this will improve code locality a
505          little.  */
506
507     insn_aload_0:               // 0x2a
508       LOADA (0);
509       NEXT_INSN;
510
511     insn_iload:         // 0x15
512       LOADI (GET1U ());
513       NEXT_INSN;
514
515     insn_iload_1:               // 0x1b
516       LOADI (1);
517       NEXT_INSN;
518
519     insn_invokevirtual: // 0xb6
520       {
521         SAVE_PC();
522         int index = GET2U ();
523
524         /* _Jv_Linker::resolve_pool_entry returns immediately if the
525          * value already is resolved.  If we want to clutter up the
526          * code here to gain a little performance, then we can check
527          * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
528          * directly.  For now, I don't think it is worth it.  */
529
530         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
531                                                    index)).rmethod;
532
533         sp -= rmeth->stack_item_count;
534
535         if (rmeth->method->accflags & Modifier::FINAL)
536           {
537             // We can't rely on NULLCHECK working if the method is final.
538             if (! sp[0].o)
539               throw_null_pointer_exception ();
540
541             // Final methods might not appear in the vtable.
542             fun = (void (*)()) rmeth->method->ncode;
543           }
544         else
545           {
546             NULLCHECK (sp[0].o);
547             jobject rcv = sp[0].o;
548             _Jv_VTable *table = *(_Jv_VTable**) rcv;
549             fun = (void (*)()) table->get_method (rmeth->method->index);
550           }
551
552 #ifdef DIRECT_THREADED
553         // Rewrite instruction so that we use a faster pre-resolved
554         // method.
555         REWRITE_INSN (&&invokevirtual_resolved, datum, rmeth);
556 #endif /* DIRECT_THREADED */
557       }
558       goto perform_invoke;
559
560 #ifdef DIRECT_THREADED
561     invokevirtual_resolved:
562       {
563         SAVE_PC();
564         rmeth = (_Jv_ResolvedMethod *) AVAL ();
565         sp -= rmeth->stack_item_count;
566
567         if (rmeth->method->accflags & Modifier::FINAL)
568           {
569             // We can't rely on NULLCHECK working if the method is final.
570             if (! sp[0].o)
571               throw_null_pointer_exception ();
572
573             // Final methods might not appear in the vtable.
574             fun = (void (*)()) rmeth->method->ncode;
575           }
576         else
577           {
578             NULLCHECK (sp[0].o);
579             jobject rcv = sp[0].o;
580             _Jv_VTable *table = *(_Jv_VTable**) rcv;
581             fun = (void (*)()) table->get_method (rmeth->method->index);
582           }
583       }
584       goto perform_invoke;
585 #endif /* DIRECT_THREADED */
586
587     perform_invoke:
588       {
589         /* here goes the magic again... */
590         ffi_cif *cif = &rmeth->cif;
591         INTERP_FFI_RAW_TYPE *raw = (INTERP_FFI_RAW_TYPE *) sp;
592
593         _Jv_value rvalue;
594
595 #if FFI_NATIVE_RAW_API
596         /* We assume that this is only implemented if it's correct      */
597         /* to use it here.  On a 64 bit machine, it never is.           */
598         ffi_raw_call (cif, fun, (void*)&rvalue, raw);
599 #else
600         ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
601 #endif
602
603         int rtype = cif->rtype->type;
604
605         /* the likelyhood of object, int, or void return is very high,
606          * so those are checked before the switch */
607         if (rtype == FFI_TYPE_POINTER)
608           {
609             PUSHA (rvalue.object_value);
610           }
611         else if (rtype == FFI_TYPE_SINT32)
612           {
613             PUSHI (rvalue.int_value);
614           }
615         else if (rtype == FFI_TYPE_VOID)
616           {
617             /* skip */
618           }
619         else
620           {
621             switch (rtype)
622               {
623               case FFI_TYPE_SINT8:
624                 PUSHI ((jbyte)(rvalue.int_value & 0xff));
625                 break;
626
627               case FFI_TYPE_SINT16:
628                 PUSHI ((jshort)(rvalue.int_value & 0xffff));
629                 break;
630
631               case FFI_TYPE_UINT16:
632                 PUSHI (rvalue.int_value & 0xffff);
633                 break;
634
635               case FFI_TYPE_FLOAT:
636                 PUSHF (rvalue.float_value);
637                 break;
638
639               case FFI_TYPE_DOUBLE:
640                 PUSHD (rvalue.double_value);
641                 break;
642
643               case FFI_TYPE_SINT64:
644                 PUSHL (rvalue.long_value);
645                 break;
646
647               default:
648                 throw_internal_error ("unknown return type in invokeXXX");
649               }
650           }
651       }
652       NEXT_INSN;
653
654     insn_aconst_null:
655       PUSHA (NULL);
656       NEXT_INSN;
657
658     insn_iconst_m1:
659       PUSHI (-1);
660       NEXT_INSN;
661
662     insn_iconst_0:
663       PUSHI (0);
664       NEXT_INSN;
665
666     insn_iconst_1:
667       PUSHI (1);
668       NEXT_INSN;
669
670     insn_iconst_2:
671       PUSHI (2);
672       NEXT_INSN;
673
674     insn_iconst_3:
675       PUSHI (3);
676       NEXT_INSN;
677
678     insn_iconst_4:
679       PUSHI (4);
680       NEXT_INSN;
681
682     insn_iconst_5:
683       PUSHI (5);
684       NEXT_INSN;
685
686     insn_lconst_0:
687       PUSHL (0);
688       NEXT_INSN;
689
690     insn_lconst_1:
691       PUSHL (1);
692       NEXT_INSN;
693
694     insn_fconst_0:
695       PUSHF (0);
696       NEXT_INSN;
697
698     insn_fconst_1:
699       PUSHF (1);
700       NEXT_INSN;
701
702     insn_fconst_2:
703       PUSHF (2);
704       NEXT_INSN;
705
706     insn_dconst_0:
707       PUSHD (0);
708       NEXT_INSN;
709
710     insn_dconst_1:
711       PUSHD (1);
712       NEXT_INSN;
713
714     insn_bipush:
715       // For direct threaded, bipush and sipush are the same.
716 #ifndef DIRECT_THREADED
717       PUSHI (GET1S ());
718       NEXT_INSN;
719 #endif /* DIRECT_THREADED */
720     insn_sipush:
721       PUSHI (GET2S ());
722       NEXT_INSN;
723
724     insn_ldc:
725       // For direct threaded, ldc and ldc_w are the same.
726 #ifndef DIRECT_THREADED
727       PUSHA ((jobject) AVAL1U ());
728       NEXT_INSN;
729 #endif /* DIRECT_THREADED */
730     insn_ldc_w:
731       PUSHA ((jobject) AVAL2U ());
732       NEXT_INSN;
733
734 #ifdef DIRECT_THREADED
735       // For direct threaded we have a separate 'ldc class' operation.
736     insn_ldc_class:
737       {
738         SAVE_PC();
739         // We could rewrite the instruction at this point.
740         int index = INTVAL ();
741         jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
742                                                      index)).o;
743         PUSHA (k);
744       }
745       NEXT_INSN;
746 #endif /* DIRECT_THREADED */
747
748     insn_ldc2_w:
749       {
750         void *where = AVAL2UP ();
751         memcpy (sp, where, 2*sizeof (_Jv_word));
752         sp += 2;
753       }
754       NEXT_INSN;
755
756     insn_lload:
757       LOADL (GET1U ());
758       NEXT_INSN;
759
760     insn_fload:
761       LOADF (GET1U ());
762       NEXT_INSN;
763
764     insn_dload:
765       LOADD (GET1U ());
766       NEXT_INSN;
767
768     insn_aload:
769       LOADA (GET1U ());
770       NEXT_INSN;
771
772     insn_iload_0:
773       LOADI (0);
774       NEXT_INSN;
775
776     insn_iload_2:
777       LOADI (2);
778       NEXT_INSN;
779
780     insn_iload_3:
781       LOADI (3);
782       NEXT_INSN;
783
784     insn_lload_0:
785       LOADL (0);
786       NEXT_INSN;
787
788     insn_lload_1:
789       LOADL (1);
790       NEXT_INSN;
791
792     insn_lload_2:
793       LOADL (2);
794       NEXT_INSN;
795
796     insn_lload_3:
797       LOADL (3);
798       NEXT_INSN;
799
800     insn_fload_0:
801       LOADF (0);
802       NEXT_INSN;
803
804     insn_fload_1:
805       LOADF (1);
806       NEXT_INSN;
807
808     insn_fload_2:
809       LOADF (2);
810       NEXT_INSN;
811
812     insn_fload_3:
813       LOADF (3);
814       NEXT_INSN;
815
816     insn_dload_0:
817       LOADD (0);
818       NEXT_INSN;
819
820     insn_dload_1:
821       LOADD (1);
822       NEXT_INSN;
823
824     insn_dload_2:
825       LOADD (2);
826       NEXT_INSN;
827
828     insn_dload_3:
829       LOADD (3);
830       NEXT_INSN;
831
832     insn_aload_1:
833       LOADA(1);
834       NEXT_INSN;
835
836     insn_aload_2:
837       LOADA(2);
838       NEXT_INSN;
839
840     insn_aload_3:
841       LOADA(3);
842       NEXT_INSN;
843
844     insn_iaload:
845       {
846         jint index = POPI();
847         jintArray arr = (jintArray) POPA();
848         NULLARRAYCHECK (arr);
849         ARRAYBOUNDSCHECK (arr, index);
850         PUSHI( elements(arr)[index] );
851       }
852       NEXT_INSN;
853
854     insn_laload:
855       {
856         jint index = POPI();
857         jlongArray arr = (jlongArray) POPA();
858         NULLARRAYCHECK (arr);
859         ARRAYBOUNDSCHECK (arr, index);
860         PUSHL( elements(arr)[index] );
861       }
862       NEXT_INSN;
863
864     insn_faload:
865       {
866         jint index = POPI();
867         jfloatArray arr = (jfloatArray) POPA();
868         NULLARRAYCHECK (arr);
869         ARRAYBOUNDSCHECK (arr, index);
870         PUSHF( elements(arr)[index] );
871       }
872       NEXT_INSN;
873
874     insn_daload:
875       {
876         jint index = POPI();
877         jdoubleArray arr = (jdoubleArray) POPA();
878         NULLARRAYCHECK (arr);
879         ARRAYBOUNDSCHECK (arr, index);
880         PUSHD( elements(arr)[index] );
881       }
882       NEXT_INSN;
883
884     insn_aaload:
885       {
886         jint index = POPI();
887         jobjectArray arr = (jobjectArray) POPA();
888         NULLARRAYCHECK (arr);
889         ARRAYBOUNDSCHECK (arr, index);
890         PUSHA( elements(arr)[index] );
891       }
892       NEXT_INSN;
893
894     insn_baload:
895       {
896         jint index = POPI();
897         jbyteArray arr = (jbyteArray) POPA();
898         NULLARRAYCHECK (arr);
899         ARRAYBOUNDSCHECK (arr, index);
900         PUSHI( elements(arr)[index] );
901       }
902       NEXT_INSN;
903
904     insn_caload:
905       {
906         jint index = POPI();
907         jcharArray arr = (jcharArray) POPA();
908         NULLARRAYCHECK (arr);
909         ARRAYBOUNDSCHECK (arr, index);
910         PUSHI( elements(arr)[index] );
911       }
912       NEXT_INSN;
913
914     insn_saload:
915       {
916         jint index = POPI();
917         jshortArray arr = (jshortArray) POPA();
918         NULLARRAYCHECK (arr);
919         ARRAYBOUNDSCHECK (arr, index);
920         PUSHI( elements(arr)[index] );
921       }
922       NEXT_INSN;
923
924     insn_istore:
925       STOREI (GET1U ());
926       NEXT_INSN;
927
928     insn_lstore:
929       STOREL (GET1U ());
930       NEXT_INSN;
931
932     insn_fstore:
933       STOREF (GET1U ());
934       NEXT_INSN;
935
936     insn_dstore:
937       STORED (GET1U ());
938       NEXT_INSN;
939
940     insn_astore:
941       STOREA (GET1U ());
942       NEXT_INSN;
943
944     insn_istore_0:
945       STOREI (0);
946       NEXT_INSN;
947
948     insn_istore_1:
949       STOREI (1);
950       NEXT_INSN;
951
952     insn_istore_2:
953       STOREI (2);
954       NEXT_INSN;
955
956     insn_istore_3:
957       STOREI (3);
958       NEXT_INSN;
959
960     insn_lstore_0:
961       STOREL (0);
962       NEXT_INSN;
963
964     insn_lstore_1:
965       STOREL (1);
966       NEXT_INSN;
967
968     insn_lstore_2:
969       STOREL (2);
970       NEXT_INSN;
971
972     insn_lstore_3:
973       STOREL (3);
974       NEXT_INSN;
975
976     insn_fstore_0:
977       STOREF (0);
978       NEXT_INSN;
979
980     insn_fstore_1:
981       STOREF (1);
982       NEXT_INSN;
983
984     insn_fstore_2:
985       STOREF (2);
986       NEXT_INSN;
987
988     insn_fstore_3:
989       STOREF (3);
990       NEXT_INSN;
991
992     insn_dstore_0:
993       STORED (0);
994       NEXT_INSN;
995
996     insn_dstore_1:
997       STORED (1);
998       NEXT_INSN;
999
1000     insn_dstore_2:
1001       STORED (2);
1002       NEXT_INSN;
1003
1004     insn_dstore_3:
1005       STORED (3);
1006       NEXT_INSN;
1007
1008     insn_astore_0:
1009       STOREA(0);
1010       NEXT_INSN;
1011
1012     insn_astore_1:
1013       STOREA(1);
1014       NEXT_INSN;
1015
1016     insn_astore_2:
1017       STOREA(2);
1018       NEXT_INSN;
1019
1020     insn_astore_3:
1021       STOREA(3);
1022       NEXT_INSN;
1023
1024     insn_iastore:
1025       {
1026         jint value = POPI();
1027         jint index  = POPI();
1028         jintArray arr = (jintArray) POPA();
1029         NULLARRAYCHECK (arr);
1030         ARRAYBOUNDSCHECK (arr, index);
1031         elements(arr)[index] = value;
1032       }
1033       NEXT_INSN;
1034
1035     insn_lastore:
1036       {
1037         jlong value = POPL();
1038         jint index  = POPI();
1039         jlongArray arr = (jlongArray) POPA();
1040         NULLARRAYCHECK (arr);
1041         ARRAYBOUNDSCHECK (arr, index);
1042         elements(arr)[index] = value;
1043       }
1044       NEXT_INSN;
1045
1046     insn_fastore:
1047       {
1048         jfloat value = POPF();
1049         jint index  = POPI();
1050         jfloatArray arr = (jfloatArray) POPA();
1051         NULLARRAYCHECK (arr);
1052         ARRAYBOUNDSCHECK (arr, index);
1053         elements(arr)[index] = value;
1054       }
1055       NEXT_INSN;
1056
1057     insn_dastore:
1058       {
1059         jdouble value = POPD();
1060         jint index  = POPI();
1061         jdoubleArray arr = (jdoubleArray) POPA();
1062         NULLARRAYCHECK (arr);
1063         ARRAYBOUNDSCHECK (arr, index);
1064         elements(arr)[index] = value;
1065       }
1066       NEXT_INSN;
1067
1068     insn_aastore:
1069       {
1070         jobject value = POPA();
1071         jint index  = POPI();
1072         jobjectArray arr = (jobjectArray) POPA();
1073         NULLARRAYCHECK (arr);
1074         ARRAYBOUNDSCHECK (arr, index);
1075         _Jv_CheckArrayStore (arr, value);
1076         elements(arr)[index] = value;
1077       }
1078       NEXT_INSN;
1079
1080     insn_bastore:
1081       {
1082         jbyte value = (jbyte) POPI();
1083         jint index  = POPI();
1084         jbyteArray arr = (jbyteArray) POPA();
1085         NULLARRAYCHECK (arr);
1086         ARRAYBOUNDSCHECK (arr, index);
1087         elements(arr)[index] = value;
1088       }
1089       NEXT_INSN;
1090
1091     insn_castore:
1092       {
1093         jchar value = (jchar) POPI();
1094         jint index  = POPI();
1095         jcharArray arr = (jcharArray) POPA();
1096         NULLARRAYCHECK (arr);
1097         ARRAYBOUNDSCHECK (arr, index);
1098         elements(arr)[index] = value;
1099       }
1100       NEXT_INSN;
1101
1102     insn_sastore:
1103       {
1104         jshort value = (jshort) POPI();
1105         jint index  = POPI();
1106         jshortArray arr = (jshortArray) POPA();
1107         NULLARRAYCHECK (arr);
1108         ARRAYBOUNDSCHECK (arr, index);
1109         elements(arr)[index] = value;
1110       }
1111       NEXT_INSN;
1112
1113     insn_pop:
1114       sp -= 1;
1115       NEXT_INSN;
1116
1117     insn_pop2:
1118       sp -= 2;
1119       NEXT_INSN;
1120
1121     insn_dup:
1122       sp[0] = sp[-1];
1123       sp += 1;
1124       NEXT_INSN;
1125
1126     insn_dup_x1:
1127       dupx (sp, 1, 1); sp+=1;
1128       NEXT_INSN;
1129
1130     insn_dup_x2:
1131       dupx (sp, 1, 2); sp+=1;
1132       NEXT_INSN;
1133
1134     insn_dup2:
1135       sp[0] = sp[-2];
1136       sp[1] = sp[-1];
1137       sp += 2;
1138       NEXT_INSN;
1139
1140     insn_dup2_x1:
1141       dupx (sp, 2, 1); sp+=2;
1142       NEXT_INSN;
1143
1144     insn_dup2_x2:
1145       dupx (sp, 2, 2); sp+=2;
1146       NEXT_INSN;
1147
1148     insn_swap:
1149       {
1150         jobject tmp1 = POPA();
1151         jobject tmp2 = POPA();
1152         PUSHA (tmp1);
1153         PUSHA (tmp2);
1154       }
1155       NEXT_INSN;
1156
1157     insn_iadd:
1158       BINOPI(+);
1159       NEXT_INSN;
1160
1161     insn_ladd:
1162       BINOPL(+);
1163       NEXT_INSN;
1164
1165     insn_fadd:
1166       BINOPF(+);
1167       NEXT_INSN;
1168
1169     insn_dadd:
1170       BINOPD(+);
1171       NEXT_INSN;
1172
1173     insn_isub:
1174       BINOPI(-);
1175       NEXT_INSN;
1176
1177     insn_lsub:
1178       BINOPL(-);
1179       NEXT_INSN;
1180
1181     insn_fsub:
1182       BINOPF(-);
1183       NEXT_INSN;
1184
1185     insn_dsub:
1186       BINOPD(-);
1187       NEXT_INSN;
1188
1189     insn_imul:
1190       BINOPI(*);
1191       NEXT_INSN;
1192
1193     insn_lmul:
1194       BINOPL(*);
1195       NEXT_INSN;
1196
1197     insn_fmul:
1198       BINOPF(*);
1199       NEXT_INSN;
1200
1201     insn_dmul:
1202       BINOPD(*);
1203       NEXT_INSN;
1204
1205     insn_idiv:
1206       {
1207         SAVE_PC();
1208         jint value2 = POPI();
1209         jint value1 = POPI();
1210         jint res = _Jv_divI (value1, value2);
1211         PUSHI (res);
1212       }
1213       NEXT_INSN;
1214
1215     insn_ldiv:
1216       {
1217         SAVE_PC();
1218         jlong value2 = POPL();
1219         jlong value1 = POPL();
1220         jlong res = _Jv_divJ (value1, value2);
1221         PUSHL (res);
1222       }
1223       NEXT_INSN;
1224
1225     insn_fdiv:
1226       {
1227         jfloat value2 = POPF();
1228         jfloat value1 = POPF();
1229         jfloat res = value1 / value2;
1230         PUSHF (res);
1231       }
1232       NEXT_INSN;
1233
1234     insn_ddiv:
1235       {
1236         jdouble value2 = POPD();
1237         jdouble value1 = POPD();
1238         jdouble res = value1 / value2;
1239         PUSHD (res);
1240       }
1241       NEXT_INSN;
1242
1243     insn_irem:
1244       {
1245         SAVE_PC();
1246         jint value2 = POPI();
1247         jint value1 =  POPI();
1248         jint res = _Jv_remI (value1, value2);
1249         PUSHI (res);
1250       }
1251       NEXT_INSN;
1252
1253     insn_lrem:
1254       {
1255         SAVE_PC();
1256         jlong value2 = POPL();
1257         jlong value1 = POPL();
1258         jlong res = _Jv_remJ (value1, value2);
1259         PUSHL (res);
1260       }
1261       NEXT_INSN;
1262
1263     insn_frem:
1264       {
1265         jfloat value2 = POPF();
1266         jfloat value1 = POPF();
1267         jfloat res    = __ieee754_fmod (value1, value2);
1268         PUSHF (res);
1269       }
1270       NEXT_INSN;
1271
1272     insn_drem:
1273       {
1274         jdouble value2 = POPD();
1275         jdouble value1 = POPD();
1276         jdouble res    = __ieee754_fmod (value1, value2);
1277         PUSHD (res);
1278       }
1279       NEXT_INSN;
1280
1281     insn_ineg:
1282       {
1283         jint value = POPI();
1284         PUSHI (value * -1);
1285       }
1286       NEXT_INSN;
1287
1288     insn_lneg:
1289       {
1290         jlong value = POPL();
1291         PUSHL (value * -1);
1292       }
1293       NEXT_INSN;
1294
1295     insn_fneg:
1296       {
1297         jfloat value = POPF();
1298         PUSHF (value * -1);
1299       }
1300       NEXT_INSN;
1301
1302     insn_dneg:
1303       {
1304         jdouble value = POPD();
1305         PUSHD (value * -1);
1306       }
1307       NEXT_INSN;
1308
1309     insn_ishl:
1310       {
1311         jint shift = (POPI() & 0x1f);
1312         jint value = POPI();
1313         PUSHI (value << shift);
1314       }
1315       NEXT_INSN;
1316
1317     insn_lshl:
1318       {
1319         jint shift = (POPI() & 0x3f);
1320         jlong value = POPL();
1321         PUSHL (value << shift);
1322       }
1323       NEXT_INSN;
1324
1325     insn_ishr:
1326       {
1327         jint shift = (POPI() & 0x1f);
1328         jint value = POPI();
1329         PUSHI (value >> shift);
1330       }
1331       NEXT_INSN;
1332
1333     insn_lshr:
1334       {
1335         jint shift = (POPI() & 0x3f);
1336         jlong value = POPL();
1337         PUSHL (value >> shift);
1338       }
1339       NEXT_INSN;
1340
1341     insn_iushr:
1342       {
1343         jint shift = (POPI() & 0x1f);
1344         _Jv_uint value = (_Jv_uint) POPI();
1345         PUSHI ((jint) (value >> shift));
1346       }
1347       NEXT_INSN;
1348
1349     insn_lushr:
1350       {
1351         jint shift = (POPI() & 0x3f);
1352         _Jv_ulong value = (_Jv_ulong) POPL();
1353         PUSHL ((jlong) (value >> shift));
1354       }
1355       NEXT_INSN;
1356
1357     insn_iand:
1358       BINOPI (&);
1359       NEXT_INSN;
1360
1361     insn_land:
1362       BINOPL (&);
1363       NEXT_INSN;
1364
1365     insn_ior:
1366       BINOPI (|);
1367       NEXT_INSN;
1368
1369     insn_lor:
1370       BINOPL (|);
1371       NEXT_INSN;
1372
1373     insn_ixor:
1374       BINOPI (^);
1375       NEXT_INSN;
1376
1377     insn_lxor:
1378       BINOPL (^);
1379       NEXT_INSN;
1380
1381     insn_iinc:
1382       {
1383         jint index  = GET1U ();
1384         jint amount = GET1S ();
1385         locals[index].i += amount;
1386       }
1387       NEXT_INSN;
1388
1389     insn_i2l:
1390       {jlong value = POPI(); PUSHL (value);}
1391       NEXT_INSN;
1392
1393     insn_i2f:
1394       {jfloat value = POPI(); PUSHF (value);}
1395       NEXT_INSN;
1396
1397     insn_i2d:
1398       {jdouble value = POPI(); PUSHD (value);}
1399       NEXT_INSN;
1400
1401     insn_l2i:
1402       {jint value = POPL(); PUSHI (value);}
1403       NEXT_INSN;
1404
1405     insn_l2f:
1406       {jfloat value = POPL(); PUSHF (value);}
1407       NEXT_INSN;
1408
1409     insn_l2d:
1410       {jdouble value = POPL(); PUSHD (value);}
1411       NEXT_INSN;
1412
1413     insn_f2i:
1414       {
1415         using namespace java::lang;
1416         jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1417         PUSHI(value);
1418       }
1419       NEXT_INSN;
1420
1421     insn_f2l:
1422       {
1423         using namespace java::lang;
1424         jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
1425         PUSHL(value);
1426       }
1427       NEXT_INSN;
1428
1429     insn_f2d:
1430       { jdouble value = POPF (); PUSHD(value); }
1431       NEXT_INSN;
1432
1433     insn_d2i:
1434       {
1435         using namespace java::lang;
1436         jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1437         PUSHI(value);
1438       }
1439       NEXT_INSN;
1440
1441     insn_d2l:
1442       {
1443         using namespace java::lang;
1444         jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
1445         PUSHL(value);
1446       }
1447       NEXT_INSN;
1448
1449     insn_d2f:
1450       { jfloat value = POPD (); PUSHF(value); }
1451       NEXT_INSN;
1452
1453     insn_i2b:
1454       { jbyte value = POPI (); PUSHI(value); }
1455       NEXT_INSN;
1456
1457     insn_i2c:
1458       { jchar value = POPI (); PUSHI(value); }
1459       NEXT_INSN;
1460
1461     insn_i2s:
1462       { jshort value = POPI (); PUSHI(value); }
1463       NEXT_INSN;
1464
1465     insn_lcmp:
1466       {
1467         jlong value2 = POPL ();
1468         jlong value1 = POPL ();
1469         if (value1 > value2)
1470           { PUSHI (1); }
1471         else if (value1 == value2)
1472           { PUSHI (0); }
1473         else
1474           { PUSHI (-1); }
1475       }
1476       NEXT_INSN;
1477
1478     insn_fcmpl:
1479       tmpval = -1;
1480       goto fcmp;
1481
1482     insn_fcmpg:
1483       tmpval = 1;
1484
1485     fcmp:
1486       {
1487         jfloat value2 = POPF ();
1488         jfloat value1 = POPF ();
1489         if (value1 > value2)
1490           PUSHI (1);
1491         else if (value1 == value2)
1492           PUSHI (0);
1493         else if (value1 < value2)
1494           PUSHI (-1);
1495         else
1496           PUSHI (tmpval);
1497       }
1498       NEXT_INSN;
1499
1500     insn_dcmpl:
1501       tmpval = -1;
1502       goto dcmp;
1503
1504     insn_dcmpg:
1505       tmpval = 1;
1506
1507     dcmp:
1508       {
1509         jdouble value2 = POPD ();
1510         jdouble value1 = POPD ();
1511         if (value1 > value2)
1512           PUSHI (1);
1513         else if (value1 == value2)
1514           PUSHI (0);
1515         else if (value1 < value2)
1516           PUSHI (-1);
1517         else
1518           PUSHI (tmpval);
1519       }
1520       NEXT_INSN;
1521
1522     insn_ifeq:
1523       {
1524         if (POPI() == 0)
1525           TAKE_GOTO;
1526         else
1527           SKIP_GOTO;
1528       }
1529       NEXT_INSN;
1530
1531     insn_ifne:
1532       {
1533         if (POPI() != 0)
1534           TAKE_GOTO;
1535         else
1536           SKIP_GOTO;
1537       }
1538       NEXT_INSN;
1539
1540     insn_iflt:
1541       {
1542         if (POPI() < 0)
1543           TAKE_GOTO;
1544         else
1545           SKIP_GOTO;
1546       }
1547       NEXT_INSN;
1548
1549     insn_ifge:
1550       {
1551         if (POPI() >= 0)
1552           TAKE_GOTO;
1553         else
1554           SKIP_GOTO;
1555       }
1556       NEXT_INSN;
1557
1558     insn_ifgt:
1559       {
1560         if (POPI() > 0)
1561           TAKE_GOTO;
1562         else
1563           SKIP_GOTO;
1564       }
1565       NEXT_INSN;
1566
1567     insn_ifle:
1568       {
1569         if (POPI() <= 0)
1570           TAKE_GOTO;
1571         else
1572           SKIP_GOTO;
1573       }
1574       NEXT_INSN;
1575
1576     insn_if_icmpeq:
1577       {
1578         jint value2 = POPI();
1579         jint value1 = POPI();
1580         if (value1 == value2)
1581           TAKE_GOTO;
1582         else
1583           SKIP_GOTO;
1584       }
1585       NEXT_INSN;
1586
1587     insn_if_icmpne:
1588       {
1589         jint value2 = POPI();
1590         jint value1 = POPI();
1591         if (value1 != value2)
1592           TAKE_GOTO;
1593         else
1594           SKIP_GOTO;
1595       }
1596       NEXT_INSN;
1597
1598     insn_if_icmplt:
1599       {
1600         jint value2 = POPI();
1601         jint value1 = POPI();
1602         if (value1 < value2)
1603           TAKE_GOTO;
1604         else
1605           SKIP_GOTO;
1606       }
1607       NEXT_INSN;
1608
1609     insn_if_icmpge:
1610       {
1611         jint value2 = POPI();
1612         jint value1 = POPI();
1613         if (value1 >= value2)
1614           TAKE_GOTO;
1615         else
1616           SKIP_GOTO;
1617       }
1618       NEXT_INSN;
1619
1620     insn_if_icmpgt:
1621       {
1622         jint value2 = POPI();
1623         jint value1 = POPI();
1624         if (value1 > value2)
1625           TAKE_GOTO;
1626         else
1627           SKIP_GOTO;
1628       }
1629       NEXT_INSN;
1630
1631     insn_if_icmple:
1632       {
1633         jint value2 = POPI();
1634         jint value1 = POPI();
1635         if (value1 <= value2)
1636           TAKE_GOTO;
1637         else
1638           SKIP_GOTO;
1639       }
1640       NEXT_INSN;
1641
1642     insn_if_acmpeq:
1643       {
1644         jobject value2 = POPA();
1645         jobject value1 = POPA();
1646         if (value1 == value2)
1647           TAKE_GOTO;
1648         else
1649           SKIP_GOTO;
1650       }
1651       NEXT_INSN;
1652
1653     insn_if_acmpne:
1654       {
1655         jobject value2 = POPA();
1656         jobject value1 = POPA();
1657         if (value1 != value2)
1658           TAKE_GOTO;
1659         else
1660           SKIP_GOTO;
1661       }
1662       NEXT_INSN;
1663
1664     insn_goto_w:
1665 #ifndef DIRECT_THREADED
1666       // For direct threaded, goto and goto_w are the same.
1667       pc = pc - 1 + get4 (pc);
1668       NEXT_INSN;
1669 #endif /* DIRECT_THREADED */
1670     insn_goto:
1671       TAKE_GOTO;
1672       NEXT_INSN;
1673
1674     insn_jsr_w:
1675 #ifndef DIRECT_THREADED
1676       // For direct threaded, jsr and jsr_w are the same.
1677       {
1678         pc_t next = pc - 1 + get4 (pc);
1679         pc += 4;
1680         PUSHA ((jobject) pc);
1681         pc = next;
1682       }
1683       NEXT_INSN;
1684 #endif /* DIRECT_THREADED */
1685     insn_jsr:
1686       {
1687         pc_t next = GOTO_VAL();
1688         SKIP_GOTO;
1689         PUSHA ((jobject) pc);
1690         pc = next;
1691       }
1692       NEXT_INSN;
1693
1694     insn_ret:
1695       {
1696         jint index = GET1U ();
1697         pc = (pc_t) PEEKA (index);
1698       }
1699       NEXT_INSN;
1700
1701     insn_tableswitch:
1702       {
1703 #ifdef DIRECT_THREADED
1704         void *def = (pc++)->datum;
1705
1706         int index = POPI();
1707
1708         jint low = INTVAL ();
1709         jint high = INTVAL ();
1710
1711         if (index < low || index > high)
1712           pc = (insn_slot *) def;
1713         else
1714           pc = (insn_slot *) ((pc + index - low)->datum);
1715 #else
1716         pc_t base_pc = pc - 1;
1717         int index = POPI ();
1718
1719         pc_t base = (pc_t) meth->bytecode ();
1720         while ((pc - base) % 4 != 0)
1721           ++pc;
1722
1723         jint def = get4 (pc);
1724         jint low = get4 (pc + 4);
1725         jint high = get4 (pc + 8);
1726         if (index < low || index > high)
1727           pc = base_pc + def;
1728         else
1729           pc = base_pc + get4 (pc + 4 * (index - low + 3));
1730 #endif /* DIRECT_THREADED */
1731       }
1732       NEXT_INSN;
1733
1734     insn_lookupswitch:
1735       {
1736 #ifdef DIRECT_THREADED
1737         void *def = (pc++)->insn;
1738
1739         int index = POPI();
1740
1741         jint npairs = INTVAL ();
1742
1743         int max = npairs - 1;
1744         int min = 0;
1745
1746         // Simple binary search...
1747         while (min < max)
1748           {
1749             int half = (min + max) / 2;
1750             int match = pc[2 * half].int_val;
1751
1752             if (index == match)
1753               {
1754                 // Found it.
1755                 pc = (insn_slot *) pc[2 * half + 1].datum;
1756                 NEXT_INSN;
1757               }
1758             else if (index < match)
1759               // We can use HALF - 1 here because we check again on
1760               // loop exit.
1761               max = half - 1;
1762             else
1763               // We can use HALF + 1 here because we check again on
1764               // loop exit.
1765               min = half + 1;
1766           }
1767         if (index == pc[2 * min].int_val)
1768           pc = (insn_slot *) pc[2 * min + 1].datum;
1769         else
1770           pc = (insn_slot *) def;
1771 #else
1772         unsigned char *base_pc = pc-1;
1773         int index = POPI();
1774
1775         unsigned char* base = meth->bytecode ();
1776         while ((pc-base) % 4 != 0)
1777           ++pc;
1778
1779         jint def     = get4 (pc);
1780         jint npairs  = get4 (pc+4);
1781
1782         int max = npairs-1;
1783         int min = 0;
1784
1785         // Simple binary search...
1786         while (min < max)
1787           {
1788             int half = (min+max)/2;
1789             int match = get4 (pc+ 4*(2 + 2*half));
1790
1791             if (index == match)
1792               min = max = half;
1793             else if (index < match)
1794               // We can use HALF - 1 here because we check again on
1795               // loop exit.
1796               max = half - 1;
1797             else
1798               // We can use HALF + 1 here because we check again on
1799               // loop exit.
1800               min = half + 1;
1801           }
1802
1803         if (index == get4 (pc+ 4*(2 + 2*min)))
1804           pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
1805         else
1806           pc = base_pc + def;    
1807 #endif /* DIRECT_THREADED */
1808       }
1809       NEXT_INSN;
1810
1811     insn_areturn:
1812       *(jobject *) retp = POPA ();
1813       return;
1814
1815     insn_lreturn:
1816       *(jlong *) retp = POPL ();
1817       return;
1818
1819     insn_freturn:
1820       *(jfloat *) retp = POPF ();
1821       return;
1822
1823     insn_dreturn:
1824       *(jdouble *) retp = POPD ();
1825       return;
1826
1827     insn_ireturn:
1828       *(jint *) retp = POPI ();
1829       return;
1830
1831     insn_return:
1832       return;
1833
1834     insn_getstatic:
1835       {
1836         jint fieldref_index = GET2U ();
1837         SAVE_PC(); // Constant pool resolution could throw.
1838         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1839         _Jv_Field *field = pool_data[fieldref_index].field;
1840
1841         if ((field->flags & Modifier::STATIC) == 0)
1842           throw_incompatible_class_change_error 
1843             (JvNewStringLatin1 ("field no longer static"));
1844
1845         jclass type = field->type;
1846
1847         // We rewrite the instruction once we discover what it refers
1848         // to.
1849         void *newinsn = NULL;
1850         if (type->isPrimitive ())
1851           {
1852             switch (type->size_in_bytes)
1853               {
1854               case 1:
1855                 PUSHI (*field->u.byte_addr);
1856                 newinsn = AMPAMP (getstatic_resolved_1);
1857                 break;
1858
1859               case 2:
1860                 if (type == JvPrimClass (char))
1861                   {
1862                     PUSHI (*field->u.char_addr);
1863                     newinsn = AMPAMP (getstatic_resolved_char);
1864                   }
1865                 else
1866                   {
1867                     PUSHI (*field->u.short_addr);
1868                     newinsn = AMPAMP (getstatic_resolved_short);
1869                   }
1870                 break;
1871
1872               case 4:
1873                 PUSHI(*field->u.int_addr);
1874                 newinsn = AMPAMP (getstatic_resolved_4);
1875                 break;
1876
1877               case 8:
1878                 PUSHL(*field->u.long_addr);
1879                 newinsn = AMPAMP (getstatic_resolved_8);
1880                 break;
1881               }
1882           }
1883         else
1884           {
1885             PUSHA(*field->u.object_addr);
1886             newinsn = AMPAMP (getstatic_resolved_obj);
1887           }
1888
1889 #ifdef DIRECT_THREADED
1890         REWRITE_INSN (newinsn, datum, field->u.addr);
1891 #endif /* DIRECT_THREADED */
1892       }
1893       NEXT_INSN;
1894
1895 #ifdef DIRECT_THREADED
1896     getstatic_resolved_1:
1897       PUSHI (*(jbyte *) AVAL ());
1898       NEXT_INSN;
1899
1900     getstatic_resolved_char:
1901       PUSHI (*(jchar *) AVAL ());
1902       NEXT_INSN;
1903
1904     getstatic_resolved_short:
1905       PUSHI (*(jshort *) AVAL ());
1906       NEXT_INSN;
1907
1908     getstatic_resolved_4:
1909       PUSHI (*(jint *) AVAL ());
1910       NEXT_INSN;
1911
1912     getstatic_resolved_8:
1913       PUSHL (*(jlong *) AVAL ());
1914       NEXT_INSN;
1915
1916     getstatic_resolved_obj:
1917       PUSHA (*(jobject *) AVAL ());
1918       NEXT_INSN;
1919 #endif /* DIRECT_THREADED */
1920
1921     insn_getfield:
1922       {
1923         SAVE_PC();
1924         jint fieldref_index = GET2U ();
1925         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1926         _Jv_Field *field = pool_data[fieldref_index].field;
1927
1928         if ((field->flags & Modifier::STATIC) != 0)
1929           throw_incompatible_class_change_error 
1930             (JvNewStringLatin1 ("field is static"));
1931
1932         jclass type = field->type;
1933         jint field_offset = field->u.boffset;
1934
1935         jobject obj   = POPA();
1936         NULLCHECK(obj);
1937
1938         void *newinsn = NULL;
1939         _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
1940         if (type->isPrimitive ())
1941           {
1942             switch (type->size_in_bytes)
1943               {
1944               case 1:
1945                 PUSHI (val->byte_value);
1946                 newinsn = AMPAMP (getfield_resolved_1);
1947                 break;
1948
1949               case 2:
1950                 if (type == JvPrimClass (char))
1951                   {
1952                     PUSHI (val->char_value);
1953                     newinsn = AMPAMP (getfield_resolved_char);
1954                   }
1955                 else
1956                   {
1957                     PUSHI (val->short_value);
1958                     newinsn = AMPAMP (getfield_resolved_short);
1959                   }
1960                 break;
1961
1962               case 4:
1963                 PUSHI (val->int_value);
1964                 newinsn = AMPAMP (getfield_resolved_4);
1965                 break;
1966
1967               case 8:
1968                 PUSHL (val->long_value);
1969                 newinsn = AMPAMP (getfield_resolved_8);
1970                 break;
1971               }
1972           }
1973         else
1974           {
1975             PUSHA (val->object_value);
1976             newinsn = AMPAMP (getfield_resolved_obj);
1977           }
1978
1979 #ifdef DIRECT_THREADED
1980         REWRITE_INSN (newinsn, int_val, field_offset);
1981 #endif /* DIRECT_THREADED */
1982       }
1983       NEXT_INSN;
1984
1985 #ifdef DIRECT_THREADED
1986     getfield_resolved_1:
1987       {
1988         char *obj = (char *) POPA ();
1989         NULLCHECK (obj);
1990         PUSHI (*(jbyte *) (obj + INTVAL ()));
1991       }
1992       NEXT_INSN;
1993
1994     getfield_resolved_char:
1995       {
1996         char *obj = (char *) POPA ();
1997         NULLCHECK (obj);
1998         PUSHI (*(jchar *) (obj + INTVAL ()));
1999       }
2000       NEXT_INSN;
2001
2002     getfield_resolved_short:
2003       {
2004         char *obj = (char *) POPA ();
2005         NULLCHECK (obj);
2006         PUSHI (*(jshort *) (obj + INTVAL ()));
2007       }
2008       NEXT_INSN;
2009
2010     getfield_resolved_4:
2011       {
2012         char *obj = (char *) POPA ();
2013         NULLCHECK (obj);
2014         PUSHI (*(jint *) (obj + INTVAL ()));
2015       }
2016       NEXT_INSN;
2017
2018     getfield_resolved_8:
2019       {
2020         char *obj = (char *) POPA ();
2021         NULLCHECK (obj);
2022         PUSHL (*(jlong *) (obj + INTVAL ()));
2023       }
2024       NEXT_INSN;
2025
2026     getfield_resolved_obj:
2027       {
2028         char *obj = (char *) POPA ();
2029         NULLCHECK (obj);
2030         PUSHA (*(jobject *) (obj + INTVAL ()));
2031       }
2032       NEXT_INSN;
2033 #endif /* DIRECT_THREADED */
2034
2035     insn_putstatic:
2036       {
2037         SAVE_PC();
2038         jint fieldref_index = GET2U ();
2039         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2040         _Jv_Field *field = pool_data[fieldref_index].field;
2041
2042         jclass type = field->type;
2043
2044         // ResolvePoolEntry cannot check this
2045         if ((field->flags & Modifier::STATIC) == 0)
2046           throw_incompatible_class_change_error 
2047             (JvNewStringLatin1 ("field no longer static"));
2048
2049         void *newinsn = NULL;
2050         if (type->isPrimitive ())
2051           {
2052             switch (type->size_in_bytes) 
2053               {
2054               case 1:
2055                 {
2056                   jint value = POPI();
2057                   *field->u.byte_addr = value;
2058                   newinsn = AMPAMP (putstatic_resolved_1);
2059                   break;
2060                 }
2061
2062               case 2:
2063                 {
2064                   jint value = POPI();
2065                   *field->u.char_addr = value;
2066                   newinsn = AMPAMP (putstatic_resolved_2);
2067                   break;
2068                 }
2069
2070               case 4:
2071                 {
2072                   jint value = POPI();
2073                   *field->u.int_addr = value;
2074                   newinsn = AMPAMP (putstatic_resolved_4);
2075                   break;
2076                 }
2077
2078               case 8:
2079                 {
2080                   jlong value = POPL();
2081                   *field->u.long_addr = value;
2082                   newinsn = AMPAMP (putstatic_resolved_8);
2083                   break;
2084                 }
2085               }
2086           }
2087         else
2088           {
2089             jobject value = POPA();
2090             *field->u.object_addr = value;
2091             newinsn = AMPAMP (putstatic_resolved_obj);
2092           }
2093
2094 #ifdef DIRECT_THREADED
2095         REWRITE_INSN (newinsn, datum, field->u.addr);
2096 #endif /* DIRECT_THREADED */
2097       }
2098       NEXT_INSN;
2099
2100 #ifdef DIRECT_THREADED
2101     putstatic_resolved_1:
2102       *(jbyte *) AVAL () = POPI ();
2103       NEXT_INSN;
2104
2105     putstatic_resolved_2:
2106       *(jchar *) AVAL () = POPI ();
2107       NEXT_INSN;
2108
2109     putstatic_resolved_4:
2110       *(jint *) AVAL () = POPI ();
2111       NEXT_INSN;
2112
2113     putstatic_resolved_8:
2114       *(jlong *) AVAL () = POPL ();
2115       NEXT_INSN;
2116
2117     putstatic_resolved_obj:
2118       *(jobject *) AVAL () = POPA ();
2119       NEXT_INSN;
2120 #endif /* DIRECT_THREADED */
2121
2122     insn_putfield:
2123       {
2124         SAVE_PC();
2125         jint fieldref_index = GET2U ();
2126         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2127         _Jv_Field *field = pool_data[fieldref_index].field;
2128
2129         jclass type = field->type;
2130
2131         if ((field->flags & Modifier::STATIC) != 0)
2132           throw_incompatible_class_change_error 
2133             (JvNewStringLatin1 ("field is static"));
2134
2135         jint field_offset = field->u.boffset;
2136
2137         void *newinsn = NULL;
2138         if (type->isPrimitive ())
2139           {
2140             switch (type->size_in_bytes) 
2141               {
2142               case 1:
2143                 {
2144                   jint    value = POPI();
2145                   jobject obj   = POPA();
2146                   NULLCHECK(obj);
2147                   *(jbyte*) ((char*)obj + field_offset) = value;
2148                   newinsn = AMPAMP (putfield_resolved_1);
2149                   break;
2150                 }
2151
2152               case 2:
2153                 {
2154                   jint    value = POPI();
2155                   jobject obj   = POPA();
2156                   NULLCHECK(obj);
2157                   *(jchar*) ((char*)obj + field_offset) = value;
2158                   newinsn = AMPAMP (putfield_resolved_2);
2159                   break;
2160                 }
2161
2162               case 4:
2163                 {
2164                   jint    value = POPI();
2165                   jobject obj   = POPA();
2166                   NULLCHECK(obj);
2167                   *(jint*) ((char*)obj + field_offset) = value;
2168                   newinsn = AMPAMP (putfield_resolved_4);
2169                   break;
2170                 }
2171
2172               case 8:
2173                 {
2174                   jlong   value = POPL();
2175                   jobject obj   = POPA();
2176                   NULLCHECK(obj);
2177                   *(jlong*) ((char*)obj + field_offset) = value;
2178                   newinsn = AMPAMP (putfield_resolved_8);
2179                   break;
2180                 }
2181               }
2182           }
2183         else
2184           {
2185             jobject value = POPA();
2186             jobject obj   = POPA();
2187             NULLCHECK(obj);
2188             *(jobject*) ((char*)obj + field_offset) = value;
2189             newinsn = AMPAMP (putfield_resolved_obj);
2190           }
2191
2192 #ifdef DIRECT_THREADED
2193         REWRITE_INSN (newinsn, int_val, field_offset);
2194 #endif /* DIRECT_THREADED */
2195       }
2196       NEXT_INSN;
2197
2198 #ifdef DIRECT_THREADED
2199     putfield_resolved_1:
2200       {
2201         jint val = POPI ();
2202         char *obj = (char *) POPA ();
2203         NULLCHECK (obj);
2204         *(jbyte *) (obj + INTVAL ()) = val;
2205       }
2206       NEXT_INSN;
2207
2208     putfield_resolved_2:
2209       {
2210         jint val = POPI ();
2211         char *obj = (char *) POPA ();
2212         NULLCHECK (obj);
2213         *(jchar *) (obj + INTVAL ()) = val;
2214       }
2215       NEXT_INSN;
2216
2217     putfield_resolved_4:
2218       {
2219         jint val = POPI ();
2220         char *obj = (char *) POPA ();
2221         NULLCHECK (obj);
2222         *(jint *) (obj + INTVAL ()) = val;
2223       }
2224       NEXT_INSN;
2225
2226     putfield_resolved_8:
2227       {
2228         jlong val = POPL ();
2229         char *obj = (char *) POPA ();
2230         NULLCHECK (obj);
2231         *(jlong *) (obj + INTVAL ()) = val;
2232       }
2233       NEXT_INSN;
2234
2235     putfield_resolved_obj:
2236       {
2237         jobject val = POPA ();
2238         char *obj = (char *) POPA ();
2239         NULLCHECK (obj);
2240         *(jobject *) (obj + INTVAL ()) = val;
2241       }
2242       NEXT_INSN;
2243 #endif /* DIRECT_THREADED */
2244
2245     insn_invokespecial:
2246       {
2247         SAVE_PC();
2248         int index = GET2U ();
2249
2250         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2251                                                    index)).rmethod;
2252
2253         sp -= rmeth->stack_item_count;
2254
2255         // We don't use NULLCHECK here because we can't rely on that
2256         // working for <init>.  So instead we do an explicit test.
2257         if (! sp[0].o)
2258           {
2259             SAVE_PC();
2260             throw_null_pointer_exception ();
2261           }
2262
2263         fun = (void (*)()) rmeth->method->ncode;
2264
2265 #ifdef DIRECT_THREADED
2266         // Rewrite instruction so that we use a faster pre-resolved
2267         // method.
2268         REWRITE_INSN (&&invokespecial_resolved, datum, rmeth);
2269 #endif /* DIRECT_THREADED */
2270       }
2271       goto perform_invoke;
2272
2273 #ifdef DIRECT_THREADED
2274     invokespecial_resolved:
2275       {
2276         SAVE_PC();
2277         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2278         sp -= rmeth->stack_item_count;
2279         // We don't use NULLCHECK here because we can't rely on that
2280         // working for <init>.  So instead we do an explicit test.
2281         if (! sp[0].o)
2282           {
2283             throw_null_pointer_exception ();
2284           }
2285         fun = (void (*)()) rmeth->method->ncode;
2286       }
2287       goto perform_invoke;
2288 #endif /* DIRECT_THREADED */
2289
2290     insn_invokestatic:
2291       {
2292         SAVE_PC();
2293         int index = GET2U ();
2294
2295         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2296                                                    index)).rmethod;
2297
2298         sp -= rmeth->stack_item_count;
2299
2300         fun = (void (*)()) rmeth->method->ncode;
2301
2302 #ifdef DIRECT_THREADED
2303         // Rewrite instruction so that we use a faster pre-resolved
2304         // method.
2305         REWRITE_INSN (&&invokestatic_resolved, datum, rmeth);
2306 #endif /* DIRECT_THREADED */
2307       }
2308       goto perform_invoke;
2309
2310 #ifdef DIRECT_THREADED
2311     invokestatic_resolved:
2312       {
2313         SAVE_PC();
2314         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2315         sp -= rmeth->stack_item_count;
2316         fun = (void (*)()) rmeth->method->ncode;
2317       }
2318       goto perform_invoke;
2319 #endif /* DIRECT_THREADED */
2320
2321     insn_invokeinterface:
2322       {
2323         SAVE_PC();
2324         int index = GET2U ();
2325
2326         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2327                                                    index)).rmethod;
2328
2329         sp -= rmeth->stack_item_count;
2330
2331         jobject rcv = sp[0].o;
2332
2333         NULLCHECK (rcv);
2334
2335         fun = (void (*)())
2336           _Jv_LookupInterfaceMethod (rcv->getClass (),
2337                                      rmeth->method->name,
2338                                      rmeth->method->signature);
2339
2340 #ifdef DIRECT_THREADED
2341         // Rewrite instruction so that we use a faster pre-resolved
2342         // method.
2343         REWRITE_INSN (&&invokeinterface_resolved, datum, rmeth);
2344 #else
2345         // Skip dummy bytes.
2346         pc += 2;
2347 #endif /* DIRECT_THREADED */
2348       }
2349       goto perform_invoke;
2350
2351 #ifdef DIRECT_THREADED
2352     invokeinterface_resolved:
2353       {
2354         SAVE_PC();
2355         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2356         sp -= rmeth->stack_item_count;
2357         jobject rcv = sp[0].o;
2358         NULLCHECK (rcv);
2359         fun = (void (*)())
2360           _Jv_LookupInterfaceMethod (rcv->getClass (),
2361                                      rmeth->method->name,
2362                                      rmeth->method->signature);
2363       }
2364       goto perform_invoke;
2365 #endif /* DIRECT_THREADED */
2366
2367     insn_new:
2368       {
2369         SAVE_PC();
2370         int index = GET2U ();
2371         jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2372                                                           index)).clazz;
2373         /* VM spec, section 3.11.5 */
2374         if ((klass->getModifiers() & Modifier::ABSTRACT)
2375             || klass->isInterface())
2376           {
2377             jthrowable t = new java::lang::InstantiationException;
2378             INTERP_REPORT_EXCEPTION (t);
2379             throw t;
2380           }
2381         jobject res = _Jv_AllocObject (klass);
2382         PUSHA (res);
2383
2384 #ifdef DIRECT_THREADED
2385         REWRITE_INSN (&&new_resolved, datum, klass);
2386 #endif /* DIRECT_THREADED */
2387       }
2388       NEXT_INSN;
2389
2390 #ifdef DIRECT_THREADED
2391     new_resolved:
2392       {
2393         jclass klass = (jclass) AVAL ();
2394         jobject res = _Jv_AllocObject (klass);
2395         PUSHA (res);
2396       }
2397       NEXT_INSN;
2398 #endif /* DIRECT_THREADED */
2399
2400     insn_newarray:
2401       {
2402         int atype = GET1U ();
2403         int size  = POPI();
2404         jobject result = _Jv_NewArray (atype, size);
2405         PUSHA (result);
2406       }
2407       NEXT_INSN;
2408
2409     insn_anewarray:
2410       {
2411         SAVE_PC();
2412         int index = GET2U ();
2413         jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2414                                                           index)).clazz;
2415         int size  = POPI();
2416         jobject result = _Jv_NewObjectArray (size, klass, 0);
2417         PUSHA (result);
2418
2419 #ifdef DIRECT_THREADED
2420         REWRITE_INSN (&&anewarray_resolved, datum, klass);
2421 #endif /* DIRECT_THREADED */
2422       }
2423       NEXT_INSN;
2424
2425 #ifdef DIRECT_THREADED
2426     anewarray_resolved:
2427       {
2428         jclass klass = (jclass) AVAL ();
2429         int size = POPI ();
2430         jobject result = _Jv_NewObjectArray (size, klass, 0);
2431         PUSHA (result);
2432       }
2433       NEXT_INSN;
2434 #endif /* DIRECT_THREADED */
2435
2436     insn_arraylength:
2437       {
2438         __JArray *arr = (__JArray*)POPA();
2439         NULLARRAYCHECK (arr);
2440         PUSHI (arr->length);
2441       }
2442       NEXT_INSN;
2443
2444     insn_athrow:
2445       {
2446         jobject value = POPA();
2447         jthrowable t = static_cast<jthrowable> (value);
2448         INTERP_REPORT_EXCEPTION (t);
2449         throw t;
2450       }
2451       NEXT_INSN;
2452
2453     insn_checkcast:
2454       {
2455         SAVE_PC();
2456         jobject value = POPA();
2457         jint index = GET2U ();
2458         jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2459                                                        index)).clazz;
2460
2461         value = (jobject) _Jv_CheckCast (to, value);
2462
2463         PUSHA (value);
2464
2465 #ifdef DIRECT_THREADED
2466         REWRITE_INSN (&&checkcast_resolved, datum, to);
2467 #endif /* DIRECT_THREADED */
2468       }
2469       NEXT_INSN;
2470
2471 #ifdef DIRECT_THREADED
2472     checkcast_resolved:
2473       {
2474         SAVE_PC();
2475         jobject value = POPA ();
2476         jclass to = (jclass) AVAL ();
2477         value = (jobject) _Jv_CheckCast (to, value);
2478         PUSHA (value);
2479       }
2480       NEXT_INSN;
2481 #endif /* DIRECT_THREADED */
2482
2483     insn_instanceof:
2484       {
2485         SAVE_PC();
2486         jobject value = POPA();
2487         jint index = GET2U ();
2488         jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2489                                                        index)).clazz;
2490         PUSHI (to->isInstance (value));
2491
2492 #ifdef DIRECT_THREADED
2493         REWRITE_INSN (&&instanceof_resolved, datum, to);
2494 #endif /* DIRECT_THREADED */
2495       }
2496       NEXT_INSN;
2497
2498 #ifdef DIRECT_THREADED
2499     instanceof_resolved:
2500       {
2501         jobject value = POPA ();
2502         jclass to = (jclass) AVAL ();
2503         PUSHI (to->isInstance (value));
2504       }
2505       NEXT_INSN;
2506 #endif /* DIRECT_THREADED */
2507
2508     insn_monitorenter:
2509       {
2510         jobject value = POPA();
2511         NULLCHECK(value);
2512         _Jv_MonitorEnter (value);
2513       }
2514       NEXT_INSN;
2515
2516     insn_monitorexit:
2517       {
2518         jobject value = POPA();
2519         NULLCHECK(value);
2520         _Jv_MonitorExit (value);
2521       }
2522       NEXT_INSN;
2523
2524     insn_ifnull:
2525       {
2526         jobject val = POPA();
2527         if (val == NULL)
2528           TAKE_GOTO;
2529         else
2530           SKIP_GOTO;
2531       }
2532       NEXT_INSN;
2533
2534     insn_ifnonnull:
2535       {
2536         jobject val = POPA();
2537         if (val != NULL)
2538           TAKE_GOTO;
2539         else
2540           SKIP_GOTO;
2541       }
2542       NEXT_INSN;
2543
2544     insn_multianewarray:
2545       {
2546         SAVE_PC();
2547         int kind_index = GET2U ();
2548         int dim        = GET1U ();
2549
2550         jclass type    
2551           = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2552                                                kind_index)).clazz;
2553         jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
2554
2555         for (int i = dim - 1; i >= 0; i--)
2556           {
2557             sizes[i] = POPI ();
2558           }
2559
2560         jobject res    = _Jv_NewMultiArray (type,dim, sizes);
2561
2562         PUSHA (res);
2563       }
2564       NEXT_INSN;
2565
2566 #ifndef DIRECT_THREADED
2567     insn_wide:
2568       {
2569         jint the_mod_op = get1u (pc++);
2570         jint wide       = get2u (pc); pc += 2;
2571
2572         switch (the_mod_op)
2573           {
2574           case op_istore:
2575             STOREI (wide);
2576             NEXT_INSN;
2577
2578           case op_fstore:
2579             STOREF (wide);
2580             NEXT_INSN;
2581
2582           case op_astore:
2583             STOREA (wide);
2584             NEXT_INSN;
2585
2586           case op_lload:
2587             LOADL (wide);
2588             NEXT_INSN;
2589
2590           case op_dload:
2591             LOADD (wide);
2592             NEXT_INSN;
2593
2594           case op_iload:
2595             LOADI (wide);
2596             NEXT_INSN;
2597
2598           case op_fload:
2599             LOADF (wide);
2600             NEXT_INSN;
2601
2602           case op_aload:
2603             LOADA (wide);
2604             NEXT_INSN;
2605
2606           case op_lstore:
2607             STOREL (wide);
2608             NEXT_INSN;
2609
2610           case op_dstore:
2611             STORED (wide);
2612             NEXT_INSN;
2613
2614           case op_ret:
2615             pc = (unsigned char*) PEEKA (wide);
2616             NEXT_INSN;
2617
2618           case op_iinc:
2619             {
2620               jint amount = get2s (pc); pc += 2;
2621               jint value = PEEKI (wide);
2622               POKEI (wide, value+amount);
2623             }
2624             NEXT_INSN;
2625
2626           default:
2627             throw_internal_error ("illegal bytecode modified by wide");
2628           }
2629
2630       }
2631 #endif /* DIRECT_THREADED */
2632
2633     insn_breakpoint:
2634       {
2635         using namespace ::java::lang;
2636         jmethodID method = meth->self;
2637         jlocation location = meth->insn_index (pc - 1);
2638
2639         using namespace gnu::gcj::jvmti;
2640         Breakpoint *bp
2641           = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
2642                                               location);
2643         JvAssert (bp != NULL);
2644
2645         // Save the insn here since the breakpoint could be removed
2646         // before the JVMTI notification returns.
2647         pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
2648
2649         bp->execute ();
2650
2651         // Continue execution
2652 #ifdef DIRECT_THREADED
2653         goto *(opc->insn);
2654 #else
2655         goto *(insn_target[*opc]);
2656 #endif
2657       }
2658     }
2659   catch (java::lang::Throwable *ex)
2660     {
2661       // Check if the exception is handled and, if so, set the pc to the start
2662       // of the appropriate catch block.
2663       if (meth->check_handler (&pc, meth, ex))
2664         {
2665           sp = stack;
2666           sp++->o = ex; // Push exception.
2667 #ifdef DEBUG
2668           if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
2669             {
2670               using namespace gnu::gcj::jvmti;
2671               jlong catch_meth = reinterpret_cast<jlong> (meth->get_method ());
2672               jlong catch_loc = meth->insn_index (pc);
2673               _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
2674                                    _Jv_GetCurrentJNIEnv (), catch_meth,
2675                                    catch_loc, ex);
2676             }
2677 #endif
2678           NEXT_INSN;
2679         }
2680
2681       // No handler, so re-throw.
2682       throw ex;
2683     }