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