OSDN Git Service

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