// interpret.cc - Code for the interpreter
-/* Copyright (C) 1999 Cygnus Solutions
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation
This file is part of libgcj.
#pragma implementation "java-interp.h"
-#include <cni.h>
#include <jvm.h>
-#include <java-field.h>
#include <java-cpool.h>
#include <java-interp.h>
-#include <java/lang/fdlibm.h>
+// #include <java/lang/fdlibm.h>
#include <java/lang/System.h>
#include <java/lang/String.h>
#include <java/lang/Integer.h>
#include <java/lang/StringBuffer.h>
-#include <java/io/PrintStream.h>
#include <java/lang/Class.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/ClassCastException.h>
#include <java-insns.h>
#include <java-signal.h>
-#ifndef INTERPRETER
+#ifdef INTERPRETER
-#include <gnu/gcj/runtime/MethodInvocation.h>
-
-/* This should never happen. */
-void
-gnu::gcj::runtime::MethodInvocation::continue1 (gnu::gcj::RawData *,
- gnu::gcj::RawData *)
-{
- JvFail ("no interpreter");
-}
-
-#else
-
-#define ClassError _CL_Q34java4lang5Error
-extern java::lang::Class ClassError;
-
-static const int PUBLIC = 0x001;
-static const int PRIVATE = 0x002;
-static const int PROTECTED = 0x004;
-static const int STATIC = 0x008;
-static const int FINAL = 0x010;
-static const int SYNCHRONIZED = 0x020;
-static const int VOLATILE = 0x040;
-static const int TRANSIENT = 0x080;
-static const int NATIVE = 0x100;
-static const int INTERFACE = 0x200;
-static const int ABSTRACT = 0x400;
-static const int ALL_FLAGS = 0x7FF;
+#include <stdlib.h>
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
__attribute__ ((__noreturn__));
static void throw_incompatible_class_change_error (jstring msg)
__attribute__ ((__noreturn__));
-#if !HANDLE_SEGV
+#ifndef HANDLE_SEGV
static void throw_null_pointer_exception ()
__attribute__ ((__noreturn__));
#endif
-#if !HANDLE_FPE
-static void throw_arithmetic_exception ()
- __attribute__ ((__noreturn__));
-#endif
+extern "C" double __ieee754_fmod (double,double);
static inline void dupx (_Jv_word *sp, int n, int x)
{
#define PUSHA(V) (sp++)->o = (V)
#define PUSHI(V) (sp++)->i = (V)
#define PUSHF(V) (sp++)->f = (V)
-#define PUSHL(V) ({ _Jv_word2 w2; w2.l=(V); \
- (sp++)->ia[0] = w2.ia[0]; \
- (sp++)->ia[0] = w2.ia[1]; })
-#define PUSHD(V) ({ _Jv_word2 w2; w2.d=(V); \
- (sp++)->ia[0] = w2.ia[0]; \
- (sp++)->ia[0] = w2.ia[1]; })
+#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)
-#define POPL() ({ _Jv_word2 w2; \
+#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; \
+# 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
-#define LOADL(I) ({ jint __idx = (I); \
- (sp++)->ia[0] = locals[__idx].ia[0]; \
- (sp++)->ia[0] = locals[__idx+1].ia[0]; \
- })
-#define LOADD(I) LOADL(I)
-
+#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
-#define STOREL(I) ({ jint __idx = (I); \
- locals[__idx+1].ia[0] = (--sp)->ia[0]; \
- locals[__idx].ia[0] = (--sp)->ia[0]; \
- })
-#define STORED(I) STOREL(I)
+#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
}
-#if HANDLE_SEGV
+#ifdef HANDLE_SEGV
#define NULLCHECK(X)
#else
#define NULLCHECK(X) \
do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
#endif
-#if HANDLE_FPE
-#define ZEROCHECK(X)
-#else
-#define ZEROCHECK(X) \
- do { if ((X) == 0) throw_arithmetic_exception (); } while (0)
-#endif
// this method starts the actual running of the method. It is inlined
// in three different variants in the static methods run_normal,
_Jv_word *locals = inv->local_base ();
/* Go straight at it! the ffi raw format matches the internal
- stack representation exactly. At leat, that's the idea.
+ stack representation exactly. At least, that's the idea.
*/
memcpy ((void*) locals, (void*) args, args_raw_size);
next_segment:
- /* this will call the method _Jv_InterpMethod::continue0, see below */
- jobject ex =
- gnu::gcj::runtime::MethodInvocation::continue0
- ((gnu::gcj::RawData *)this, (gnu::gcj::RawData *)inv);
+
+ jobject ex = NULL;
+
+ try
+ {
+ continue1 (inv);
+ }
+ catch (java::lang::Throwable *ex2)
+ {
+ ex = ex2;
+ }
if (ex == 0) // no exception...
{
default:
throw_internal_error ("unknown return type");
}
-
}
/** handle an exception */
if ( find_exception (ex, inv) )
goto next_segment;
- java::lang::System::out->println
- (_Jv_NewStringUTF (self->name->data));
-
return ex;
}
// "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*)
- alloca (sizeof (_Jv_InterpMethodInvocation)
- + storage_size * sizeof (_Jv_word));
+ __builtin_alloca (sizeof (_Jv_InterpMethodInvocation)
+ + storage_size * sizeof (_Jv_word));
jobject ex = _this->run (cif, ret, args, inv);
- if (ex != 0) _Jv_Throw (ex);
+ if (ex != 0) throw static_cast<jthrowable>(ex);
}
void _Jv_InterpMethod::run_synch_object (ffi_cif* cif,
int storage_size = _this->max_stack+_this->max_locals;
_Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
- alloca (sizeof (_Jv_InterpMethodInvocation)
- + storage_size * sizeof (_Jv_word));
+ __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) _Jv_Throw (ex);
+ if (ex != 0) throw static_cast<jthrowable>(ex);
}
void _Jv_InterpMethod::run_synch_class (ffi_cif* cif,
int storage_size = _this->max_stack+_this->max_locals;
_Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
- alloca (sizeof (_Jv_InterpMethodInvocation)
- + storage_size * sizeof (_Jv_word));
+ __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) _Jv_Throw (ex);
-}
-
-/* this is the exception handler hack, for the interpreter */
-void
-gnu::gcj::runtime::MethodInvocation::continue1 (gnu::gcj::RawData *meth,
- gnu::gcj::RawData *inv)
-{
- _Jv_InterpMethod *meth0 = (_Jv_InterpMethod*)meth;
- _Jv_InterpMethodInvocation *inv0 = (_Jv_InterpMethodInvocation*)inv;
- meth0->continue1 (inv0);
+ if (ex != 0) throw static_cast<jthrowable>(ex);
}
/*
*/
-#ifdef __i386__
-#define PC_REGISTER_ASM asm("%esi")
-#else
-#define PC_REGISTER_ASM
-#endif
-
void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
{
- register _Jv_word *sp = inv->sp;
- register unsigned char *pc PC_REGISTER_ASM = inv->pc;
- _Jv_word *locals = inv->local_base ();
+ 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)(...);
+ void (*fun)();
_Jv_ResolvedMethod* rmeth;
#define INSN_LABEL(op) &&insn_##op
INSN_LABEL(ifnonnull),
INSN_LABEL(goto_w),
INSN_LABEL(jsr_w),
-
- INSN_LABEL(putfield_1),
- INSN_LABEL(putfield_2),
- INSN_LABEL(putfield_4),
- INSN_LABEL(putfield_8),
- INSN_LABEL(putfield_a),
-
- INSN_LABEL(putstatic_1),
- INSN_LABEL(putstatic_2),
- INSN_LABEL(putstatic_4),
- INSN_LABEL(putstatic_8),
- INSN_LABEL(putstatic_a),
-
- INSN_LABEL(getfield_1),
- INSN_LABEL(getfield_2s),
- INSN_LABEL(getfield_2u),
- INSN_LABEL(getfield_4),
- INSN_LABEL(getfield_8),
- INSN_LABEL(getfield_a),
-
- INSN_LABEL(getstatic_1),
- INSN_LABEL(getstatic_2s),
- INSN_LABEL(getstatic_2u),
- INSN_LABEL(getstatic_4),
- INSN_LABEL(getstatic_8),
- INSN_LABEL(getstatic_a),
};
#define SAVE_PC inv->pc = pc-1
#ifdef INLINE_SWITCH
-#define NEXT_INSN GOTO_INSN(*pc++)
+#define NEXT_INSN do { GOTO_INSN(*pc++); } while (0)
+
+
NEXT_INSN;
#else
LOADI (get1u (pc++));
NEXT_INSN;
- insn_getfield_4: // 0xd8
- SAVE_PC;
- {
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- PUSHI (*(jint*) ((char*)obj + field_offset));
- }
- NEXT_INSN;
-
insn_iload_1: // 0x1b
LOADI (1);
NEXT_INSN;
- insn_getfield_a: // 0xda
- SAVE_PC;
- {
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- PUSHA(*(jobject*) ((char*)obj + field_offset));
- }
- NEXT_INSN;
-
insn_invokevirtual: // 0xb6
SAVE_PC;
{
rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
sp -= rmeth->stack_item_count;
- NULLCHECK(sp[0]);
+ // 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;
+ fun = (void (*)()) rmeth->method->ncode;
}
else
{
jobject rcv = sp[0].o;
_Jv_VTable *table = *(_Jv_VTable**)rcv;
- fun = (void (*) (...))table->method[rmeth->vtable_index];
+ fun = (void (*)()) table->method[rmeth->vtable_index];
}
}
goto perform_invoke;
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;
NEXT_INSN;
insn_astore:
- STOREI (get1u (pc++));
+ STOREA (get1u (pc++));
NEXT_INSN;
insn_istore_0:
{
jint value2 = POPI();
jint value1 = POPI();
- ZEROCHECK (value2);
- jint res = value1 / value2;
+ jint res = _Jv_divI (value1, value2);
PUSHI (res);
}
NEXT_INSN;
{
jlong value2 = POPL();
jlong value1 = POPL();
- ZEROCHECK (value2);
- jlong res = value1 / value2;
+ jlong res = _Jv_divJ (value1, value2);
PUSHL (res);
}
NEXT_INSN;
{
jfloat value2 = POPF();
jfloat value1 = POPF();
- ZEROCHECK (value2);
jfloat res = value1 / value2;
PUSHF (res);
}
{
jdouble value2 = POPD();
jdouble value1 = POPD();
- ZEROCHECK (value2);
jdouble res = value1 / value2;
PUSHD (res);
}
SAVE_PC;
{
jint value2 = POPI();
- jint value1 = POPI();
- ZEROCHECK (value2);
- jint res = value1 % value2;
+ jint value1 = POPI();
+ jint res = _Jv_remI (value1, value2);
PUSHI (res);
}
NEXT_INSN;
{
jlong value2 = POPL();
jlong value1 = POPL();
- ZEROCHECK (value2);
- jlong res = value1 % value2;
+ jlong res = _Jv_remJ (value1, value2);
PUSHL (res);
}
NEXT_INSN;
{
jfloat value2 = POPF();
jfloat value1 = POPF();
- ZEROCHECK (value2);
jfloat res = __ieee754_fmod (value1, value2);
PUSHF (res);
}
{
jdouble value2 = POPD();
jdouble value1 = POPD();
- ZEROCHECK (value2);
jdouble res = __ieee754_fmod (value1, value2);
PUSHD (res);
}
insn_getstatic:
SAVE_PC;
{
- unsigned char *base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field;
- if ((field->flags & STATIC) == 0)
+ if ((field->flags & Modifier::STATIC) == 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("field no longer static"));
switch (type->size_in_bytes)
{
case 1:
- *base_pc = op_getstatic_1;
+ PUSHI (*(jbyte*) (field->u.addr));
break;
case 2:
if (type == JvPrimClass (char))
- *base_pc = op_getstatic_2u;
+ PUSHI(*(jchar*) (field->u.addr));
else
- *base_pc = op_getstatic_2s;
+ PUSHI(*(jshort*) (field->u.addr));
break;
case 4:
- *base_pc = op_getstatic_4;
+ PUSHI(*(jint*) (field->u.addr));
break;
case 8:
- *base_pc = op_getstatic_8;
+ PUSHL(*(jlong*) (field->u.addr));
break;
}
}
else
{
- *base_pc = op_getstatic_a;
+ PUSHA(*(jobject*) (field->u.addr));
}
-
- pc = base_pc;
}
NEXT_INSN;
insn_getfield:
SAVE_PC;
{
- unsigned char *base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field;
- if ((field->flags & STATIC) != 0)
+ 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:
- *base_pc = op_getfield_1;
+ PUSHI (*(jbyte*) ((char*)obj + field_offset));
break;
case 2:
if (type == JvPrimClass (char))
- *base_pc = op_getfield_2u;
+ PUSHI (*(jchar*) ((char*)obj + field_offset));
else
- *base_pc = op_getfield_2s;
+ PUSHI (*(jshort*) ((char*)obj + field_offset));
break;
case 4:
- *base_pc = op_getfield_4;
+ PUSHI (*(jint*) ((char*)obj + field_offset));
break;
case 8:
- *base_pc = op_getfield_8;
+ PUSHL(*(jlong*) ((char*)obj + field_offset));
break;
}
}
else
{
- *base_pc = op_getfield_a;
+ PUSHA(*(jobject*) ((char*)obj + field_offset));
}
-
- if (field->u.boffset > 0xffff)
- JvThrow (new java::lang::VirtualMachineError);
-
- base_pc[1] = (field->u.boffset>>8) & 0xff;
- base_pc[2] = field->u.boffset & 0xff;
-
- pc = base_pc;
}
NEXT_INSN;
insn_putstatic:
SAVE_PC;
{
- unsigned char* base_pc = pc-1;
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 & STATIC) == 0)
+ if ((field->flags & Modifier::STATIC) == 0)
throw_incompatible_class_change_error
(JvNewStringLatin1 ("field no longer static"));
- /* if this is patented, then maybe we could install
- a function in the constant pool, to do the right thing */
-
if (type->isPrimitive ())
{
switch (type->size_in_bytes)
{
case 1:
- *base_pc = op_putstatic_1;
- break;
+ {
+ jint value = POPI();
+ *(jbyte*) (field->u.addr) = value;
+ break;
+ }
case 2:
- *base_pc = op_putstatic_2;
- break;
+ {
+ jint value = POPI();
+ *(jchar*) (field->u.addr) = value;
+ break;
+ }
case 4:
- *base_pc = op_putstatic_4;
- break;
+ {
+ jint value = POPI();
+ *(jint*) (field->u.addr) = value;
+ break;
+ }
case 8:
- *base_pc = op_putstatic_8;
- break;
+ {
+ jlong value = POPL();
+ *(jlong*) (field->u.addr) = value;
+ break;
+ }
}
}
else
{
- *base_pc = op_putstatic_a;
+ jobject value = POPA();
+ *(jobject*) (field->u.addr) = value;
}
-
- // do the instruction again!
- pc = base_pc;
}
NEXT_INSN;
insn_putfield:
SAVE_PC;
{
- unsigned char* base_pc = pc-1;
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 & STATIC) != 0)
+ 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:
- *base_pc = op_putfield_1;
- break;
+ {
+ jint value = POPI();
+ jobject obj = POPA();
+ NULLCHECK(obj);
+ *(jbyte*) ((char*)obj + field_offset) = value;
+ break;
+ }
case 2:
- *base_pc = op_putfield_2;
- break;
+ {
+ jint value = POPI();
+ jobject obj = POPA();
+ NULLCHECK(obj);
+ *(jchar*) ((char*)obj + field_offset) = value;
+ break;
+ }
case 4:
- *base_pc = op_putfield_4;
- break;
+ {
+ jint value = POPI();
+ jobject obj = POPA();
+ NULLCHECK(obj);
+ *(jint*) ((char*)obj + field_offset) = value;
+ break;
+ }
case 8:
- *base_pc = op_putfield_8;
- break;
+ {
+ jlong value = POPL();
+ jobject obj = POPA();
+ NULLCHECK(obj);
+ *(jlong*) ((char*)obj + field_offset) = value;
+ break;
+ }
}
}
else
{
- *base_pc = op_putfield_a;
+ jobject value = POPA();
+ jobject obj = POPA();
+ NULLCHECK(obj);
+ *(jobject*) ((char*)obj + field_offset) = value;
}
-
- if (field->u.boffset > 0xffff)
- JvThrow (new java::lang::VirtualMachineError);
-
- base_pc[1] = (field->u.boffset>>8) & 0xff;
- base_pc[2] = field->u.boffset & 0xff;
-
- // do the instruction again!
- pc = base_pc;
- }
- NEXT_INSN;
-
-
- insn_getfield_1:
- SAVE_PC;
- {
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- PUSHI (*(jbyte*) ((char*)obj + field_offset));
- }
- NEXT_INSN;
-
- insn_getfield_2s:
- SAVE_PC;
- {
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- PUSHI (*(jshort*) ((char*)obj + field_offset));
- }
- NEXT_INSN;
-
- insn_getfield_2u:
- SAVE_PC;
- {
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- PUSHI (*(jchar*) ((char*)obj + field_offset));
- }
- NEXT_INSN;
-
- insn_getfield_8:
- SAVE_PC;
- {
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- PUSHL(*(jlong*) ((char*)obj + field_offset));
- }
- NEXT_INSN;
-
- insn_getstatic_1:
- {
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- PUSHI (*(jbyte*) (field->u.addr));
- }
- NEXT_INSN;
-
- insn_getstatic_2s:
- {
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- PUSHI(*(jshort*) (field->u.addr));
- }
- NEXT_INSN;
-
- insn_getstatic_2u:
- {
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- PUSHI(*(jchar*) (field->u.addr));
- }
- NEXT_INSN;
-
- insn_getstatic_4:
- {
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- PUSHI(*(jint*) (field->u.addr));
- }
- NEXT_INSN;
-
- insn_getstatic_8:
- {
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- PUSHL(*(jlong*) (field->u.addr));
- }
- NEXT_INSN;
-
- insn_getstatic_a:
- {
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- PUSHA(*(jobject*) (field->u.addr));
- }
- NEXT_INSN;
-
- insn_putfield_1:
- SAVE_PC;
- {
- jint value = POPI();
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- *(jbyte*) ((char*)obj + field_offset) = value;
- }
- NEXT_INSN;
-
- insn_putfield_2:
- SAVE_PC;
- {
- jint value = POPI();
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- *(jchar*) ((char*)obj + field_offset) = value;
- }
- NEXT_INSN;
-
- insn_putfield_4:
- SAVE_PC;
- {
- jint value = POPI();
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- *(jint*) ((char*)obj + field_offset) = value;
- }
- NEXT_INSN;
-
- insn_putfield_8:
- SAVE_PC;
- {
- jlong value = POPL();
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- *(jlong*) ((char*)obj + field_offset) = value;
- }
- NEXT_INSN;
-
- insn_putfield_a:
- SAVE_PC;
- {
- jobject value = POPA();
- jobject obj = POPA();
- NULLCHECK(obj);
- jint field_offset = get2u (pc); pc += 2;
- *(jobject*) ((char*)obj + field_offset) = value;
- }
- NEXT_INSN;
-
- insn_putstatic_1:
- {
- jint value = POPI();
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- *(jbyte*) (field->u.addr) = value;
- }
- NEXT_INSN;
-
- insn_putstatic_2:
- {
- jint value = POPI();
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- *(jchar*) (field->u.addr) = value;
- }
- NEXT_INSN;
-
- insn_putstatic_4:
- {
- jint value = POPI();
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- *(jint*) (field->u.addr) = value;
- }
- NEXT_INSN;
-
- insn_putstatic_8:
- {
- jlong value = POPL();
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- *(jlong*) (field->u.addr) = value;
- }
- NEXT_INSN;
-
- insn_putstatic_a:
- {
- jobject value = POPA();
- jint fieldref_index = get2u (pc); pc += 2;
- _Jv_Field *field = pool_data[fieldref_index].field;
- *(jobject*) (field->u.addr) = value;
}
NEXT_INSN;
sp -= rmeth->stack_item_count;
- NULLCHECK(sp[0]);
+ NULLCHECK (sp[0].o);
- fun = (void (*) (...))rmeth->method->ncode;
+ fun = (void (*)()) rmeth->method->ncode;
}
goto perform_invoke;
sp -= rmeth->stack_item_count;
_Jv_InitClass (rmeth->klass);
- fun = (void (*) (...))rmeth->method->ncode;
+ fun = (void (*)()) rmeth->method->ncode;
}
goto perform_invoke;
rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
sp -= rmeth->stack_item_count;
- NULLCHECK(sp[0]);
jobject rcv = sp[0].o;
- fun = (void (*) (...))
+ NULLCHECK (rcv);
+
+ fun = (void (*)())
_Jv_LookupInterfaceMethod (rcv->getClass (),
rmeth->method->name,
rmeth->method->signature);
SAVE_PC;
{
jobject value = POPA();
- JvThrow (value);
+ throw static_cast<jthrowable>(value);
}
NEXT_INSN;
if (value != NULL && ! to->isInstance (value))
{
- JvThrow (new java::lang::ClassCastException
- (to->getName()));
+ throw new java::lang::ClassCastException (to->getName());
}
PUSHA (value);
jclass type
= (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
_Jv_InitClass (type);
- jint *sizes = (jint*) alloca (sizeof (jint)*dim);
+ jint *sizes = (jint*) __builtin_alloca (sizeof (jint)*dim);
for (int i = dim - 1; i >= 0; i--)
{
static void
throw_internal_error (char *msg)
{
- JvThrow (new java::lang::InternalError (JvNewStringLatin1 (msg)));
+ throw new java::lang::InternalError (JvNewStringLatin1 (msg));
}
static void
throw_incompatible_class_change_error (jstring msg)
{
- JvThrow (new java::lang::IncompatibleClassChangeError (msg));
+ throw new java::lang::IncompatibleClassChangeError (msg);
}
-#if !HANDLE_SEGV
+#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;
- JvThrow (null_pointer_exc);
+ throw null_pointer_exc;
}
#endif
-#if !HANDLE_FPE
-static java::lang::ArithmeticException *arithmetic_exc;
-static void
-throw_arithmetic_exception ()
-{
- if (arithmetic_exc == NULL)
- arithmetic_exc = new java::lang::ArithmeticException
- (JvNewStringLatin1 ("/ by zero"));
-
- JvThrow (arithmetic_exc);
-}
-#endif
-
-
#endif // INTERPRETER