OSDN Git Service

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