X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=libjava%2Finterpret.cc;fp=libjava%2Finterpret.cc;h=0000000000000000000000000000000000000000;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=198ec45eb16711fd513e4e4df7e92b59fd151ec3;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libjava/interpret.cc b/libjava/interpret.cc deleted file mode 100644 index 198ec45e..00000000 --- a/libjava/interpret.cc +++ /dev/null @@ -1,2412 +0,0 @@ -// interpret.cc - Code for the interpreter - -/* Copyright (C) 1999, 2000, 2001 , 2002 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -/* Author: Kresten Krab Thorup */ - -#include - -#pragma implementation "java-interp.h" - -#include -#include -#include -// #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef INTERPRETER - -#include - -using namespace gcj; - -static void throw_internal_error (char *msg) - __attribute__ ((__noreturn__)); -static void throw_incompatible_class_change_error (jstring msg) - __attribute__ ((__noreturn__)); -#ifndef HANDLE_SEGV -static void throw_null_pointer_exception () - __attribute__ ((__noreturn__)); -#endif - -extern "C" double __ieee754_fmod (double,double); - -static inline void dupx (_Jv_word *sp, int n, int x) -{ - // first "slide" n+x elements n to the right - int top = n-1; - for (int i = 0; i < n+x; i++) - { - sp[(top-i)] = sp[(top-i)-n]; - } - - // next, copy the n top elements, n+x down - for (int i = 0; i < n; i++) - { - sp[top-(n+x)-i] = sp[top-i]; - } - -}; - -// Used to convert from floating types to integral types. -template -static inline TO -convert (FROM val, TO min, TO max) -{ - TO ret; - if (val >= (FROM) max) - ret = max; - else if (val <= (FROM) min) - ret = min; - else if (val != val) - ret = 0; - else - ret = (TO) val; - return ret; -} - -#define PUSHA(V) (sp++)->o = (V) -#define PUSHI(V) (sp++)->i = (V) -#define PUSHF(V) (sp++)->f = (V) -#if SIZEOF_VOID_P == 8 -# define PUSHL(V) (sp->l = (V), sp += 2) -# define PUSHD(V) (sp->d = (V), sp += 2) -#else -# define PUSHL(V) do { _Jv_word2 w2; w2.l=(V); \ - (sp++)->ia[0] = w2.ia[0]; \ - (sp++)->ia[0] = w2.ia[1]; } while (0) -# define PUSHD(V) do { _Jv_word2 w2; w2.d=(V); \ - (sp++)->ia[0] = w2.ia[0]; \ - (sp++)->ia[0] = w2.ia[1]; } while (0) -#endif - -#define POPA() ((--sp)->o) -#define POPI() ((jint) (--sp)->i) // cast since it may be promoted -#define POPF() ((jfloat) (--sp)->f) -#if SIZEOF_VOID_P == 8 -# define POPL() (sp -= 2, (jlong) sp->l) -# define POPD() (sp -= 2, (jdouble) sp->d) -#else -# define POPL() ({ _Jv_word2 w2; \ - w2.ia[1] = (--sp)->ia[0]; \ - w2.ia[0] = (--sp)->ia[0]; w2.l; }) -# define POPD() ({ _Jv_word2 w2; \ - w2.ia[1] = (--sp)->ia[0]; \ - w2.ia[0] = (--sp)->ia[0]; w2.d; }) -#endif - -#define LOADA(I) (sp++)->o = locals[I].o -#define LOADI(I) (sp++)->i = locals[I].i -#define LOADF(I) (sp++)->f = locals[I].f -#if SIZEOF_VOID_P == 8 -# define LOADL(I) (sp->l = locals[I].l, sp += 2) -# define LOADD(I) (sp->d = locals[I].d, sp += 2) -#else -# define LOADL(I) do { jint __idx = (I); \ - (sp++)->ia[0] = locals[__idx].ia[0]; \ - (sp++)->ia[0] = locals[__idx+1].ia[0]; \ - } while (0) -# define LOADD(I) LOADL(I) -#endif - -#define STOREA(I) locals[I].o = (--sp)->o -#define STOREI(I) locals[I].i = (--sp)->i -#define STOREF(I) locals[I].f = (--sp)->f -#if SIZEOF_VOID_P == 8 -# define STOREL(I) (sp -= 2, locals[I].l = sp->l) -# define STORED(I) (sp -= 2, locals[I].d = sp->d) -#else -# define STOREL(I) do { jint __idx = (I); \ - locals[__idx+1].ia[0] = (--sp)->ia[0]; \ - locals[__idx].ia[0] = (--sp)->ia[0]; \ - } while (0) -# define STORED(I) STOREL(I) -#endif - -#define PEEKI(I) (locals+(I))->i -#define PEEKA(I) (locals+(I))->o - -#define POKEI(I,V) ((locals+(I))->i = (V)) - - -#define BINOPI(OP) { \ - jint value2 = POPI(); \ - jint value1 = POPI(); \ - PUSHI(value1 OP value2); \ -} - -#define BINOPF(OP) { \ - jfloat value2 = POPF(); \ - jfloat value1 = POPF(); \ - PUSHF(value1 OP value2); \ -} - -#define BINOPL(OP) { \ - jlong value2 = POPL(); \ - jlong value1 = POPL(); \ - PUSHL(value1 OP value2); \ -} - -#define BINOPD(OP) { \ - jdouble value2 = POPD(); \ - jdouble value1 = POPD(); \ - PUSHD(value1 OP value2); \ -} - -static inline jint get1s(unsigned char* loc) { - return *(signed char*)loc; -} - -static inline jint get1u(unsigned char* loc) { - return *loc; -} - -static inline jint get2s(unsigned char* loc) { - return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1)); -} - -static inline jint get2u(unsigned char* loc) { - return (((jint)(*loc)) << 8) | ((jint)*(loc+1)); -} - -static jint get4(unsigned char* loc) { - return (((jint)(loc[0])) << 24) - | (((jint)(loc[1])) << 16) - | (((jint)(loc[2])) << 8) - | (((jint)(loc[3])) << 0); -} - - -#ifdef HANDLE_SEGV -#define NULLCHECK(X) -#define NULLARRAYCHECK(X) do { SAVE_PC; } while (0) -#else -#define NULLCHECK(X) \ - do { if ((X)==NULL) throw_null_pointer_exception (); } while (0) -#define NULLARRAYCHECK(X) \ - do { if ((X)==NULL) { SAVE_PC; throw_null_pointer_exception (); } } while (0) -#endif - -#define ARRAYBOUNDSCHECK(array, index) \ - do \ - { \ - if (((unsigned) index) >= (unsigned) (array->length)) \ - _Jv_ThrowBadArrayIndex (index); \ - } \ - while (0) - -// this method starts the actual running of the method. It is inlined -// in three different variants in the static methods run_normal, -// run_sync_object and run_sync_class (see below). Those static methods -// are installed directly in the stub for this method (by -// _Jv_InterpMethod::ncode, in resolve.cc). - -inline jobject -_Jv_InterpMethod::run (ffi_cif* cif, - void *retp, - ffi_raw *args, - _Jv_InterpMethodInvocation *inv) -{ - inv->running = this; - inv->pc = bytecode (); - inv->sp = inv->stack_base (); - _Jv_word *locals = inv->local_base (); - - /* Go straight at it! the ffi raw format matches the internal - stack representation exactly. At least, that's the idea. - */ - memcpy ((void*) locals, (void*) args, args_raw_size); - - next_segment: - - jobject ex = NULL; - - try - { - continue1 (inv); - } - catch (java::lang::Throwable *ex2) - { - ex = ex2; - } - - if (ex == 0) // no exception... - { - /* define sp locally, so the POP? macros will pick it up */ - _Jv_word *sp = inv->sp; - int rtype = cif->rtype->type; - - if (rtype == FFI_TYPE_POINTER) - { - jobject r = POPA(); - *(jobject*) retp = r; - return 0; - } - else if (rtype == FFI_TYPE_SINT32) - { - jint r = POPI(); - *(jint*)retp = r; - return 0; - } - else if (rtype == FFI_TYPE_VOID) - { - return 0; - } - else switch (rtype) - { - case FFI_TYPE_FLOAT: - { - jfloat r = POPF(); - *(jfloat*)retp = r; - return 0; - } - - case FFI_TYPE_DOUBLE: - { - jdouble r = POPD(); - *(jdouble*)retp = r; - return 0; - } - - case FFI_TYPE_UINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT8: - case FFI_TYPE_SINT16: - { - jint r = POPI(); - *(jint*)retp = r; - return 0; - } - - case FFI_TYPE_SINT64: - { - jlong r = POPL(); - *(jlong*)retp = r; - return 0; - } - - default: - throw_internal_error ("unknown return type"); - } - } - - /** handle an exception */ - if ( find_exception (ex, inv) ) - goto next_segment; - - return ex; -} - -#define SAVE_PC inv->pc = pc - -bool _Jv_InterpMethod::find_exception (jobject ex, - _Jv_InterpMethodInvocation *inv) -{ - // We subtract one because the PC was incremented before it was - // saved. - int logical_pc = inv->pc - 1 - bytecode (); - _Jv_InterpException *exc = exceptions (); - jclass exc_class = ex->getClass (); - - for (int i = 0; i < exc_count; i++) - { - if (exc[i].start_pc <= logical_pc && logical_pc < exc[i].end_pc) - { - jclass handler; - - if (exc[i].handler_type != 0) - handler = (_Jv_ResolvePoolEntry (defining_class, - exc[i].handler_type)).clazz; - else - handler = NULL; - - if (handler==NULL || handler->isAssignableFrom (exc_class)) - { - inv->pc = bytecode () + exc[i].handler_pc; - inv->sp = inv->stack_base (); // reset stack - (inv->sp++)->o = ex; // push exception - return true; - } - } - } - return false; -} - -void _Jv_InterpMethod::run_normal (ffi_cif* cif, - void* ret, - ffi_raw * args, - void* __this) -{ - _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this; - - // we do the alloca of the method invocation here, to allow the method - // "run" ro be inlined. Otherwise gcc will ignore the inline directive. - int storage_size = _this->max_stack+_this->max_locals; - _Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*) - __builtin_alloca (sizeof (_Jv_InterpMethodInvocation) - + storage_size * sizeof (_Jv_word)); - - jobject ex = _this->run (cif, ret, args, inv); - if (ex != 0) throw static_cast(ex); -} - -void _Jv_InterpMethod::run_synch_object (ffi_cif* cif, - void* ret, - ffi_raw * args, - void* __this) -{ - _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this; - jobject rcv = (jobject)args[0].ptr; - - int storage_size = _this->max_stack+_this->max_locals; - _Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*) - __builtin_alloca (sizeof (_Jv_InterpMethodInvocation) - + storage_size * sizeof (_Jv_word)); - - _Jv_MonitorEnter (rcv); - jobject ex = _this->run (cif, ret, args, inv); - _Jv_MonitorExit (rcv); - - if (ex != 0) throw static_cast(ex); -} - -void _Jv_InterpMethod::run_synch_class (ffi_cif* cif, - void* ret, - ffi_raw * args, - void* __this) -{ - _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this; - jclass sync = _this->defining_class; - - int storage_size = _this->max_stack+_this->max_locals; - _Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*) - __builtin_alloca (sizeof (_Jv_InterpMethodInvocation) - + storage_size * sizeof (_Jv_word)); - - _Jv_MonitorEnter (sync); - jobject ex = _this->run (cif, ret, args, inv); - _Jv_MonitorExit (sync); - - if (ex != 0) throw static_cast(ex); -} - -/* - This proceeds execution, as designated in "inv". If an exception - happens, then it is simply thrown, and handled in Java. Thus, the pc - needs to be stored in the inv->pc at all times, so we can figure - out which handler (if any) to invoke. - - One design issue, which I have not completely considered, is if it - should be possible to have interpreted classes linked in! Seldom used - (or non-critical) classes could reasonably be interpreted. -*/ - - -void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) -{ - using namespace java::lang::reflect; - - _Jv_word *sp = inv->sp; - unsigned char *pc = inv->pc; - _Jv_word *locals = inv->local_base (); - - _Jv_word *pool_data = defining_class->constants.data; - - /* these two are used in the invokeXXX instructions */ - void (*fun)(); - _Jv_ResolvedMethod* rmeth; - -#define INSN_LABEL(op) &&insn_##op -#define GOTO_INSN(op) goto *(insn_target[op]) - - static const void *const insn_target[] = - { - INSN_LABEL(nop), - INSN_LABEL(aconst_null), - INSN_LABEL(iconst_m1), - INSN_LABEL(iconst_0), - INSN_LABEL(iconst_1), - INSN_LABEL(iconst_2), - INSN_LABEL(iconst_3), - INSN_LABEL(iconst_4), - INSN_LABEL(iconst_5), - INSN_LABEL(lconst_0), - INSN_LABEL(lconst_1), - INSN_LABEL(fconst_0), - INSN_LABEL(fconst_1), - INSN_LABEL(fconst_2), - INSN_LABEL(dconst_0), - INSN_LABEL(dconst_1), - INSN_LABEL(bipush), - INSN_LABEL(sipush), - INSN_LABEL(ldc), - INSN_LABEL(ldc_w), - INSN_LABEL(ldc2_w), - INSN_LABEL(iload), - INSN_LABEL(lload), - INSN_LABEL(fload), - INSN_LABEL(dload), - INSN_LABEL(aload), - INSN_LABEL(iload_0), - INSN_LABEL(iload_1), - INSN_LABEL(iload_2), - INSN_LABEL(iload_3), - INSN_LABEL(lload_0), - INSN_LABEL(lload_1), - INSN_LABEL(lload_2), - INSN_LABEL(lload_3), - INSN_LABEL(fload_0), - INSN_LABEL(fload_1), - INSN_LABEL(fload_2), - INSN_LABEL(fload_3), - INSN_LABEL(dload_0), - INSN_LABEL(dload_1), - INSN_LABEL(dload_2), - INSN_LABEL(dload_3), - INSN_LABEL(aload_0), - INSN_LABEL(aload_1), - INSN_LABEL(aload_2), - INSN_LABEL(aload_3), - INSN_LABEL(iaload), - INSN_LABEL(laload), - INSN_LABEL(faload), - INSN_LABEL(daload), - INSN_LABEL(aaload), - INSN_LABEL(baload), - INSN_LABEL(caload), - INSN_LABEL(saload), - INSN_LABEL(istore), - INSN_LABEL(lstore), - INSN_LABEL(fstore), - INSN_LABEL(dstore), - INSN_LABEL(astore), - INSN_LABEL(istore_0), - INSN_LABEL(istore_1), - INSN_LABEL(istore_2), - INSN_LABEL(istore_3), - INSN_LABEL(lstore_0), - INSN_LABEL(lstore_1), - INSN_LABEL(lstore_2), - INSN_LABEL(lstore_3), - INSN_LABEL(fstore_0), - INSN_LABEL(fstore_1), - INSN_LABEL(fstore_2), - INSN_LABEL(fstore_3), - INSN_LABEL(dstore_0), - INSN_LABEL(dstore_1), - INSN_LABEL(dstore_2), - INSN_LABEL(dstore_3), - INSN_LABEL(astore_0), - INSN_LABEL(astore_1), - INSN_LABEL(astore_2), - INSN_LABEL(astore_3), - INSN_LABEL(iastore), - INSN_LABEL(lastore), - INSN_LABEL(fastore), - INSN_LABEL(dastore), - INSN_LABEL(aastore), - INSN_LABEL(bastore), - INSN_LABEL(castore), - INSN_LABEL(sastore), - INSN_LABEL(pop), - INSN_LABEL(pop2), - INSN_LABEL(dup), - INSN_LABEL(dup_x1), - INSN_LABEL(dup_x2), - INSN_LABEL(dup2), - INSN_LABEL(dup2_x1), - INSN_LABEL(dup2_x2), - INSN_LABEL(swap), - INSN_LABEL(iadd), - INSN_LABEL(ladd), - INSN_LABEL(fadd), - INSN_LABEL(dadd), - INSN_LABEL(isub), - INSN_LABEL(lsub), - INSN_LABEL(fsub), - INSN_LABEL(dsub), - INSN_LABEL(imul), - INSN_LABEL(lmul), - INSN_LABEL(fmul), - INSN_LABEL(dmul), - INSN_LABEL(idiv), - INSN_LABEL(ldiv), - INSN_LABEL(fdiv), - INSN_LABEL(ddiv), - INSN_LABEL(irem), - INSN_LABEL(lrem), - INSN_LABEL(frem), - INSN_LABEL(drem), - INSN_LABEL(ineg), - INSN_LABEL(lneg), - INSN_LABEL(fneg), - INSN_LABEL(dneg), - INSN_LABEL(ishl), - INSN_LABEL(lshl), - INSN_LABEL(ishr), - INSN_LABEL(lshr), - INSN_LABEL(iushr), - INSN_LABEL(lushr), - INSN_LABEL(iand), - INSN_LABEL(land), - INSN_LABEL(ior), - INSN_LABEL(lor), - INSN_LABEL(ixor), - INSN_LABEL(lxor), - INSN_LABEL(iinc), - INSN_LABEL(i2l), - INSN_LABEL(i2f), - INSN_LABEL(i2d), - INSN_LABEL(l2i), - INSN_LABEL(l2f), - INSN_LABEL(l2d), - INSN_LABEL(f2i), - INSN_LABEL(f2l), - INSN_LABEL(f2d), - INSN_LABEL(d2i), - INSN_LABEL(d2l), - INSN_LABEL(d2f), - INSN_LABEL(i2b), - INSN_LABEL(i2c), - INSN_LABEL(i2s), - INSN_LABEL(lcmp), - INSN_LABEL(fcmpl), - INSN_LABEL(fcmpg), - INSN_LABEL(dcmpl), - INSN_LABEL(dcmpg), - INSN_LABEL(ifeq), - INSN_LABEL(ifne), - INSN_LABEL(iflt), - INSN_LABEL(ifge), - INSN_LABEL(ifgt), - INSN_LABEL(ifle), - INSN_LABEL(if_icmpeq), - INSN_LABEL(if_icmpne), - INSN_LABEL(if_icmplt), - INSN_LABEL(if_icmpge), - INSN_LABEL(if_icmpgt), - INSN_LABEL(if_icmple), - INSN_LABEL(if_acmpeq), - INSN_LABEL(if_acmpne), - INSN_LABEL(goto), - INSN_LABEL(jsr), - INSN_LABEL(ret), - INSN_LABEL(tableswitch), - INSN_LABEL(lookupswitch), - INSN_LABEL(ireturn), - INSN_LABEL(lreturn), - INSN_LABEL(freturn), - INSN_LABEL(dreturn), - INSN_LABEL(areturn), - INSN_LABEL(return), - INSN_LABEL(getstatic), - INSN_LABEL(putstatic), - INSN_LABEL(getfield), - INSN_LABEL(putfield), - INSN_LABEL(invokevirtual), - INSN_LABEL(invokespecial), - INSN_LABEL(invokestatic), - INSN_LABEL(invokeinterface), - 0, /* op_xxxunusedxxx1, */ - INSN_LABEL(new), - INSN_LABEL(newarray), - INSN_LABEL(anewarray), - INSN_LABEL(arraylength), - INSN_LABEL(athrow), - INSN_LABEL(checkcast), - INSN_LABEL(instanceof), - INSN_LABEL(monitorenter), - INSN_LABEL(monitorexit), - INSN_LABEL(wide), - INSN_LABEL(multianewarray), - INSN_LABEL(ifnull), - INSN_LABEL(ifnonnull), - INSN_LABEL(goto_w), - INSN_LABEL(jsr_w), - }; - - /* If the macro INLINE_SWITCH is not defined, then the main loop - operates as one big (normal) switch statement. If it is defined, - then the case selection is performed `inline' in the end of the - code for each case. The latter saves a native branch instruction - for each java-instruction, but expands the code size somewhat. - - NOTE: On i386 defining INLINE_SWITCH improves over all - performance approximately seven percent, but it may be different - for other machines. At some point, this may be made into a proper - configuration parameter. */ - -#define INLINE_SWITCH - -#ifdef INLINE_SWITCH - -#define NEXT_INSN do { GOTO_INSN(*pc++); } while (0) - - - NEXT_INSN; -#else - -#define NEXT_INSN goto next_insn - - next_insn: - GOTO_INSN (*pc++); - -#endif - - /* The first few instructions here are ordered according to their - frequency, in the hope that this will improve code locality a - little. */ - - insn_aload_0: // 0x2a - LOADA(0); - NEXT_INSN; - - insn_iload: // 0x15 - LOADI (get1u (pc++)); - NEXT_INSN; - - insn_iload_1: // 0x1b - LOADI (1); - NEXT_INSN; - - insn_invokevirtual: // 0xb6 - SAVE_PC; - { - int index = get2u (pc); pc += 2; - - /* _Jv_ResolvePoolEntry returns immediately if the value already - * is resolved. If we want to clutter up the code here to gain - * a little performance, then we can check the corresponding bit - * JV_CONSTANT_ResolvedFlag in the tag directly. For now, I - * don't think it is worth it. */ - - rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod; - - sp -= rmeth->stack_item_count; - // We don't use NULLCHECK here because we can't rely on that - // working if the method is final. So instead we do an - // explicit test. - if (! sp[0].o) - throw new java::lang::NullPointerException; - - if (rmeth->vtable_index == -1) - { - // final methods do not appear in the vtable, - // if it does not appear in the superclass. - fun = (void (*)()) rmeth->method->ncode; - } - else - { - jobject rcv = sp[0].o; - _Jv_VTable *table = *(_Jv_VTable**)rcv; - fun = (void (*)()) table->get_method(rmeth->vtable_index); - } - } - goto perform_invoke; - - perform_invoke: - { - /* here goes the magic again... */ - ffi_cif *cif = &rmeth->cif; - ffi_raw *raw = (ffi_raw*) sp; - - jdouble rvalue; - -#if FFI_NATIVE_RAW_API - /* We assume that this is only implemented if it's correct */ - /* to use it here. On a 64 bit machine, it never is. */ - ffi_raw_call (cif, fun, (void*)&rvalue, raw); -#else - ffi_java_raw_call (cif, fun, (void*)&rvalue, raw); -#endif - - int rtype = cif->rtype->type; - - /* the likelyhood of object, int, or void return is very high, - * so those are checked before the switch */ - if (rtype == FFI_TYPE_POINTER) - { - PUSHA (*(jobject*)&rvalue); - } - else if (rtype == FFI_TYPE_SINT32) - { - PUSHI (*(jint*)&rvalue); - } - else if (rtype == FFI_TYPE_VOID) - { - /* skip */ - } - else switch (rtype) - { - case FFI_TYPE_SINT8: - { - jbyte value = (*(jint*)&rvalue) & 0xff; - PUSHI (value); - } - break; - - case FFI_TYPE_SINT16: - { - jshort value = (*(jint*)&rvalue) & 0xffff; - PUSHI (value); - } - break; - - case FFI_TYPE_UINT16: - { - jint value = (*(jint*)&rvalue) & 0xffff; - PUSHI (value); - } - break; - - case FFI_TYPE_FLOAT: - PUSHF (*(jfloat*)&rvalue); - break; - - case FFI_TYPE_DOUBLE: - PUSHD (rvalue); - break; - - case FFI_TYPE_SINT64: - PUSHL (*(jlong*)&rvalue); - break; - - default: - throw_internal_error ("unknown return type in invokeXXX"); - } - - } - NEXT_INSN; - - - insn_nop: - NEXT_INSN; - - insn_aconst_null: - PUSHA (NULL); - NEXT_INSN; - - insn_iconst_m1: - PUSHI (-1); - NEXT_INSN; - - insn_iconst_0: - PUSHI (0); - NEXT_INSN; - - insn_iconst_1: - PUSHI (1); - NEXT_INSN; - - insn_iconst_2: - PUSHI (2); - NEXT_INSN; - - insn_iconst_3: - PUSHI (3); - NEXT_INSN; - - insn_iconst_4: - PUSHI (4); - NEXT_INSN; - - insn_iconst_5: - PUSHI (5); - NEXT_INSN; - - insn_lconst_0: - PUSHL (0); - NEXT_INSN; - - insn_lconst_1: - PUSHL (1); - NEXT_INSN; - - insn_fconst_0: - PUSHF (0); - NEXT_INSN; - - insn_fconst_1: - PUSHF (1); - NEXT_INSN; - - insn_fconst_2: - PUSHF (2); - NEXT_INSN; - - insn_dconst_0: - PUSHD (0); - NEXT_INSN; - - insn_dconst_1: - PUSHD (1); - NEXT_INSN; - - insn_bipush: - PUSHI (get1s(pc++)); - NEXT_INSN; - - insn_sipush: - PUSHI (get2s(pc)); pc += 2; - NEXT_INSN; - - insn_ldc: - { - int index = get1u (pc++); - PUSHA(pool_data[index].o); - } - NEXT_INSN; - - insn_ldc_w: - { - int index = get2u (pc); pc += 2; - PUSHA(pool_data[index].o); - } - NEXT_INSN; - - insn_ldc2_w: - { - int index = get2u (pc); pc += 2; - memcpy (sp, &pool_data[index], 2*sizeof (_Jv_word)); - sp += 2; - } - NEXT_INSN; - - insn_lload: - LOADL (get1u (pc++)); - NEXT_INSN; - - insn_fload: - LOADF (get1u (pc++)); - NEXT_INSN; - - insn_dload: - LOADD (get1u (pc++)); - NEXT_INSN; - - insn_aload: - LOADA (get1u (pc++)); - NEXT_INSN; - - insn_iload_0: - LOADI (0); - NEXT_INSN; - - insn_iload_2: - LOADI (2); - NEXT_INSN; - - insn_iload_3: - LOADI (3); - NEXT_INSN; - - insn_lload_0: - LOADL (0); - NEXT_INSN; - - insn_lload_1: - LOADL (1); - NEXT_INSN; - - insn_lload_2: - LOADL (2); - NEXT_INSN; - - insn_lload_3: - LOADL (3); - NEXT_INSN; - - insn_fload_0: - LOADF (0); - NEXT_INSN; - - insn_fload_1: - LOADF (1); - NEXT_INSN; - - insn_fload_2: - LOADF (2); - NEXT_INSN; - - insn_fload_3: - LOADF (3); - NEXT_INSN; - - insn_dload_0: - LOADD (0); - NEXT_INSN; - - insn_dload_1: - LOADD (1); - NEXT_INSN; - - insn_dload_2: - LOADD (2); - NEXT_INSN; - - insn_dload_3: - LOADD (3); - NEXT_INSN; - - insn_aload_1: - LOADA(1); - NEXT_INSN; - - insn_aload_2: - LOADA(2); - NEXT_INSN; - - insn_aload_3: - LOADA(3); - NEXT_INSN; - - insn_iaload: - { - jint index = POPI(); - jintArray arr = (jintArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHI( elements(arr)[index] ); - } - NEXT_INSN; - - insn_laload: - { - jint index = POPI(); - jlongArray arr = (jlongArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHL( elements(arr)[index] ); - } - NEXT_INSN; - - insn_faload: - { - jint index = POPI(); - jfloatArray arr = (jfloatArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHF( elements(arr)[index] ); - } - NEXT_INSN; - - insn_daload: - { - jint index = POPI(); - jdoubleArray arr = (jdoubleArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHD( elements(arr)[index] ); - } - NEXT_INSN; - - insn_aaload: - { - jint index = POPI(); - jobjectArray arr = (jobjectArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHA( elements(arr)[index] ); - } - NEXT_INSN; - - insn_baload: - { - jint index = POPI(); - jbyteArray arr = (jbyteArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHI( elements(arr)[index] ); - } - NEXT_INSN; - - insn_caload: - { - jint index = POPI(); - jcharArray arr = (jcharArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHI( elements(arr)[index] ); - } - NEXT_INSN; - - insn_saload: - { - jint index = POPI(); - jshortArray arr = (jshortArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - PUSHI( elements(arr)[index] ); - } - NEXT_INSN; - - insn_istore: - STOREI (get1u (pc++)); - NEXT_INSN; - - insn_lstore: - STOREL (get1u (pc++)); - NEXT_INSN; - - insn_fstore: - STOREF (get1u (pc++)); - NEXT_INSN; - - insn_dstore: - STORED (get1u (pc++)); - NEXT_INSN; - - insn_astore: - STOREA (get1u (pc++)); - NEXT_INSN; - - insn_istore_0: - STOREI (0); - NEXT_INSN; - - insn_istore_1: - STOREI (1); - NEXT_INSN; - - insn_istore_2: - STOREI (2); - NEXT_INSN; - - insn_istore_3: - STOREI (3); - NEXT_INSN; - - insn_lstore_0: - STOREL (0); - NEXT_INSN; - - insn_lstore_1: - STOREL (1); - NEXT_INSN; - - insn_lstore_2: - STOREL (2); - NEXT_INSN; - - insn_lstore_3: - STOREL (3); - NEXT_INSN; - - insn_fstore_0: - STOREF (0); - NEXT_INSN; - - insn_fstore_1: - STOREF (1); - NEXT_INSN; - - insn_fstore_2: - STOREF (2); - NEXT_INSN; - - insn_fstore_3: - STOREF (3); - NEXT_INSN; - - insn_dstore_0: - STORED (0); - NEXT_INSN; - - insn_dstore_1: - STORED (1); - NEXT_INSN; - - insn_dstore_2: - STORED (2); - NEXT_INSN; - - insn_dstore_3: - STORED (3); - NEXT_INSN; - - insn_astore_0: - STOREA(0); - NEXT_INSN; - - insn_astore_1: - STOREA(1); - NEXT_INSN; - - insn_astore_2: - STOREA(2); - NEXT_INSN; - - insn_astore_3: - STOREA(3); - NEXT_INSN; - - insn_iastore: - { - jint value = POPI(); - jint index = POPI(); - jintArray arr = (jintArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_lastore: - { - jlong value = POPL(); - jint index = POPI(); - jlongArray arr = (jlongArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_fastore: - { - jfloat value = POPF(); - jint index = POPI(); - jfloatArray arr = (jfloatArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_dastore: - { - jdouble value = POPD(); - jint index = POPI(); - jdoubleArray arr = (jdoubleArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_aastore: - { - jobject value = POPA(); - jint index = POPI(); - jobjectArray arr = (jobjectArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - _Jv_CheckArrayStore (arr, value); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_bastore: - { - jbyte value = (jbyte) POPI(); - jint index = POPI(); - jbyteArray arr = (jbyteArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_castore: - { - jchar value = (jchar) POPI(); - jint index = POPI(); - jcharArray arr = (jcharArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_sastore: - { - jshort value = (jshort) POPI(); - jint index = POPI(); - jshortArray arr = (jshortArray) POPA(); - NULLARRAYCHECK (arr); - ARRAYBOUNDSCHECK (arr, index); - elements(arr)[index] = value; - } - NEXT_INSN; - - insn_pop: - sp -= 1; - NEXT_INSN; - - insn_pop2: - sp -= 2; - NEXT_INSN; - - insn_dup: - sp[0] = sp[-1]; - sp += 1; - NEXT_INSN; - - insn_dup_x1: - dupx (sp, 1, 1); sp+=1; - NEXT_INSN; - - insn_dup_x2: - dupx (sp, 1, 2); sp+=1; - NEXT_INSN; - - insn_dup2: - sp[0] = sp[-2]; - sp[1] = sp[-1]; - sp += 2; - NEXT_INSN; - - insn_dup2_x1: - dupx (sp, 2, 1); sp+=2; - NEXT_INSN; - - insn_dup2_x2: - dupx (sp, 2, 2); sp+=2; - NEXT_INSN; - - insn_swap: - { - jobject tmp1 = POPA(); - jobject tmp2 = POPA(); - PUSHA (tmp1); - PUSHA (tmp2); - } - NEXT_INSN; - - insn_iadd: - BINOPI(+); - NEXT_INSN; - - insn_ladd: - BINOPL(+); - NEXT_INSN; - - insn_fadd: - BINOPF(+); - NEXT_INSN; - - insn_dadd: - BINOPD(+); - NEXT_INSN; - - insn_isub: - BINOPI(-); - NEXT_INSN; - - insn_lsub: - BINOPL(-); - NEXT_INSN; - - insn_fsub: - BINOPF(-); - NEXT_INSN; - - insn_dsub: - BINOPD(-); - NEXT_INSN; - - insn_imul: - BINOPI(*); - NEXT_INSN; - - insn_lmul: - BINOPL(*); - NEXT_INSN; - - insn_fmul: - BINOPF(*); - NEXT_INSN; - - insn_dmul: - BINOPD(*); - NEXT_INSN; - - insn_idiv: - SAVE_PC; - { - jint value2 = POPI(); - jint value1 = POPI(); - jint res = _Jv_divI (value1, value2); - PUSHI (res); - } - NEXT_INSN; - - insn_ldiv: - SAVE_PC; - { - jlong value2 = POPL(); - jlong value1 = POPL(); - jlong res = _Jv_divJ (value1, value2); - PUSHL (res); - } - NEXT_INSN; - - insn_fdiv: - { - jfloat value2 = POPF(); - jfloat value1 = POPF(); - jfloat res = value1 / value2; - PUSHF (res); - } - NEXT_INSN; - - insn_ddiv: - { - jdouble value2 = POPD(); - jdouble value1 = POPD(); - jdouble res = value1 / value2; - PUSHD (res); - } - NEXT_INSN; - - insn_irem: - SAVE_PC; - { - jint value2 = POPI(); - jint value1 = POPI(); - jint res = _Jv_remI (value1, value2); - PUSHI (res); - } - NEXT_INSN; - - insn_lrem: - SAVE_PC; - { - jlong value2 = POPL(); - jlong value1 = POPL(); - jlong res = _Jv_remJ (value1, value2); - PUSHL (res); - } - NEXT_INSN; - - insn_frem: - { - jfloat value2 = POPF(); - jfloat value1 = POPF(); - jfloat res = __ieee754_fmod (value1, value2); - PUSHF (res); - } - NEXT_INSN; - - insn_drem: - { - jdouble value2 = POPD(); - jdouble value1 = POPD(); - jdouble res = __ieee754_fmod (value1, value2); - PUSHD (res); - } - NEXT_INSN; - - insn_ineg: - { - jint value = POPI(); - PUSHI (value * -1); - } - NEXT_INSN; - - insn_lneg: - { - jlong value = POPL(); - PUSHL (value * -1); - } - NEXT_INSN; - - insn_fneg: - { - jfloat value = POPF(); - PUSHF (value * -1); - } - NEXT_INSN; - - insn_dneg: - { - jdouble value = POPD(); - PUSHD (value * -1); - } - NEXT_INSN; - - insn_ishl: - { - jint shift = (POPI() & 0x1f); - jint value = POPI(); - PUSHI (value << shift); - } - NEXT_INSN; - - insn_lshl: - { - jint shift = (POPI() & 0x3f); - jlong value = POPL(); - PUSHL (value << shift); - } - NEXT_INSN; - - insn_ishr: - { - jint shift = (POPI() & 0x1f); - jint value = POPI(); - PUSHI (value >> shift); - } - NEXT_INSN; - - insn_lshr: - { - jint shift = (POPI() & 0x3f); - jlong value = POPL(); - PUSHL (value >> shift); - } - NEXT_INSN; - - insn_iushr: - { - jint shift = (POPI() & 0x1f); - unsigned long value = POPI(); - PUSHI ((jint) (value >> shift)); - } - NEXT_INSN; - - insn_lushr: - { - jint shift = (POPI() & 0x3f); - UINT64 value = (UINT64) POPL(); - PUSHL ((value >> shift)); - } - NEXT_INSN; - - insn_iand: - BINOPI (&); - NEXT_INSN; - - insn_land: - BINOPL (&); - NEXT_INSN; - - insn_ior: - BINOPI (|); - NEXT_INSN; - - insn_lor: - BINOPL (|); - NEXT_INSN; - - insn_ixor: - BINOPI (^); - NEXT_INSN; - - insn_lxor: - BINOPL (^); - NEXT_INSN; - - insn_iinc: - { - jint index = get1u (pc++); - jint amount = get1s (pc++); - locals[index].i += amount; - } - NEXT_INSN; - - insn_i2l: - {jlong value = POPI(); PUSHL (value);} - NEXT_INSN; - - insn_i2f: - {jfloat value = POPI(); PUSHF (value);} - NEXT_INSN; - - insn_i2d: - {jdouble value = POPI(); PUSHD (value);} - NEXT_INSN; - - insn_l2i: - {jint value = POPL(); PUSHI (value);} - NEXT_INSN; - - insn_l2f: - {jfloat value = POPL(); PUSHF (value);} - NEXT_INSN; - - insn_l2d: - {jdouble value = POPL(); PUSHD (value);} - NEXT_INSN; - - insn_f2i: - { - using namespace java::lang; - jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE); - PUSHI(value); - } - NEXT_INSN; - - insn_f2l: - { - using namespace java::lang; - jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE); - PUSHL(value); - } - NEXT_INSN; - - insn_f2d: - { jdouble value = POPF (); PUSHD(value); } - NEXT_INSN; - - insn_d2i: - { - using namespace java::lang; - jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE); - PUSHI(value); - } - NEXT_INSN; - - insn_d2l: - { - using namespace java::lang; - jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE); - PUSHL(value); - } - NEXT_INSN; - - insn_d2f: - { jfloat value = POPD (); PUSHF(value); } - NEXT_INSN; - - insn_i2b: - { jbyte value = POPI (); PUSHI(value); } - NEXT_INSN; - - insn_i2c: - { jchar value = POPI (); PUSHI(value); } - NEXT_INSN; - - insn_i2s: - { jshort value = POPI (); PUSHI(value); } - NEXT_INSN; - - insn_lcmp: - { - jlong value2 = POPL (); - jlong value1 = POPL (); - if (value1 > value2) - { PUSHI (1); } - else if (value1 == value2) - { PUSHI (0); } - else - { PUSHI (-1); } - } - NEXT_INSN; - - insn_fcmpl: - insn_fcmpg: - { - jfloat value2 = POPF (); - jfloat value1 = POPF (); - if (value1 > value2) - PUSHI (1); - else if (value1 == value2) - PUSHI (0); - else if (value1 < value2) - PUSHI (-1); - else if ((*(pc-1)) == op_fcmpg) - PUSHI (1); - else - PUSHI (-1); - } - NEXT_INSN; - - insn_dcmpl: - insn_dcmpg: - { - jdouble value2 = POPD (); - jdouble value1 = POPD (); - if (value1 > value2) - PUSHI (1); - else if (value1 == value2) - PUSHI (0); - else if (value1 < value2) - PUSHI (-1); - else if ((*(pc-1)) == op_dcmpg) - PUSHI (1); - else - PUSHI (-1); - } - NEXT_INSN; - - insn_ifeq: - { - jint offset = get2s (pc); - if (POPI() == 0) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_ifne: - { - jint offset = get2s (pc); - if (POPI() != 0) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_iflt: - { - jint offset = get2s (pc); - if (POPI() < 0) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_ifge: - { - jint offset = get2s (pc); - if (POPI() >= 0) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_ifgt: - { - jint offset = get2s (pc); - if (POPI() > 0) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_ifle: - { - jint offset = get2s (pc); - if (POPI() <= 0) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_icmpeq: - { - jint offset = get2s (pc); - jint value2 = POPI(); - jint value1 = POPI(); - if (value1 == value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_icmpne: - { - jint offset = get2s (pc); - jint value2 = POPI(); - jint value1 = POPI(); - if (value1 != value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_icmplt: - { - jint offset = get2s (pc); - jint value2 = POPI(); - jint value1 = POPI(); - if (value1 < value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_icmpge: - { - jint offset = get2s (pc); - jint value2 = POPI(); - jint value1 = POPI(); - if (value1 >= value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_icmpgt: - { - jint offset = get2s (pc); - jint value2 = POPI(); - jint value1 = POPI(); - if (value1 > value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_icmple: - { - jint offset = get2s (pc); - jint value2 = POPI(); - jint value1 = POPI(); - if (value1 <= value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_acmpeq: - { - jint offset = get2s (pc); - jobject value2 = POPA(); - jobject value1 = POPA(); - if (value1 == value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_if_acmpne: - { - jint offset = get2s (pc); - jobject value2 = POPA(); - jobject value1 = POPA(); - if (value1 != value2) - pc = pc-1+offset; - else - pc = pc+2; - } - NEXT_INSN; - - insn_goto: - { - jint offset = get2s (pc); - pc = pc-1+offset; - } - NEXT_INSN; - - insn_jsr: - { - unsigned char *base_pc = pc-1; - jint offset = get2s (pc); pc += 2; - PUSHA ((jobject)pc); - pc = base_pc+offset; - } - NEXT_INSN; - - insn_ret: - { - jint index = get1u (pc); - pc = (unsigned char*) PEEKA (index); - } - NEXT_INSN; - - insn_tableswitch: - { - unsigned char *base_pc = pc-1; - int index = POPI(); - - unsigned char* base = bytecode (); - while ((pc-base) % 4 != 0) - pc++; - - jint def = get4 (pc); - jint low = get4 (pc+4); - jint high = get4 (pc+8); - - if (index < low || index > high) - pc = base_pc + def; - else - pc = base_pc + get4 (pc+4*(index-low+3)); - } - NEXT_INSN; - - insn_lookupswitch: - { - unsigned char *base_pc = pc-1; - int index = POPI(); - - unsigned char* base = bytecode (); - while ((pc-base) % 4 != 0) - pc++; - - jint def = get4 (pc); - jint npairs = get4 (pc+4); - - int max = npairs-1; - int min = 0; - - // simple binary search... - while (min < max) - { - int half = (min+max)/2; - int match = get4 (pc+ 4*(2 + 2*half)); - - if (index == match) - min = max = half; - - else if (index < match) - max = half-1; - - else - min = half+1; - } - - if (index == get4 (pc+ 4*(2 + 2*min))) - pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1)); - else - pc = base_pc + def; - } - NEXT_INSN; - - /* on return, just save the sp and return to caller */ - insn_ireturn: - insn_lreturn: - insn_freturn: - insn_dreturn: - insn_areturn: - insn_return: - inv->sp = sp; - return; - - insn_getstatic: - SAVE_PC; - { - jint fieldref_index = get2u (pc); pc += 2; - _Jv_ResolvePoolEntry (defining_class, fieldref_index); - _Jv_Field *field = pool_data[fieldref_index].field; - - if ((field->flags & Modifier::STATIC) == 0) - throw_incompatible_class_change_error - (JvNewStringLatin1 ("field no longer static")); - - jclass type = field->type; - - if (type->isPrimitive ()) - { - switch (type->size_in_bytes) - { - case 1: - PUSHI (*(jbyte*) (field->u.addr)); - break; - - case 2: - if (type == JvPrimClass (char)) - PUSHI(*(jchar*) (field->u.addr)); - else - PUSHI(*(jshort*) (field->u.addr)); - break; - - case 4: - PUSHI(*(jint*) (field->u.addr)); - break; - - case 8: - PUSHL(*(jlong*) (field->u.addr)); - break; - } - } - else - { - PUSHA(*(jobject*) (field->u.addr)); - } - } - NEXT_INSN; - - insn_getfield: - SAVE_PC; - { - jint fieldref_index = get2u (pc); pc += 2; - _Jv_ResolvePoolEntry (defining_class, fieldref_index); - _Jv_Field *field = pool_data[fieldref_index].field; - - if ((field->flags & Modifier::STATIC) != 0) - throw_incompatible_class_change_error - (JvNewStringLatin1 ("field is static")); - - jclass type = field->type; - jint field_offset = field->u.boffset; - if (field_offset > 0xffff) - throw new java::lang::VirtualMachineError; - - jobject obj = POPA(); - NULLCHECK(obj); - - if (type->isPrimitive ()) - { - switch (type->size_in_bytes) - { - case 1: - PUSHI (*(jbyte*) ((char*)obj + field_offset)); - break; - - case 2: - if (type == JvPrimClass (char)) - PUSHI (*(jchar*) ((char*)obj + field_offset)); - else - PUSHI (*(jshort*) ((char*)obj + field_offset)); - break; - - case 4: - PUSHI (*(jint*) ((char*)obj + field_offset)); - break; - - case 8: - PUSHL(*(jlong*) ((char*)obj + field_offset)); - break; - } - } - else - { - PUSHA(*(jobject*) ((char*)obj + field_offset)); - } - } - NEXT_INSN; - - insn_putstatic: - SAVE_PC; - { - jint fieldref_index = get2u (pc); pc += 2; - _Jv_ResolvePoolEntry (defining_class, fieldref_index); - _Jv_Field *field = pool_data[fieldref_index].field; - - jclass type = field->type; - - // ResolvePoolEntry cannot check this - if ((field->flags & Modifier::STATIC) == 0) - throw_incompatible_class_change_error - (JvNewStringLatin1 ("field no longer static")); - - if (type->isPrimitive ()) - { - switch (type->size_in_bytes) - { - case 1: - { - jint value = POPI(); - *(jbyte*) (field->u.addr) = value; - break; - } - - case 2: - { - jint value = POPI(); - *(jchar*) (field->u.addr) = value; - break; - } - - case 4: - { - jint value = POPI(); - *(jint*) (field->u.addr) = value; - break; - } - - case 8: - { - jlong value = POPL(); - *(jlong*) (field->u.addr) = value; - break; - } - } - } - else - { - jobject value = POPA(); - *(jobject*) (field->u.addr) = value; - } - } - NEXT_INSN; - - - insn_putfield: - SAVE_PC; - { - jint fieldref_index = get2u (pc); pc += 2; - _Jv_ResolvePoolEntry (defining_class, fieldref_index); - _Jv_Field *field = pool_data[fieldref_index].field; - - jclass type = field->type; - - if ((field->flags & Modifier::STATIC) != 0) - throw_incompatible_class_change_error - (JvNewStringLatin1 ("field is static")); - - jint field_offset = field->u.boffset; - if (field_offset > 0xffff) - throw new java::lang::VirtualMachineError; - - if (type->isPrimitive ()) - { - switch (type->size_in_bytes) - { - case 1: - { - jint value = POPI(); - jobject obj = POPA(); - NULLCHECK(obj); - *(jbyte*) ((char*)obj + field_offset) = value; - break; - } - - case 2: - { - jint value = POPI(); - jobject obj = POPA(); - NULLCHECK(obj); - *(jchar*) ((char*)obj + field_offset) = value; - break; - } - - case 4: - { - jint value = POPI(); - jobject obj = POPA(); - NULLCHECK(obj); - *(jint*) ((char*)obj + field_offset) = value; - break; - } - - case 8: - { - jlong value = POPL(); - jobject obj = POPA(); - NULLCHECK(obj); - *(jlong*) ((char*)obj + field_offset) = value; - break; - } - } - } - else - { - jobject value = POPA(); - jobject obj = POPA(); - NULLCHECK(obj); - *(jobject*) ((char*)obj + field_offset) = value; - } - } - NEXT_INSN; - - insn_invokespecial: - SAVE_PC; - { - int index = get2u (pc); pc += 2; - - rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod; - - sp -= rmeth->stack_item_count; - - NULLCHECK (sp[0].o); - - fun = (void (*)()) rmeth->method->ncode; - } - goto perform_invoke; - - insn_invokestatic: - SAVE_PC; - { - int index = get2u (pc); pc += 2; - - rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod; - - sp -= rmeth->stack_item_count; - - _Jv_InitClass (rmeth->klass); - fun = (void (*)()) rmeth->method->ncode; - } - goto perform_invoke; - - insn_invokeinterface: - SAVE_PC; - { - int index = get2u (pc); pc += 2; - - // invokeinterface has two unused bytes... - pc += 2; - - rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod; - - sp -= rmeth->stack_item_count; - - jobject rcv = sp[0].o; - - NULLCHECK (rcv); - - fun = (void (*)()) - _Jv_LookupInterfaceMethod (rcv->getClass (), - rmeth->method->name, - rmeth->method->signature); - } - goto perform_invoke; - - - insn_new: - SAVE_PC; - { - int index = get2u (pc); pc += 2; - jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz; - _Jv_InitClass (klass); - jobject res = _Jv_AllocObject (klass, klass->size_in_bytes); - PUSHA (res); - } - NEXT_INSN; - - insn_newarray: - SAVE_PC; - { - int atype = get1u (pc++); - int size = POPI(); - jobject result = _Jv_NewArray (atype, size); - PUSHA (result); - } - NEXT_INSN; - - insn_anewarray: - SAVE_PC; - { - int index = get2u (pc); pc += 2; - jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz; - int size = POPI(); - _Jv_InitClass (klass); - jobject result = _Jv_NewObjectArray (size, klass, 0); - PUSHA (result); - } - NEXT_INSN; - - insn_arraylength: - { - __JArray *arr = (__JArray*)POPA(); - NULLARRAYCHECK (arr); - PUSHI (arr->length); - } - NEXT_INSN; - - insn_athrow: - SAVE_PC; - { - jobject value = POPA(); - throw static_cast(value); - } - NEXT_INSN; - - insn_checkcast: - SAVE_PC; - { - jobject value = POPA(); - jint index = get2u (pc); pc += 2; - jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz; - - if (value != NULL && ! to->isInstance (value)) - { - throw new java::lang::ClassCastException (to->getName()); - } - - PUSHA (value); - } - NEXT_INSN; - - insn_instanceof: - SAVE_PC; - { - jobject value = POPA(); - jint index = get2u (pc); pc += 2; - jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz; - PUSHI (to->isInstance (value)); - } - NEXT_INSN; - - insn_monitorenter: - SAVE_PC; - { - jobject value = POPA(); - NULLCHECK(value); - _Jv_MonitorEnter (value); - } - NEXT_INSN; - - insn_monitorexit: - SAVE_PC; - { - jobject value = POPA(); - NULLCHECK(value); - _Jv_MonitorExit (value); - } - NEXT_INSN; - - insn_ifnull: - { - unsigned char* base_pc = pc-1; - jint offset = get2s (pc); pc += 2; - jobject val = POPA(); - if (val == NULL) - pc = base_pc+offset; - } - NEXT_INSN; - - insn_ifnonnull: - { - unsigned char* base_pc = pc-1; - jint offset = get2s (pc); pc += 2; - jobject val = POPA(); - if (val != NULL) - pc = base_pc+offset; - } - NEXT_INSN; - - insn_wide: - SAVE_PC; - { - jint the_mod_op = get1u (pc++); - jint wide = get2u (pc); pc += 2; - - switch (the_mod_op) - { - case op_istore: - STOREI (wide); - NEXT_INSN; - - case op_fstore: - STOREF (wide); - NEXT_INSN; - - case op_astore: - STOREA (wide); - NEXT_INSN; - - case op_lload: - LOADL (wide); - NEXT_INSN; - - case op_dload: - LOADD (wide); - NEXT_INSN; - - case op_iload: - LOADI (wide); - NEXT_INSN; - - case op_aload: - LOADA (wide); - NEXT_INSN; - - case op_lstore: - STOREL (wide); - NEXT_INSN; - - case op_dstore: - STORED (wide); - NEXT_INSN; - - case op_ret: - pc = (unsigned char*) PEEKA (wide); - NEXT_INSN; - - case op_iinc: - { - jint amount = get2s (pc); pc += 2; - jint value = PEEKI (wide); - POKEI (wide, value+amount); - } - NEXT_INSN; - - default: - throw_internal_error ("illegal bytecode modified by wide"); - } - - } - - insn_multianewarray: - SAVE_PC; - { - int kind_index = get2u (pc); pc += 2; - int dim = get1u (pc); pc += 1; - - jclass type - = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz; - _Jv_InitClass (type); - jint *sizes = (jint*) __builtin_alloca (sizeof (jint)*dim); - - for (int i = dim - 1; i >= 0; i--) - { - sizes[i] = POPI (); - } - - jobject res = _Jv_NewMultiArray (type,dim, sizes); - - PUSHA (res); - } - NEXT_INSN; - - insn_goto_w: - { - unsigned char* base_pc = pc-1; - int offset = get4 (pc); pc += 4; - pc = base_pc+offset; - } - NEXT_INSN; - - insn_jsr_w: - { - unsigned char* base_pc = pc-1; - int offset = get4 (pc); pc += 4; - PUSHA((jobject)pc); - pc = base_pc+offset; - } - NEXT_INSN; -} - - -static void -throw_internal_error (char *msg) -{ - throw new java::lang::InternalError (JvNewStringLatin1 (msg)); -} - -static void -throw_incompatible_class_change_error (jstring msg) -{ - throw new java::lang::IncompatibleClassChangeError (msg); -} - -#ifndef HANDLE_SEGV -static java::lang::NullPointerException *null_pointer_exc; -static void -throw_null_pointer_exception () -{ - if (null_pointer_exc == NULL) - null_pointer_exc = new java::lang::NullPointerException; - - throw null_pointer_exc; -} -#endif - -#endif // INTERPRETER