OSDN Git Service

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