OSDN Git Service

fortran/
[pf3gnuchains/gcc-fork.git] / libjava / interpret.cc
1 // interpret.cc - Code for the interpreter
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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 #include <platform.h>
15
16 #pragma implementation "java-interp.h"
17
18 #include <jvm.h>
19 #include <java-cpool.h>
20 #include <java-interp.h>
21 #include <java/lang/System.h>
22 #include <java/lang/String.h>
23 #include <java/lang/Integer.h>
24 #include <java/lang/Long.h>
25 #include <java/lang/StringBuffer.h>
26 #include <java/lang/Class.h>
27 #include <java/lang/reflect/Modifier.h>
28 #include <java/lang/InternalError.h>
29 #include <java/lang/NullPointerException.h>
30 #include <java/lang/ArithmeticException.h>
31 #include <java/lang/IncompatibleClassChangeError.h>
32 #include <java/lang/InstantiationException.h>
33 #include <java/lang/Thread.h>
34 #include <java-insns.h>
35 #include <java-signal.h>
36 #include <java/lang/ClassFormatError.h>
37 #include <execution.h>
38 #include <java/lang/reflect/Modifier.h>
39
40 #include <gnu/classpath/jdwp/Jdwp.h>
41
42 #ifdef INTERPRETER
43
44 // Execution engine for interpreted code.
45 _Jv_InterpreterEngine _Jv_soleInterpreterEngine;
46
47 #include <stdlib.h>
48
49 using namespace gcj;
50
51 static void throw_internal_error (const char *msg)
52   __attribute__ ((__noreturn__));
53 static void throw_incompatible_class_change_error (jstring msg)
54   __attribute__ ((__noreturn__));
55 static void throw_null_pointer_exception ()
56   __attribute__ ((__noreturn__));
57
58 static void throw_class_format_error (jstring msg)
59         __attribute__ ((__noreturn__));
60 static void throw_class_format_error (const char *msg)
61         __attribute__ ((__noreturn__));
62
63 #ifdef DIRECT_THREADED
64 // Lock to ensure that methods are not compiled concurrently.
65 // We could use a finer-grained lock here, however it is not safe to use
66 // the Class monitor as user code in another thread could hold it.
67 static _Jv_Mutex_t compile_mutex;
68
69 void
70 _Jv_InitInterpreter()
71 {
72   _Jv_MutexInit (&compile_mutex);
73 }
74 #else
75 void _Jv_InitInterpreter() {}
76 #endif
77
78 // The breakpoint instruction. For the direct threaded case,
79 // _Jv_InterpMethod::compile will initialize breakpoint_insn
80 // the first time it is called.
81 #ifdef DIRECT_THREADED
82 insn_slot _Jv_InterpMethod::bp_insn_slot;
83 pc_t _Jv_InterpMethod::breakpoint_insn = NULL;
84 #else
85 unsigned char _Jv_InterpMethod::bp_insn_opcode
86   = static_cast<unsigned char> (op_breakpoint);
87 pc_t _Jv_InterpMethod::breakpoint_insn = &_Jv_InterpMethod::bp_insn_opcode;
88 #endif
89
90 extern "C" double __ieee754_fmod (double,double);
91
92 static inline void dupx (_Jv_word *sp, int n, int x)
93 {
94   // first "slide" n+x elements n to the right
95   int top = n-1;
96   for (int i = 0; i < n+x; i++)
97     {
98       sp[(top-i)] = sp[(top-i)-n];
99     }
100   
101   // next, copy the n top elements, n+x down
102   for (int i = 0; i < n; i++)
103     {
104       sp[top-(n+x)-i] = sp[top-i];
105     }
106 }
107
108 // Used to convert from floating types to integral types.
109 template<typename TO, typename FROM>
110 static inline TO
111 convert (FROM val, TO min, TO max)
112 {
113   TO ret;
114   if (val >= (FROM) max)
115     ret = max;
116   else if (val <= (FROM) min)
117     ret = min;
118   else if (val != val)
119     ret = 0;
120   else
121     ret = (TO) val;
122   return ret;
123 }
124
125 #define PUSHA(V)  (sp++)->o = (V)
126 #define PUSHI(V)  (sp++)->i = (V)
127 #define PUSHF(V)  (sp++)->f = (V)
128 #if SIZEOF_VOID_P == 8
129 # define PUSHL(V)   (sp->l = (V), sp += 2)
130 # define PUSHD(V)   (sp->d = (V), sp += 2)
131 #else
132 # define PUSHL(V)  do { _Jv_word2 w2; w2.l=(V); \
133                         (sp++)->ia[0] = w2.ia[0]; \
134                         (sp++)->ia[0] = w2.ia[1]; } while (0)
135 # define PUSHD(V)  do { _Jv_word2 w2; w2.d=(V); \
136                         (sp++)->ia[0] = w2.ia[0]; \
137                         (sp++)->ia[0] = w2.ia[1]; } while (0)
138 #endif
139
140 #define POPA()    ((--sp)->o)
141 #define POPI()    ((jint) (--sp)->i) // cast since it may be promoted
142 #define POPF()    ((jfloat) (--sp)->f)
143 #if SIZEOF_VOID_P == 8
144 # define POPL()   (sp -= 2, (jlong) sp->l)
145 # define POPD()   (sp -= 2, (jdouble) sp->d)
146 #else
147 # define POPL()    ({ _Jv_word2 w2; \
148                      w2.ia[1] = (--sp)->ia[0]; \
149                      w2.ia[0] = (--sp)->ia[0]; w2.l; })
150 # define POPD()    ({ _Jv_word2 w2; \
151                      w2.ia[1] = (--sp)->ia[0]; \
152                      w2.ia[0] = (--sp)->ia[0]; w2.d; })
153 #endif
154
155 #define LOADA(I)  (sp++)->o = locals[I].o
156 #define LOADI(I)  (sp++)->i = locals[I].i
157 #define LOADF(I)  (sp++)->f = locals[I].f
158 #if SIZEOF_VOID_P == 8
159 # define LOADL(I)  (sp->l = locals[I].l, sp += 2)
160 # define LOADD(I)  (sp->d = locals[I].d, sp += 2)
161 #else
162 # define LOADL(I)  do { jint __idx = (I); \
163                         (sp++)->ia[0] = locals[__idx].ia[0]; \
164                         (sp++)->ia[0] = locals[__idx+1].ia[0]; \
165                    } while (0)
166 # define LOADD(I)  LOADL(I)
167 #endif
168
169 #define STOREA(I)               \
170 do {                                    \
171 DEBUG_LOCALS_INSN(I, 'o');              \
172 locals[I].o = (--sp)->o;                \
173 } while(0)
174 #define STOREI(I)               \
175 do {                                    \
176 DEBUG_LOCALS_INSN (I, 'i');             \
177 locals[I].i = (--sp)->i;                \
178 } while(0)
179 #define STOREF(I)               \
180 do {                                    \
181 DEBUG_LOCALS_INSN (I, 'f');             \
182 locals[I].f = (--sp)->f;                \
183 } while(0)
184 #if SIZEOF_VOID_P == 8
185 # define STOREL(I)                      \
186 do {                                                    \
187 DEBUG_LOCALS_INSN (I, 'l');                     \
188 (sp -= 2, locals[I].l = sp->l);         \
189 } while(0)
190 # define STORED(I)                              \
191 do {                                                    \
192 DEBUG_LOCALS_INSN (I, 'd');                     \
193 (sp -= 2, locals[I].d = sp->d);         \
194 } while(0)
195
196 #else
197 # define STOREL(I)              \
198 do { DEBUG_LOCALS_INSN(I, 'l'); \
199          jint __idx = (I);      \
200      locals[__idx+1].ia[0] = (--sp)->ia[0]; \
201      locals[__idx].ia[0] = (--sp)->ia[0];       \
202    } while (0)
203 # define STORED(I)              \
204 do { DEBUG_LOCALS_INSN(I, 'd'); \
205          jint __idx = (I);      \
206      locals[__idx+1].ia[0] = (--sp)->ia[0]; \
207      locals[__idx].ia[0] = (--sp)->ia[0];       \
208    } while (0)
209 #endif
210
211 #define PEEKI(I)  (locals+(I))->i
212 #define PEEKA(I)  (locals+(I))->o
213
214 #define POKEI(I,V)      \
215 DEBUG_LOCALS_INSN(I,'i'); \
216 ((locals+(I))->i = (V))
217
218
219 #define BINOPI(OP) { \
220    jint value2 = POPI(); \
221    jint value1 = POPI(); \
222    PUSHI(value1 OP value2); \
223 }
224
225 #define BINOPF(OP) { \
226    jfloat value2 = POPF(); \
227    jfloat value1 = POPF(); \
228    PUSHF(value1 OP value2); \
229 }
230
231 #define BINOPL(OP) { \
232    jlong value2 = POPL(); \
233    jlong value1 = POPL(); \
234    PUSHL(value1 OP value2); \
235 }
236
237 #define BINOPD(OP) { \
238    jdouble value2 = POPD(); \
239    jdouble value1 = POPD(); \
240    PUSHD(value1 OP value2); \
241 }
242
243 static inline jint get1s(unsigned char* loc) {
244   return *(signed char*)loc;
245 }
246
247 static inline jint get1u(unsigned char* loc) {
248   return *loc;
249 }
250
251 static inline jint get2s(unsigned char* loc) {
252   return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
253 }
254
255 static inline jint get2u(unsigned char* loc) {
256   return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
257 }
258
259 static jint get4(unsigned char* loc) {
260   return (((jint)(loc[0])) << 24) 
261        | (((jint)(loc[1])) << 16) 
262        | (((jint)(loc[2])) << 8) 
263        | (((jint)(loc[3])) << 0);
264 }
265
266 #define SAVE_PC() frame_desc.pc = pc
267
268 // We used to define this conditionally, depending on HANDLE_SEGV.
269 // However, that runs into a problem if a chunk in low memory is
270 // mapped and we try to look at a field near the end of a large
271 // object.  See PR 26858 for details.  It is, most likely, relatively
272 // inexpensive to simply do this check always.
273 #define NULLCHECK(X) \
274   do { SAVE_PC(); if ((X)==NULL) throw_null_pointer_exception (); } while (0)
275
276 // Note that we can still conditionally define NULLARRAYCHECK, since
277 // we know that all uses of an array will first reference the length
278 // field, which is first -- and thus will trigger a SEGV.
279 #ifdef HANDLE_SEGV
280 #define NULLARRAYCHECK(X) SAVE_PC()
281 #else
282 #define NULLARRAYCHECK(X) \
283   do { SAVE_PC(); if ((X)==NULL) { throw_null_pointer_exception (); } } while (0)
284 #endif
285
286 #define ARRAYBOUNDSCHECK(array, index)                                        \
287   do                                                                          \
288     {                                                                         \
289       if (((unsigned) index) >= (unsigned) (array->length))                   \
290         _Jv_ThrowBadArrayIndex (index);                                       \
291     }                                                                         \
292   while (0)
293
294 void
295 _Jv_InterpMethod::run_normal (ffi_cif *,
296                               void* ret,
297                               ffi_raw * args,
298                               void* __this)
299 {
300   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
301   run (ret, args, _this);
302 }
303
304 void
305 _Jv_InterpMethod::run_normal_debug (ffi_cif *,
306                               void* ret,
307                               ffi_raw * args,
308                               void* __this)
309 {
310   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
311   run_debug (ret, args, _this);
312 }
313
314 void
315 _Jv_InterpMethod::run_synch_object (ffi_cif *,
316                                     void* ret,
317                                     ffi_raw * args,
318                                     void* __this)
319 {
320   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
321
322   jobject rcv = (jobject) args[0].ptr;
323   JvSynchronize mutex (rcv);
324
325   run (ret, args, _this);
326 }
327
328 void
329 _Jv_InterpMethod::run_synch_object_debug (ffi_cif *,
330                                     void* ret,
331                                     ffi_raw * args,
332                                     void* __this)
333 {
334   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
335
336   jobject rcv = (jobject) args[0].ptr;
337   JvSynchronize mutex (rcv);
338
339   run_debug (ret, args, _this);
340 }
341
342 void
343 _Jv_InterpMethod::run_class (ffi_cif *,
344                              void* ret,
345                              ffi_raw * args,
346                              void* __this)
347 {
348   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
349   _Jv_InitClass (_this->defining_class);
350   run (ret, args, _this);
351 }
352
353 void
354 _Jv_InterpMethod::run_class_debug (ffi_cif *,
355                              void* ret,
356                              ffi_raw * args,
357                              void* __this)
358 {
359   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
360   _Jv_InitClass (_this->defining_class);
361   run_debug (ret, args, _this);
362 }
363
364 void
365 _Jv_InterpMethod::run_synch_class (ffi_cif *,
366                                    void* ret,
367                                    ffi_raw * args,
368                                    void* __this)
369 {
370   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
371
372   jclass sync = _this->defining_class;
373   _Jv_InitClass (sync);
374   JvSynchronize mutex (sync);
375
376   run (ret, args, _this);
377 }
378
379 void
380 _Jv_InterpMethod::run_synch_class_debug (ffi_cif *,
381                                    void* ret,
382                                    ffi_raw * args,
383                                    void* __this)
384 {
385   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
386
387   jclass sync = _this->defining_class;
388   _Jv_InitClass (sync);
389   JvSynchronize mutex (sync);
390
391   run_debug (ret, args, _this);
392 }
393
394 #ifdef DIRECT_THREADED
395 // "Compile" a method by turning it from bytecode to direct-threaded
396 // code.
397 void
398 _Jv_InterpMethod::compile (const void * const *insn_targets)
399 {
400   insn_slot *insns = NULL;
401   int next = 0;
402   unsigned char *codestart = bytecode ();
403   unsigned char *end = codestart + code_length;
404   _Jv_word *pool_data = defining_class->constants.data;
405
406 #define SET_ONE(Field, Value)                                                 \
407   do                                                                          \
408     {                                                                         \
409       if (first_pass)                                                         \
410         ++next;                                                               \
411       else                                                                    \
412         insns[next++].Field = Value;                                          \
413     }                                                                         \
414   while (0)
415
416 #define SET_INSN(Value) SET_ONE (insn, (void *) Value)
417 #define SET_INT(Value) SET_ONE (int_val, Value)
418 #define SET_DATUM(Value) SET_ONE (datum, Value)
419
420   // Map from bytecode PC to slot in INSNS.
421   int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
422   for (int i = 0; i < code_length; ++i)
423     pc_mapping[i] = -1;
424
425   for (int i = 0; i < 2; ++i)
426     {
427       jboolean first_pass = i == 0;
428
429       if (! first_pass)
430         {
431           insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
432           number_insn_slots = next;
433           next = 0;
434         }
435
436       unsigned char *pc = codestart;
437       while (pc < end)
438         {
439           int base_pc_val = pc - codestart;
440           if (first_pass)
441             pc_mapping[base_pc_val] = next;
442
443           java_opcode opcode = (java_opcode) *pc++;
444           // Just elide NOPs.
445           if (opcode == op_nop)
446             continue;
447           SET_INSN (insn_targets[opcode]);
448
449           switch (opcode)
450             {
451             case op_nop:
452             case op_aconst_null:
453             case op_iconst_m1:
454             case op_iconst_0:
455             case op_iconst_1:
456             case op_iconst_2:
457             case op_iconst_3:
458             case op_iconst_4:
459             case op_iconst_5:
460             case op_lconst_0:
461             case op_lconst_1:
462             case op_fconst_0:
463             case op_fconst_1:
464             case op_fconst_2:
465             case op_dconst_0:
466             case op_dconst_1:
467             case op_iload_0:
468             case op_iload_1:
469             case op_iload_2:
470             case op_iload_3:
471             case op_lload_0:
472             case op_lload_1:
473             case op_lload_2:
474             case op_lload_3:
475             case op_fload_0:
476             case op_fload_1:
477             case op_fload_2:
478             case op_fload_3:
479             case op_dload_0:
480             case op_dload_1:
481             case op_dload_2:
482             case op_dload_3:
483             case op_aload_0:
484             case op_aload_1:
485             case op_aload_2:
486             case op_aload_3:
487             case op_iaload:
488             case op_laload:
489             case op_faload:
490             case op_daload:
491             case op_aaload:
492             case op_baload:
493             case op_caload:
494             case op_saload:
495             case op_istore_0:
496             case op_istore_1:
497             case op_istore_2:
498             case op_istore_3:
499             case op_lstore_0:
500             case op_lstore_1:
501             case op_lstore_2:
502             case op_lstore_3:
503             case op_fstore_0:
504             case op_fstore_1:
505             case op_fstore_2:
506             case op_fstore_3:
507             case op_dstore_0:
508             case op_dstore_1:
509             case op_dstore_2:
510             case op_dstore_3:
511             case op_astore_0:
512             case op_astore_1:
513             case op_astore_2:
514             case op_astore_3:
515             case op_iastore:
516             case op_lastore:
517             case op_fastore:
518             case op_dastore:
519             case op_aastore:
520             case op_bastore:
521             case op_castore:
522             case op_sastore:
523             case op_pop:
524             case op_pop2:
525             case op_dup:
526             case op_dup_x1:
527             case op_dup_x2:
528             case op_dup2:
529             case op_dup2_x1:
530             case op_dup2_x2:
531             case op_swap:
532             case op_iadd:
533             case op_isub:
534             case op_imul:
535             case op_idiv:
536             case op_irem:
537             case op_ishl:
538             case op_ishr:
539             case op_iushr:
540             case op_iand:
541             case op_ior:
542             case op_ixor:
543             case op_ladd:
544             case op_lsub:
545             case op_lmul:
546             case op_ldiv:
547             case op_lrem:
548             case op_lshl:
549             case op_lshr:
550             case op_lushr:
551             case op_land:
552             case op_lor:
553             case op_lxor:
554             case op_fadd:
555             case op_fsub:
556             case op_fmul:
557             case op_fdiv:
558             case op_frem:
559             case op_dadd:
560             case op_dsub:
561             case op_dmul:
562             case op_ddiv:
563             case op_drem:
564             case op_ineg:
565             case op_i2b:
566             case op_i2c:
567             case op_i2s:
568             case op_lneg:
569             case op_fneg:
570             case op_dneg:
571             case op_i2l:
572             case op_i2f:
573             case op_i2d:
574             case op_l2i:
575             case op_l2f:
576             case op_l2d:
577             case op_f2i:
578             case op_f2l:
579             case op_f2d:
580             case op_d2i:
581             case op_d2l:
582             case op_d2f:
583             case op_lcmp:
584             case op_fcmpl:
585             case op_fcmpg:
586             case op_dcmpl:
587             case op_dcmpg:
588             case op_monitorenter:
589             case op_monitorexit:
590             case op_ireturn:
591             case op_lreturn:
592             case op_freturn:
593             case op_dreturn:
594             case op_areturn:
595             case op_return:
596             case op_athrow:
597             case op_arraylength:
598               // No argument, nothing else to do.
599               break;
600
601             case op_bipush:
602               SET_INT (get1s (pc));
603               ++pc;
604               break;
605
606             case op_ldc:
607               {
608                 int index = get1u (pc);
609                 ++pc;
610                 // For an unresolved class we want to delay resolution
611                 // until execution.
612                 if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
613                   {
614                     --next;
615                     SET_INSN (insn_targets[int (op_jsr_w) + 1]);
616                     SET_INT (index);
617                   }
618                 else
619                   SET_DATUM (pool_data[index].o);
620               }
621               break;
622
623             case op_ret:
624             case op_iload:
625             case op_lload:
626             case op_fload:
627             case op_dload:
628             case op_aload:
629             case op_istore:
630             case op_lstore:
631             case op_fstore:
632             case op_dstore:
633             case op_astore:
634             case op_newarray:
635               SET_INT (get1u (pc));
636               ++pc;
637               break;
638
639             case op_iinc:
640               SET_INT (get1u (pc));
641               SET_INT (get1s (pc + 1));
642               pc += 2;
643               break;
644
645             case op_ldc_w:
646               {
647                 int index = get2u (pc);
648                 pc += 2;
649                 // For an unresolved class we want to delay resolution
650                 // until execution.
651                 if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
652                   {
653                     --next;
654                     SET_INSN (insn_targets[int (op_jsr_w) + 1]);
655                     SET_INT (index);
656                   }
657                 else
658                   SET_DATUM (pool_data[index].o);
659               }
660               break;
661
662             case op_ldc2_w:
663               {
664                 int index = get2u (pc);
665                 pc += 2;
666                 SET_DATUM (&pool_data[index]);
667               }
668               break;
669
670             case op_sipush:
671               SET_INT (get2s (pc));
672               pc += 2;
673               break;
674
675             case op_new:
676             case op_getstatic:
677             case op_getfield:
678             case op_putfield:
679             case op_putstatic:
680             case op_anewarray:
681             case op_instanceof:
682             case op_checkcast:
683             case op_invokespecial:
684             case op_invokestatic:
685             case op_invokevirtual:
686               SET_INT (get2u (pc));
687               pc += 2;
688               break;
689
690             case op_multianewarray:
691               SET_INT (get2u (pc));
692               SET_INT (get1u (pc + 2));
693               pc += 3;
694               break;
695
696             case op_jsr:
697             case op_ifeq:
698             case op_ifne:
699             case op_iflt:
700             case op_ifge:
701             case op_ifgt:
702             case op_ifle:
703             case op_if_icmpeq:
704             case op_if_icmpne:
705             case op_if_icmplt:
706             case op_if_icmpge:
707             case op_if_icmpgt:
708             case op_if_icmple:
709             case op_if_acmpeq:
710             case op_if_acmpne:
711             case op_ifnull:
712             case op_ifnonnull:
713             case op_goto:
714               {
715                 int offset = get2s (pc);
716                 pc += 2;
717
718                 int new_pc = base_pc_val + offset;
719
720                 bool orig_was_goto = opcode == op_goto;
721
722                 // Thread jumps.  We limit the loop count; this lets
723                 // us avoid infinite loops if the bytecode contains
724                 // such.  `10' is arbitrary.
725                 int count = 10;
726                 while (codestart[new_pc] == op_goto && count-- > 0)
727                   new_pc += get2s (&codestart[new_pc + 1]);
728
729                 // If the jump takes us to a `return' instruction and
730                 // the original branch was an unconditional goto, then
731                 // we hoist the return.
732                 opcode = (java_opcode) codestart[new_pc];
733                 if (orig_was_goto
734                     && (opcode == op_ireturn || opcode == op_lreturn
735                         || opcode == op_freturn || opcode == op_dreturn
736                         || opcode == op_areturn || opcode == op_return))
737                   {
738                     --next;
739                     SET_INSN (insn_targets[opcode]);
740                   }
741                 else
742                   SET_DATUM (&insns[pc_mapping[new_pc]]);
743               }
744               break;
745
746             case op_tableswitch:
747               {
748                 while ((pc - codestart) % 4 != 0)
749                   ++pc;
750
751                 jint def = get4 (pc);
752                 SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
753                 pc += 4;
754
755                 int low = get4 (pc);
756                 SET_INT (low);
757                 pc += 4;
758                 int high = get4 (pc);
759                 SET_INT (high);
760                 pc += 4;
761
762                 for (int i = low; i <= high; ++i)
763                   {
764                     SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
765                     pc += 4;
766                   }
767               }
768               break;
769
770             case op_lookupswitch:
771               {
772                 while ((pc - codestart) % 4 != 0)
773                   ++pc;
774
775                 jint def = get4 (pc);
776                 SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
777                 pc += 4;
778
779                 jint npairs = get4 (pc);
780                 pc += 4;
781                 SET_INT (npairs);
782
783                 while (npairs-- > 0)
784                   {
785                     jint match = get4 (pc);
786                     jint offset = get4 (pc + 4);
787                     SET_INT (match);
788                     SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
789                     pc += 8;
790                   }
791               }
792               break;
793
794             case op_invokeinterface:
795               {
796                 jint index = get2u (pc);
797                 pc += 2;
798                 // We ignore the next two bytes.
799                 pc += 2;
800                 SET_INT (index);
801               }
802               break;
803
804             case op_wide:
805               {
806                 opcode = (java_opcode) get1u (pc);
807                 pc += 1;
808                 jint val = get2u (pc);
809                 pc += 2;
810
811                 // We implement narrow and wide instructions using the
812                 // same code in the interpreter.  So we rewrite the
813                 // instruction slot here.
814                 if (! first_pass)
815                   insns[next - 1].insn = (void *) insn_targets[opcode];
816                 SET_INT (val);
817
818                 if (opcode == op_iinc)
819                   {
820                     SET_INT (get2s (pc));
821                     pc += 2;
822                   }
823               }
824               break;
825
826             case op_jsr_w:
827             case op_goto_w:
828               {
829                 jint offset = get4 (pc);
830                 pc += 4;
831                 SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
832               }
833               break;
834
835             // Some "can't happen" cases that we include for
836             // error-checking purposes.
837             case op_putfield_1:
838             case op_putfield_2:
839             case op_putfield_4:
840             case op_putfield_8:
841             case op_putfield_a:
842             case op_putstatic_1:
843             case op_putstatic_2:
844             case op_putstatic_4:
845             case op_putstatic_8:
846             case op_putstatic_a:
847             case op_getfield_1:
848             case op_getfield_2s:
849             case op_getfield_2u:
850             case op_getfield_4:
851             case op_getfield_8:
852             case op_getfield_a:
853             case op_getstatic_1:
854             case op_getstatic_2s:
855             case op_getstatic_2u:
856             case op_getstatic_4:
857             case op_getstatic_8:
858             case op_getstatic_a:
859             case op_breakpoint:
860             default:
861               // Fail somehow.
862               break;
863             }
864         }
865     }
866
867   // Now update exceptions.
868   _Jv_InterpException *exc = exceptions ();
869   for (int i = 0; i < exc_count; ++i)
870     {
871       exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
872       exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
873       exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
874       // FIXME: resolve_pool_entry can throw - we shouldn't be doing this
875       // during compilation.
876       jclass handler
877         = (_Jv_Linker::resolve_pool_entry (defining_class,
878                                              exc[i].handler_type.i)).clazz;
879       exc[i].handler_type.p = handler;
880     }
881
882   // Translate entries in the LineNumberTable from bytecode PC's to direct
883   // threaded interpreter instruction values.
884   for (int i = 0; i < line_table_len; i++)
885     {
886       int byte_pc = line_table[i].bytecode_pc;
887       // It isn't worth throwing an exception if this table is
888       // corrupted, but at the same time we don't want a crash.
889       if (byte_pc < 0 || byte_pc >= code_length)
890         byte_pc = 0;
891       line_table[i].pc = &insns[pc_mapping[byte_pc]];
892     }  
893
894   prepared = insns;
895
896   if (breakpoint_insn == NULL)
897     {
898       bp_insn_slot.insn = const_cast<void *> (insn_targets[op_breakpoint]);
899       breakpoint_insn = &bp_insn_slot;
900     }
901 }
902 #endif /* DIRECT_THREADED */
903
904 /* Run the given method.
905    When args is NULL, don't run anything -- just compile it. */
906 void
907 _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
908 {
909 #undef DEBUG
910 #undef DEBUG_LOCALS_INSN
911 #define DEBUG_LOCALS_INSN(s, t) do {} while(0)
912
913 #include "interpret-run.cc"
914 }
915
916 void
917 _Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
918 {
919 /* Used to keep track of local variable type
920  * 
921  * Possible Types:
922  * o object
923  * i integer
924  * f float
925  * l long 
926  * d double 
927  */
928 #define DEBUG
929 #undef DEBUG_LOCALS_INSN
930 #define DEBUG_LOCALS_INSN(s, t) do {} while(0)
931
932 #include "interpret-run.cc"
933 }
934
935 static void
936 throw_internal_error (const char *msg)
937 {
938   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
939 }
940
941 static void 
942 throw_incompatible_class_change_error (jstring msg)
943 {
944   throw new java::lang::IncompatibleClassChangeError (msg);
945 }
946
947 static void 
948 throw_null_pointer_exception ()
949 {
950   throw new java::lang::NullPointerException;
951 }
952
953 /* Look up source code line number for given bytecode (or direct threaded
954    interpreter) PC. */
955 int
956 _Jv_InterpMethod::get_source_line(pc_t mpc)
957 {
958   int line = line_table_len > 0 ? line_table[0].line : -1;
959   for (int i = 1; i < line_table_len; i++)
960     if (line_table[i].pc > mpc)
961       break;
962     else
963       line = line_table[i].line;
964
965   return line;
966 }
967
968 /** Do static initialization for fields with a constant initializer */
969 void
970 _Jv_InitField (jobject obj, jclass klass, int index)
971 {
972   using namespace java::lang::reflect;
973
974   if (obj != 0 && klass == 0)
975     klass = obj->getClass ();
976
977   if (!_Jv_IsInterpretedClass (klass))
978     return;
979
980   _Jv_InterpClass *iclass = (_Jv_InterpClass*)klass->aux_info;
981
982   _Jv_Field * field = (&klass->fields[0]) + index;
983
984   if (index > klass->field_count)
985     throw_internal_error ("field out of range");
986
987   int init = iclass->field_initializers[index];
988   if (init == 0)
989     return;
990
991   _Jv_Constants *pool = &klass->constants;
992   int tag = pool->tags[init];
993
994   if (! field->isResolved ())
995     throw_internal_error ("initializing unresolved field");
996
997   if (obj==0 && ((field->flags & Modifier::STATIC) == 0))
998     throw_internal_error ("initializing non-static field with no object");
999
1000   void *addr = 0;
1001
1002   if ((field->flags & Modifier::STATIC) != 0)
1003     addr = (void*) field->u.addr;
1004   else
1005     addr = (void*) (((char*)obj) + field->u.boffset);
1006
1007   switch (tag)
1008     {
1009     case JV_CONSTANT_String:
1010       {
1011         jstring str;
1012         str = _Jv_NewStringUtf8Const (pool->data[init].utf8);
1013         pool->data[init].string = str;
1014         pool->tags[init] = JV_CONSTANT_ResolvedString;
1015       }
1016       /* fall through */
1017
1018     case JV_CONSTANT_ResolvedString:
1019       if (! (field->type == &java::lang::String::class$
1020              || field->type == &java::lang::Class::class$))
1021         throw_class_format_error ("string initialiser to non-string field");
1022
1023       *(jstring*)addr = pool->data[init].string;
1024       break;
1025
1026     case JV_CONSTANT_Integer:
1027       {
1028         int value = pool->data[init].i;
1029
1030         if (field->type == JvPrimClass (boolean))
1031           *(jboolean*)addr = (jboolean)value;
1032         
1033         else if (field->type == JvPrimClass (byte))
1034           *(jbyte*)addr = (jbyte)value;
1035         
1036         else if (field->type == JvPrimClass (char))
1037           *(jchar*)addr = (jchar)value;
1038
1039         else if (field->type == JvPrimClass (short))
1040           *(jshort*)addr = (jshort)value;
1041         
1042         else if (field->type == JvPrimClass (int))
1043           *(jint*)addr = (jint)value;
1044
1045         else
1046           throw_class_format_error ("erroneous field initializer");
1047       }  
1048       break;
1049
1050     case JV_CONSTANT_Long:
1051       if (field->type != JvPrimClass (long))
1052         throw_class_format_error ("erroneous field initializer");
1053
1054       *(jlong*)addr = _Jv_loadLong (&pool->data[init]);
1055       break;
1056
1057     case JV_CONSTANT_Float:
1058       if (field->type != JvPrimClass (float))
1059         throw_class_format_error ("erroneous field initializer");
1060
1061       *(jfloat*)addr = pool->data[init].f;
1062       break;
1063
1064     case JV_CONSTANT_Double:
1065       if (field->type != JvPrimClass (double))
1066         throw_class_format_error ("erroneous field initializer");
1067
1068       *(jdouble*)addr = _Jv_loadDouble (&pool->data[init]);
1069       break;
1070
1071     default:
1072       throw_class_format_error ("erroneous field initializer");
1073     }
1074 }
1075
1076 inline static unsigned char*
1077 skip_one_type (unsigned char* ptr)
1078 {
1079   int ch = *ptr++;
1080
1081   while (ch == '[')
1082     { 
1083       ch = *ptr++;
1084     }
1085   
1086   if (ch == 'L')
1087     {
1088       do { ch = *ptr++; } while (ch != ';');
1089     }
1090
1091   return ptr;
1092 }
1093
1094 static ffi_type*
1095 get_ffi_type_from_signature (unsigned char* ptr)
1096 {
1097   switch (*ptr) 
1098     {
1099     case 'L':
1100     case '[':
1101       return &ffi_type_pointer;
1102       break;
1103
1104     case 'Z':
1105       // On some platforms a bool is a byte, on others an int.
1106       if (sizeof (jboolean) == sizeof (jbyte))
1107         return &ffi_type_sint8;
1108       else
1109         {
1110           JvAssert (sizeof (jbyte) == sizeof (jint));
1111           return &ffi_type_sint32;
1112         }
1113       break;
1114
1115     case 'B':
1116       return &ffi_type_sint8;
1117       break;
1118       
1119     case 'C':
1120       return &ffi_type_uint16;
1121       break;
1122           
1123     case 'S': 
1124       return &ffi_type_sint16;
1125       break;
1126           
1127     case 'I':
1128       return &ffi_type_sint32;
1129       break;
1130           
1131     case 'J':
1132       return &ffi_type_sint64;
1133       break;
1134           
1135     case 'F':
1136       return &ffi_type_float;
1137       break;
1138           
1139     case 'D':
1140       return &ffi_type_double;
1141       break;
1142
1143     case 'V':
1144       return &ffi_type_void;
1145       break;
1146     }
1147
1148   throw_internal_error ("unknown type in signature");
1149 }
1150
1151 /* this function yields the number of actual arguments, that is, if the
1152  * function is non-static, then one is added to the number of elements
1153  * found in the signature */
1154
1155 int 
1156 _Jv_count_arguments (_Jv_Utf8Const *signature,
1157                      jboolean staticp)
1158 {
1159   unsigned char *ptr = (unsigned char*) signature->chars();
1160   int arg_count = staticp ? 0 : 1;
1161
1162   /* first, count number of arguments */
1163
1164   // skip '('
1165   ptr++;
1166
1167   // count args
1168   while (*ptr != ')')
1169     {
1170       ptr = skip_one_type (ptr);
1171       arg_count += 1;
1172     }
1173
1174   return arg_count;
1175 }
1176
1177 /* This beast will build a cif, given the signature.  Memory for
1178  * the cif itself and for the argument types must be allocated by the
1179  * caller.
1180  */
1181
1182 static int 
1183 init_cif (_Jv_Utf8Const* signature,
1184           int arg_count,
1185           jboolean staticp,
1186           ffi_cif *cif,
1187           ffi_type **arg_types,
1188           ffi_type **rtype_p)
1189 {
1190   unsigned char *ptr = (unsigned char*) signature->chars();
1191
1192   int arg_index = 0;            // arg number
1193   int item_count = 0;           // stack-item count
1194
1195   // setup receiver
1196   if (!staticp)
1197     {
1198       arg_types[arg_index++] = &ffi_type_pointer;
1199       item_count += 1;
1200     }
1201
1202   // skip '('
1203   ptr++;
1204
1205   // assign arg types
1206   while (*ptr != ')')
1207     {
1208       arg_types[arg_index++] = get_ffi_type_from_signature (ptr);
1209
1210       if (*ptr == 'J' || *ptr == 'D')
1211         item_count += 2;
1212       else
1213         item_count += 1;
1214
1215       ptr = skip_one_type (ptr);
1216     }
1217
1218   // skip ')'
1219   ptr++;
1220   ffi_type *rtype = get_ffi_type_from_signature (ptr);
1221
1222   ptr = skip_one_type (ptr);
1223   if (ptr != (unsigned char*)signature->chars() + signature->len())
1224     throw_internal_error ("did not find end of signature");
1225
1226   if (ffi_prep_cif (cif, FFI_DEFAULT_ABI,
1227                     arg_count, rtype, arg_types) != FFI_OK)
1228     throw_internal_error ("ffi_prep_cif failed");
1229
1230   if (rtype_p != NULL)
1231     *rtype_p = rtype;
1232
1233   return item_count;
1234 }
1235
1236 #if FFI_NATIVE_RAW_API
1237 #   define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure
1238 #   define FFI_RAW_SIZE ffi_raw_size
1239 #else
1240 #   define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure
1241 #   define FFI_RAW_SIZE ffi_java_raw_size
1242 #endif
1243
1244 /* we put this one here, and not in interpret.cc because it
1245  * calls the utility routines _Jv_count_arguments 
1246  * which are static to this module.  The following struct defines the
1247  * layout we use for the stubs, it's only used in the ncode method. */
1248
1249 typedef struct {
1250   ffi_raw_closure  closure;
1251   ffi_cif   cif;
1252   ffi_type *arg_types[0];
1253 } ncode_closure;
1254
1255 typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*);
1256
1257 void *
1258 _Jv_InterpMethod::ncode ()
1259 {
1260   using namespace java::lang::reflect;
1261
1262   if (self->ncode != 0)
1263     return self->ncode;
1264
1265   jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
1266   int arg_count = _Jv_count_arguments (self->signature, staticp);
1267
1268   ncode_closure *closure =
1269     (ncode_closure*)_Jv_AllocBytes (sizeof (ncode_closure)
1270                                         + arg_count * sizeof (ffi_type*));
1271
1272   init_cif (self->signature,
1273             arg_count,
1274             staticp,
1275             &closure->cif,
1276             &closure->arg_types[0],
1277             NULL);
1278
1279   ffi_closure_fun fun;
1280
1281   args_raw_size = FFI_RAW_SIZE (&closure->cif);
1282
1283   JvAssert ((self->accflags & Modifier::NATIVE) == 0);
1284
1285   if ((self->accflags & Modifier::SYNCHRONIZED) != 0)
1286     {
1287       if (staticp)
1288         {
1289         if (::gnu::classpath::jdwp::Jdwp::isDebugging)
1290                   fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class_debug;
1291                 else
1292                   fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
1293         }
1294       else
1295         {
1296               if (::gnu::classpath::jdwp::Jdwp::isDebugging)
1297                     fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object_debug;
1298                   else
1299                         fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
1300         } 
1301     }
1302   else
1303     {
1304       if (staticp)
1305         {
1306               if (::gnu::classpath::jdwp::Jdwp::isDebugging)
1307                     fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class_debug;
1308                   else
1309                     fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class;
1310         }
1311       else
1312         {
1313               if (::gnu::classpath::jdwp::Jdwp::isDebugging)
1314                     fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal_debug;
1315                   else
1316                     fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
1317         }
1318     }
1319
1320   FFI_PREP_RAW_CLOSURE (&closure->closure,
1321                         &closure->cif, 
1322                         fun,
1323                         (void*)this);
1324
1325   self->ncode = (void*)closure;
1326   return self->ncode;
1327 }
1328
1329 /* Find the index of the given insn in the array of insn slots
1330    for this method. Returns -1 if not found. */
1331 jlong
1332 _Jv_InterpMethod::insn_index (pc_t pc)
1333 {
1334   jlong left = 0;
1335 #ifdef DIRECT_THREADED
1336   jlong right = number_insn_slots;
1337   pc_t insns = prepared;
1338 #else
1339   jlong right = code_length;
1340   pc_t insns = bytecode ();
1341 #endif
1342
1343   while (right >= 0)
1344     {
1345       jlong mid = (left + right) / 2;
1346       if (&insns[mid] == pc)
1347         return mid;
1348
1349       if (pc < &insns[mid])
1350         right = mid - 1;
1351       else
1352         left = mid + 1;
1353     }
1354
1355   return -1;
1356 }
1357
1358 void
1359 _Jv_InterpMethod::get_line_table (jlong& start, jlong& end,
1360                                   jintArray& line_numbers,
1361                                   jlongArray& code_indices)
1362 {
1363 #ifdef DIRECT_THREADED
1364   /* For the DIRECT_THREADED case, if the method has not yet been
1365    * compiled, the linetable will change to insn slots instead of
1366    * bytecode PCs. It is probably easiest, in this case, to simply
1367    * compile the method and guarantee that we are using insn
1368    * slots.
1369    */
1370   _Jv_CompileMethod (this);
1371
1372   if (line_table_len > 0)
1373     {
1374       start = 0;
1375       end = number_insn_slots;
1376       line_numbers = JvNewIntArray (line_table_len);
1377       code_indices = JvNewLongArray (line_table_len);
1378
1379       jint* lines = elements (line_numbers);
1380       jlong* indices = elements (code_indices);
1381       for (int i = 0; i < line_table_len; ++i)
1382         {
1383           lines[i] = line_table[i].line;
1384           indices[i] = insn_index (line_table[i].pc);
1385         }
1386     }
1387 #else // !DIRECT_THREADED
1388   if (line_table_len > 0)
1389     {
1390       start = 0;
1391       end = code_length;
1392       line_numbers = JvNewIntArray (line_table_len);
1393       code_indices = JvNewLongArray (line_table_len);
1394
1395       jint* lines = elements (line_numbers);
1396       jlong* indices = elements (code_indices);
1397       for (int i = 0; i < line_table_len; ++i)
1398         {
1399           lines[i] = line_table[i].line;
1400           indices[i] = (jlong) line_table[i].bytecode_pc;
1401         }
1402     }
1403 #endif // !DIRECT_THREADED
1404 }
1405
1406 pc_t
1407 _Jv_InterpMethod::install_break (jlong index)
1408 {
1409   return set_insn (index, breakpoint_insn);
1410 }
1411
1412 pc_t
1413 _Jv_InterpMethod::get_insn (jlong index)
1414 {
1415   pc_t code;
1416
1417 #ifdef DIRECT_THREADED
1418   if (index >= number_insn_slots || index < 0)
1419     return NULL;
1420
1421   code = prepared;
1422 #else // !DIRECT_THREADED
1423   if (index >= code_length || index < 0)
1424     return NULL;
1425
1426   code = reinterpret_cast<pc_t> (bytecode ());
1427 #endif // !DIRECT_THREADED
1428
1429   return &code[index];
1430 }
1431
1432 pc_t
1433 _Jv_InterpMethod::set_insn (jlong index, pc_t insn)
1434 {
1435 #ifdef DIRECT_THREADED
1436   if (index >= number_insn_slots || index < 0)
1437     return NULL;
1438
1439   pc_t code = prepared;
1440   code[index].insn = insn->insn;
1441 #else // !DIRECT_THREADED
1442   if (index >= code_length || index < 0)
1443     return NULL;
1444
1445   pc_t code = reinterpret_cast<pc_t> (bytecode ());
1446   code[index] = *insn;
1447 #endif // !DIRECT_THREADED
1448
1449   return &code[index];
1450 }
1451
1452 void *
1453 _Jv_JNIMethod::ncode ()
1454 {
1455   using namespace java::lang::reflect;
1456
1457   if (self->ncode != 0)
1458     return self->ncode;
1459
1460   jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
1461   int arg_count = _Jv_count_arguments (self->signature, staticp);
1462
1463   ncode_closure *closure =
1464     (ncode_closure*)_Jv_AllocBytes (sizeof (ncode_closure)
1465                                     + arg_count * sizeof (ffi_type*));
1466
1467   ffi_type *rtype;
1468   init_cif (self->signature,
1469             arg_count,
1470             staticp,
1471             &closure->cif,
1472             &closure->arg_types[0],
1473             &rtype);
1474
1475   ffi_closure_fun fun;
1476
1477   args_raw_size = FFI_RAW_SIZE (&closure->cif);
1478
1479   // Initialize the argument types and CIF that represent the actual
1480   // underlying JNI function.
1481   int extra_args = 1;
1482   if ((self->accflags & Modifier::STATIC))
1483     ++extra_args;
1484   jni_arg_types = (ffi_type **) _Jv_AllocBytes ((extra_args + arg_count)
1485                                                 * sizeof (ffi_type *));
1486   int offset = 0;
1487   jni_arg_types[offset++] = &ffi_type_pointer;
1488   if ((self->accflags & Modifier::STATIC))
1489     jni_arg_types[offset++] = &ffi_type_pointer;
1490   memcpy (&jni_arg_types[offset], &closure->arg_types[0],
1491           arg_count * sizeof (ffi_type *));
1492
1493   if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
1494                     extra_args + arg_count, rtype,
1495                     jni_arg_types) != FFI_OK)
1496     throw_internal_error ("ffi_prep_cif failed for JNI function");
1497
1498   JvAssert ((self->accflags & Modifier::NATIVE) != 0);
1499
1500   // FIXME: for now we assume that all native methods for
1501   // interpreted code use JNI.
1502   fun = (ffi_closure_fun) &_Jv_JNIMethod::call;
1503
1504   FFI_PREP_RAW_CLOSURE (&closure->closure,
1505                         &closure->cif, 
1506                         fun,
1507                         (void*) this);
1508
1509   self->ncode = (void *) closure;
1510   return self->ncode;
1511 }
1512
1513 static void
1514 throw_class_format_error (jstring msg)
1515 {
1516   throw (msg
1517          ? new java::lang::ClassFormatError (msg)
1518          : new java::lang::ClassFormatError);
1519 }
1520
1521 static void
1522 throw_class_format_error (const char *msg)
1523 {
1524   throw_class_format_error (JvNewStringLatin1 (msg));
1525 }
1526
1527 \f
1528
1529 void
1530 _Jv_InterpreterEngine::do_verify (jclass klass)
1531 {
1532   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1533   for (int i = 0; i < klass->method_count; i++)
1534     {
1535       using namespace java::lang::reflect;
1536       _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
1537       _Jv_ushort accflags = klass->methods[i].accflags;
1538       if ((accflags & (Modifier::NATIVE | Modifier::ABSTRACT)) == 0)
1539         {
1540           _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
1541           _Jv_VerifyMethod (im);
1542         }
1543     }
1544 }
1545
1546 void
1547 _Jv_InterpreterEngine::do_create_ncode (jclass klass)
1548 {
1549   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1550   for (int i = 0; i < klass->method_count; i++)
1551     {
1552       // Just skip abstract methods.  This is particularly important
1553       // because we don't resize the interpreted_methods array when
1554       // miranda methods are added to it.
1555       if ((klass->methods[i].accflags
1556            & java::lang::reflect::Modifier::ABSTRACT)
1557           != 0)
1558         continue;
1559
1560       _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
1561
1562       if ((klass->methods[i].accflags & java::lang::reflect::Modifier::NATIVE)
1563           != 0)
1564         {
1565           // You might think we could use a virtual `ncode' method in
1566           // the _Jv_MethodBase and unify the native and non-native
1567           // cases.  Well, we can't, because we don't allocate these
1568           // objects using `new', and thus they don't get a vtable.
1569           _Jv_JNIMethod *jnim = reinterpret_cast<_Jv_JNIMethod *> (imeth);
1570           klass->methods[i].ncode = jnim->ncode ();
1571         }
1572       else if (imeth != 0)              // it could be abstract
1573         {
1574           _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
1575           klass->methods[i].ncode = im->ncode ();
1576         }
1577     }
1578 }
1579
1580 void
1581 _Jv_InterpreterEngine::do_allocate_static_fields (jclass klass,
1582                                                   int pointer_size,
1583                                                   int other_size)
1584 {
1585   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1586
1587   // Splitting the allocations here lets us scan reference fields and
1588   // avoid scanning non-reference fields.  How reference fields are
1589   // scanned is a bit tricky: we allocate using _Jv_AllocRawObj, which
1590   // means that this memory will be scanned conservatively (same
1591   // difference, since we know all the contents here are pointers).
1592   // Then we put pointers into this memory into the 'fields'
1593   // structure.  Most of these are interior pointers, which is ok (but
1594   // even so the pointer to the first reference field will be used and
1595   // that is not an interior pointer).  The 'fields' array is also
1596   // allocated with _Jv_AllocRawObj (see defineclass.cc), so it will
1597   // be scanned.  A pointer to this array is held by Class and thus
1598   // seen by the collector.
1599   char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
1600   char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);
1601
1602   for (int i = 0; i < klass->field_count; i++)
1603     {
1604       _Jv_Field *field = &klass->fields[i];
1605
1606       if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
1607         continue;
1608
1609       char *base = field->isRef() ? reference_fields : non_reference_fields;
1610       field->u.addr  = base + field->u.boffset;
1611
1612       if (iclass->field_initializers[i] != 0)
1613         {
1614           _Jv_Linker::resolve_field (field, klass->loader);
1615           _Jv_InitField (0, klass, i);
1616         }
1617     }
1618
1619   // Now we don't need the field_initializers anymore, so let the
1620   // collector get rid of it.
1621   iclass->field_initializers = 0;
1622 }
1623
1624 _Jv_ResolvedMethod *
1625 _Jv_InterpreterEngine::do_resolve_method (_Jv_Method *method, jclass klass,
1626                                           jboolean staticp)
1627 {
1628   int arg_count = _Jv_count_arguments (method->signature, staticp);
1629
1630   _Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
1631     _Jv_AllocBytes (sizeof (_Jv_ResolvedMethod)
1632                     + arg_count*sizeof (ffi_type*));
1633
1634   result->stack_item_count
1635     = init_cif (method->signature,
1636                 arg_count,
1637                 staticp,
1638                 &result->cif,
1639                 &result->arg_types[0],
1640                 NULL);
1641
1642   result->method              = method;
1643   result->klass               = klass;
1644
1645   return result;
1646 }
1647
1648 void
1649 _Jv_InterpreterEngine::do_post_miranda_hook (jclass klass)
1650 {
1651   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1652   for (int i = 0; i < klass->method_count; i++)
1653     {
1654       // Just skip abstract methods.  This is particularly important
1655       // because we don't resize the interpreted_methods array when
1656       // miranda methods are added to it.
1657       if ((klass->methods[i].accflags
1658            & java::lang::reflect::Modifier::ABSTRACT)
1659           != 0)
1660         continue;
1661       // Miranda method additions mean that the `methods' array moves.
1662       // We cache a pointer into this array, so we have to update.
1663       iclass->interpreted_methods[i]->self = &klass->methods[i];
1664     }
1665 }
1666
1667 #ifdef DIRECT_THREADED
1668 void
1669 _Jv_CompileMethod (_Jv_InterpMethod* method)
1670 {
1671   if (method->prepared == NULL)
1672     _Jv_InterpMethod::run (NULL, NULL, method);
1673 }
1674 #endif // DIRECT_THREADED
1675
1676 #endif // INTERPRETER