OSDN Git Service

* mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
[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 <alloca.h>
39
40 #define ClassError _CL_Q34java4lang5Error
41 extern java::lang::Class ClassError;
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 __P((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]);
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
1943               case 2:
1944                 if (type == JvPrimClass (char))
1945                   PUSHI(*(jchar*) (field->u.addr));
1946                 else
1947                   PUSHI(*(jshort*) (field->u.addr));
1948                 break;
1949
1950               case 4:
1951                 PUSHI(*(jint*) (field->u.addr));
1952                 break;
1953
1954               case 8:
1955                 PUSHL(*(jlong*) (field->u.addr));
1956                 break;
1957               }
1958           }
1959         else
1960           {
1961             PUSHA(*(jobject*) (field->u.addr));
1962           }
1963       }
1964       NEXT_INSN;
1965
1966      insn_getfield:
1967       SAVE_PC;
1968       {
1969         jint fieldref_index = get2u (pc); pc += 2;
1970         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
1971         _Jv_Field *field = pool_data[fieldref_index].field;
1972
1973         if ((field->flags & Modifier::STATIC) != 0)
1974           throw_incompatible_class_change_error 
1975             (JvNewStringLatin1 ("field is static"));
1976
1977         jclass type = field->type;
1978         jint field_offset = field->u.boffset;
1979         if (field_offset > 0xffff)
1980           JvThrow (new java::lang::VirtualMachineError);
1981
1982         jobject obj   = POPA();
1983         NULLCHECK(obj);
1984
1985         if (type->isPrimitive ())
1986           {
1987             switch (type->size_in_bytes)
1988               {
1989               case 1:
1990                 PUSHI (*(jbyte*) ((char*)obj + field_offset));
1991                 break;
1992
1993               case 2:
1994                 if (type == JvPrimClass (char))
1995                   PUSHI (*(jchar*) ((char*)obj + field_offset));
1996                 else
1997                   PUSHI (*(jshort*) ((char*)obj + field_offset));
1998                 break;
1999
2000               case 4:
2001                 PUSHI (*(jint*) ((char*)obj + field_offset));
2002                 break;
2003
2004               case 8:
2005                 PUSHL(*(jlong*) ((char*)obj + field_offset));
2006                 break;
2007               }
2008           }
2009         else
2010           {
2011             PUSHA(*(jobject*) ((char*)obj + field_offset));
2012           }
2013       }
2014       NEXT_INSN;
2015
2016      insn_putstatic:
2017       SAVE_PC;
2018       {
2019         jint fieldref_index = get2u (pc); pc += 2;
2020         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
2021         _Jv_Field *field = pool_data[fieldref_index].field;
2022
2023         jclass type = field->type;
2024
2025         // ResolvePoolEntry cannot check this
2026         if ((field->flags & Modifier::STATIC) == 0)
2027           throw_incompatible_class_change_error 
2028             (JvNewStringLatin1 ("field no longer static"));
2029
2030         if (type->isPrimitive ())
2031           {
2032             switch (type->size_in_bytes) 
2033               {
2034               case 1:
2035                 {
2036                   jint value = POPI();
2037                   *(jbyte*) (field->u.addr) = value;
2038                   break;
2039                 }
2040
2041               case 2:
2042                 {
2043                   jint value = POPI();
2044                   *(jchar*) (field->u.addr) = value;
2045                   break;
2046                 }
2047
2048               case 4:
2049                 {
2050                   jint value = POPI();
2051                   *(jint*) (field->u.addr) = value;
2052                   break;
2053                 }
2054
2055               case 8:
2056                 {
2057                   jlong value = POPL();
2058                   *(jlong*) (field->u.addr) = value;
2059                   break;
2060                 }
2061               }
2062           }
2063         else
2064           {
2065             jobject value = POPA();
2066             *(jobject*) (field->u.addr) = value;
2067           }
2068       }
2069       NEXT_INSN;
2070
2071
2072      insn_putfield:
2073       SAVE_PC;
2074       {
2075         jint fieldref_index = get2u (pc); pc += 2;
2076         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
2077         _Jv_Field *field = pool_data[fieldref_index].field;
2078
2079         jclass type = field->type;
2080
2081         if ((field->flags & Modifier::STATIC) != 0)
2082           throw_incompatible_class_change_error 
2083             (JvNewStringLatin1 ("field is static"));
2084
2085         jint field_offset = field->u.boffset;
2086         if (field_offset > 0xffff)
2087           JvThrow (new java::lang::VirtualMachineError);
2088
2089         if (type->isPrimitive ())
2090           {
2091             switch (type->size_in_bytes) 
2092               {
2093               case 1:
2094                 {
2095                   jint    value = POPI();
2096                   jobject obj   = POPA();
2097                   NULLCHECK(obj);
2098                   *(jbyte*) ((char*)obj + field_offset) = value;
2099                   break;
2100                 }
2101
2102               case 2:
2103                 {
2104                   jint    value = POPI();
2105                   jobject obj   = POPA();
2106                   NULLCHECK(obj);
2107                   *(jchar*) ((char*)obj + field_offset) = value;
2108                   break;
2109                 }
2110
2111               case 4:
2112                 {
2113                   jint    value = POPI();
2114                   jobject obj   = POPA();
2115                   NULLCHECK(obj);
2116                   *(jint*) ((char*)obj + field_offset) = value;
2117                   break;
2118                 }
2119
2120               case 8:
2121                 {
2122                   jlong   value = POPL();
2123                   jobject obj   = POPA();
2124                   NULLCHECK(obj);
2125                   *(jlong*) ((char*)obj + field_offset) = value;
2126                   break;
2127                 }
2128               }
2129           }
2130         else
2131           {
2132             jobject value = POPA();
2133             jobject obj   = POPA();
2134             NULLCHECK(obj);
2135             *(jobject*) ((char*)obj + field_offset) = value;
2136           }
2137       }
2138       NEXT_INSN;
2139
2140      insn_invokespecial:
2141       SAVE_PC;
2142       {
2143         int index = get2u (pc); pc += 2;
2144
2145         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2146
2147         sp -= rmeth->stack_item_count;
2148
2149         NULLCHECK(sp[0]);
2150
2151         fun = (void (*) (...))rmeth->method->ncode;
2152       }
2153       goto perform_invoke;
2154
2155      insn_invokestatic:
2156       SAVE_PC;
2157       {
2158         int index = get2u (pc); pc += 2;
2159
2160         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2161
2162         sp -= rmeth->stack_item_count;
2163
2164         _Jv_InitClass (rmeth->klass);
2165         fun = (void (*) (...))rmeth->method->ncode;
2166       }
2167       goto perform_invoke;
2168
2169      insn_invokeinterface:
2170       SAVE_PC;
2171       {
2172         int index = get2u (pc); pc += 2;
2173
2174         // invokeinterface has two unused bytes...
2175         pc += 2;
2176
2177         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2178
2179         sp -= rmeth->stack_item_count;
2180         NULLCHECK(sp[0]);
2181
2182         jobject rcv = sp[0].o;
2183
2184         fun = (void (*) (...))
2185           _Jv_LookupInterfaceMethod (rcv->getClass (),
2186                                      rmeth->method->name,
2187                                      rmeth->method->signature);
2188       }
2189       goto perform_invoke;
2190
2191
2192      insn_new:
2193       SAVE_PC;
2194       {
2195         int index = get2u (pc); pc += 2;
2196         jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2197         _Jv_InitClass (klass);
2198         jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
2199         PUSHA (res);
2200       }
2201       NEXT_INSN;
2202
2203      insn_newarray:
2204       SAVE_PC;
2205       {
2206         int atype = get1u (pc++);
2207         int size  = POPI();
2208         jobject result = _Jv_NewArray (atype, size);
2209         PUSHA (result);
2210       }
2211       NEXT_INSN;
2212
2213      insn_anewarray:
2214       SAVE_PC;
2215       {
2216         int index = get2u (pc); pc += 2;
2217         jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2218         int size  = POPI();
2219         _Jv_InitClass (klass);
2220         jobject result = _Jv_NewObjectArray (size, klass, 0);
2221         PUSHA (result);
2222       }
2223       NEXT_INSN;
2224
2225      insn_arraylength:
2226       SAVE_PC;
2227       {
2228         __JArray *arr = (__JArray*)POPA();
2229         PUSHI (arr->length);
2230       }
2231       NEXT_INSN;
2232
2233      insn_athrow:
2234       SAVE_PC;
2235       {
2236         jobject value = POPA();
2237         JvThrow (value);
2238       }
2239       NEXT_INSN;
2240
2241      insn_checkcast:
2242       SAVE_PC;
2243       {
2244         jobject value = POPA();
2245         jint index = get2u (pc); pc += 2;
2246         jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2247
2248         if (value != NULL && ! to->isInstance (value))
2249           {
2250             JvThrow (new java::lang::ClassCastException
2251                      (to->getName()));
2252           }
2253
2254         PUSHA (value);
2255       }
2256       NEXT_INSN;
2257
2258      insn_instanceof:
2259       SAVE_PC;
2260       {
2261         jobject value = POPA();
2262         jint index = get2u (pc); pc += 2;
2263         jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2264         PUSHI (to->isInstance (value));
2265       }
2266       NEXT_INSN;
2267
2268      insn_monitorenter:
2269       SAVE_PC;
2270       {
2271         jobject value = POPA();
2272         NULLCHECK(value);
2273         _Jv_MonitorEnter (value);
2274       }
2275       NEXT_INSN;
2276
2277      insn_monitorexit:
2278       SAVE_PC;
2279       {
2280         jobject value = POPA();
2281         NULLCHECK(value);
2282         _Jv_MonitorExit (value);
2283       }
2284       NEXT_INSN;
2285
2286      insn_ifnull:
2287       {
2288         unsigned char* base_pc = pc-1;
2289         jint offset = get2s (pc); pc += 2;
2290         jobject val = POPA();
2291         if (val == NULL)
2292           pc = base_pc+offset;
2293       }
2294       NEXT_INSN;
2295
2296      insn_ifnonnull:
2297       {
2298         unsigned char* base_pc = pc-1;
2299         jint offset = get2s (pc); pc += 2;
2300         jobject val = POPA();
2301         if (val != NULL)
2302           pc = base_pc+offset;
2303       }
2304       NEXT_INSN;
2305
2306      insn_wide:
2307       SAVE_PC;
2308       {
2309         jint the_mod_op = get1u (pc++);
2310         jint wide       = get2u (pc); pc += 2;
2311
2312         switch (the_mod_op)
2313           {
2314           case op_istore:
2315             STOREI (wide);
2316             NEXT_INSN;
2317
2318           case op_fstore:
2319             STOREF (wide);
2320             NEXT_INSN;
2321
2322           case op_astore:
2323             STOREA (wide);
2324             NEXT_INSN;
2325
2326           case op_lload:
2327             LOADL (wide);
2328             NEXT_INSN;
2329
2330           case op_dload:
2331             LOADD (wide);
2332             NEXT_INSN;
2333
2334           case op_iload:
2335             LOADI (wide);
2336             NEXT_INSN;
2337
2338           case op_aload:
2339             LOADA (wide);
2340             NEXT_INSN;
2341
2342           case op_lstore:
2343             STOREL (wide);
2344             NEXT_INSN;
2345
2346           case op_dstore:
2347             STORED (wide);
2348             NEXT_INSN;
2349
2350           case op_ret:
2351             pc = (unsigned char*) PEEKA (wide);
2352             NEXT_INSN;
2353
2354           case op_iinc:
2355             {
2356               jint amount = get2s (pc); pc += 2;
2357               jint value = PEEKI (wide);
2358               POKEI (wide, value+amount);
2359             }
2360             NEXT_INSN;
2361
2362           default:
2363             throw_internal_error ("illegal bytecode modified by wide");
2364           }
2365
2366       }
2367
2368      insn_multianewarray:
2369       SAVE_PC;
2370       {
2371         int kind_index = get2u (pc); pc += 2;
2372         int dim        = get1u (pc); pc += 1;
2373
2374         jclass type    
2375           = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
2376         _Jv_InitClass (type);
2377         jint *sizes    = (jint*) alloca (sizeof (jint)*dim);
2378
2379         for (int i = dim - 1; i >= 0; i--)
2380           {
2381             sizes[i] = POPI ();
2382           }
2383
2384         jobject res    = _Jv_NewMultiArray (type,dim, sizes);
2385
2386         PUSHA (res);
2387       }
2388       NEXT_INSN;
2389
2390      insn_goto_w:
2391       {
2392         unsigned char* base_pc = pc-1;
2393         int offset = get4 (pc); pc += 4;
2394         pc = base_pc+offset;
2395       }
2396       NEXT_INSN;
2397
2398      insn_jsr_w:
2399       {
2400         unsigned char* base_pc = pc-1;
2401         int offset = get4 (pc); pc += 4;
2402         PUSHA((jobject)pc);
2403         pc = base_pc+offset;
2404       }
2405       NEXT_INSN;
2406 }
2407
2408
2409 static void
2410 throw_internal_error (char *msg)
2411 {
2412   JvThrow (new java::lang::InternalError (JvNewStringLatin1 (msg)));
2413 }
2414
2415 static void 
2416 throw_incompatible_class_change_error (jstring msg)
2417 {
2418   JvThrow (new java::lang::IncompatibleClassChangeError (msg));
2419 }
2420
2421 #ifndef HANDLE_SEGV
2422 static java::lang::NullPointerException *null_pointer_exc;
2423 static void 
2424 throw_null_pointer_exception ()
2425 {
2426   if (null_pointer_exc == NULL)
2427     null_pointer_exc = new java::lang::NullPointerException;
2428
2429   JvThrow (null_pointer_exc);
2430 }
2431 #endif
2432
2433 #endif // INTERPRETER