OSDN Git Service

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