OSDN Git Service

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