OSDN Git Service

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