OSDN Git Service

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