OSDN Git Service

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