Commit 715bdd81 by Andrew Haley Committed by Andrew Haley

interpret.cc: Don't include fdlibm.h.

2000-02-10  Andrew Haley  <aph@cygnus.com>

	* interpret.cc: Don't include fdlibm.h.
	Replace #if with #ifdef throughout.
	Declare extern __ieee754_fmod.
	(continue1): Remove op_getfield, op_getstatic, op_putfield,
	op_putstatic insns.
	* resolve.cc (_Jv_PrepareClass): Use imeth as method pointer.
	Search class hierarchy for superclass vtable.

	* java/lang/natClassLoader.cc (_Jv_UnregisterClass): Don't fall
	off the end of a pointer list.

	* java/lang/natThread.cc (stop): Don't abort, throw an exception
	instead.
	(suspend): Ditto.

From-SVN: r31897
parent ae0a06c5
2000-02-10 Andrew Haley <aph@cygnus.com>
* interpret.cc: Don't include fdlibm.h.
Replace #if with #ifdef throughout.
Declare extern __ieee754_fmod.
(continue1): Remove op_getfield, op_getstatic, op_putfield,
op_putstatic insns.
* resolve.cc (_Jv_PrepareClass): Use imeth as method pointer.
Search class hierarchy for superclass vtable.
* java/lang/natClassLoader.cc (_Jv_UnregisterClass): Don't fall
off the end of a pointer list.
* java/lang/natThread.cc (stop): Don't abort, throw an exception
instead.
(suspend): Ditto.
2000-02-09 Tom Tromey <tromey@cygnus.com> 2000-02-09 Tom Tromey <tromey@cygnus.com>
* java/lang/natRuntime.cc (_load): Call add_library. * java/lang/natRuntime.cc (_load): Call add_library.
......
...@@ -17,7 +17,7 @@ details. */ ...@@ -17,7 +17,7 @@ details. */
#include <jvm.h> #include <jvm.h>
#include <java-cpool.h> #include <java-cpool.h>
#include <java-interp.h> #include <java-interp.h>
#include <java/lang/fdlibm.h> // #include <java/lang/fdlibm.h>
#include <java/lang/System.h> #include <java/lang/System.h>
#include <java/lang/String.h> #include <java/lang/String.h>
#include <java/lang/Integer.h> #include <java/lang/Integer.h>
...@@ -56,16 +56,18 @@ static void throw_internal_error (char *msg) ...@@ -56,16 +56,18 @@ static void throw_internal_error (char *msg)
__attribute__ ((__noreturn__)); __attribute__ ((__noreturn__));
static void throw_incompatible_class_change_error (jstring msg) static void throw_incompatible_class_change_error (jstring msg)
__attribute__ ((__noreturn__)); __attribute__ ((__noreturn__));
#if !HANDLE_SEGV #ifndef HANDLE_SEGV
static void throw_null_pointer_exception () static void throw_null_pointer_exception ()
__attribute__ ((__noreturn__)); __attribute__ ((__noreturn__));
#endif #endif
#if !HANDLE_FPE #ifndef HANDLE_FPE
static void throw_arithmetic_exception () static void throw_arithmetic_exception ()
__attribute__ ((__noreturn__)); __attribute__ ((__noreturn__));
#endif #endif
extern "C" double __ieee754_fmod __P((double,double));
static inline void dupx (_Jv_word *sp, int n, int x) static inline void dupx (_Jv_word *sp, int n, int x)
{ {
// first "slide" n+x elements n to the right // first "slide" n+x elements n to the right
...@@ -177,14 +179,14 @@ static jint get4(unsigned char* loc) { ...@@ -177,14 +179,14 @@ static jint get4(unsigned char* loc) {
} }
#if HANDLE_SEGV #ifdef HANDLE_SEGV
#define NULLCHECK(X) #define NULLCHECK(X)
#else #else
#define NULLCHECK(X) \ #define NULLCHECK(X) \
do { if ((X)==NULL) throw_null_pointer_exception (); } while (0) do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
#endif #endif
#if HANDLE_FPE #ifdef HANDLE_FPE
#define ZEROCHECK(X) #define ZEROCHECK(X)
#else #else
#define ZEROCHECK(X) \ #define ZEROCHECK(X) \
...@@ -620,32 +622,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -620,32 +622,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
INSN_LABEL(ifnonnull), INSN_LABEL(ifnonnull),
INSN_LABEL(goto_w), INSN_LABEL(goto_w),
INSN_LABEL(jsr_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 #define SAVE_PC inv->pc = pc-1
...@@ -665,7 +641,9 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -665,7 +641,9 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
#ifdef INLINE_SWITCH #ifdef INLINE_SWITCH
#define NEXT_INSN GOTO_INSN(*pc++) #define NEXT_INSN do { GOTO_INSN(*pc++); } while (0)
NEXT_INSN; NEXT_INSN;
#else #else
...@@ -688,30 +666,10 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -688,30 +666,10 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
LOADI (get1u (pc++)); LOADI (get1u (pc++));
NEXT_INSN; 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 insn_iload_1: // 0x1b
LOADI (1); LOADI (1);
NEXT_INSN; 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 insn_invokevirtual: // 0xb6
SAVE_PC; SAVE_PC;
{ {
...@@ -1973,7 +1931,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -1973,7 +1931,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
insn_getstatic: insn_getstatic:
SAVE_PC; SAVE_PC;
{ {
unsigned char *base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2; jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index); _Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field; _Jv_Field *field = pool_data[fieldref_index].field;
...@@ -1989,38 +1946,34 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -1989,38 +1946,34 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
switch (type->size_in_bytes) switch (type->size_in_bytes)
{ {
case 1: case 1:
*base_pc = op_getstatic_1; PUSHI (*(jbyte*) (field->u.addr));
break;
case 2: case 2:
if (type == JvPrimClass (char)) if (type == JvPrimClass (char))
*base_pc = op_getstatic_2u; PUSHI(*(jchar*) (field->u.addr));
else else
*base_pc = op_getstatic_2s; PUSHI(*(jshort*) (field->u.addr));
break; break;
case 4: case 4:
*base_pc = op_getstatic_4; PUSHI(*(jint*) (field->u.addr));
break; break;
case 8: case 8:
*base_pc = op_getstatic_8; PUSHL(*(jlong*) (field->u.addr));
break; break;
} }
} }
else else
{ {
*base_pc = op_getstatic_a; PUSHA(*(jobject*) (field->u.addr));
} }
pc = base_pc;
} }
NEXT_INSN; NEXT_INSN;
insn_getfield: insn_getfield:
SAVE_PC; SAVE_PC;
{ {
unsigned char *base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2; jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index); _Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field; _Jv_Field *field = pool_data[fieldref_index].field;
...@@ -2030,50 +1983,47 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -2030,50 +1983,47 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
(JvNewStringLatin1 ("field is static")); (JvNewStringLatin1 ("field is static"));
jclass type = field->type; jclass type = field->type;
jint field_offset = field->u.boffset;
if (field_offset > 0xffff)
JvThrow (new java::lang::VirtualMachineError);
jobject obj = POPA();
NULLCHECK(obj);
if (type->isPrimitive ()) if (type->isPrimitive ())
{ {
switch (type->size_in_bytes) switch (type->size_in_bytes)
{ {
case 1: case 1:
*base_pc = op_getfield_1; PUSHI (*(jbyte*) ((char*)obj + field_offset));
break; break;
case 2: case 2:
if (type == JvPrimClass (char)) if (type == JvPrimClass (char))
*base_pc = op_getfield_2u; PUSHI (*(jchar*) ((char*)obj + field_offset));
else else
*base_pc = op_getfield_2s; PUSHI (*(jshort*) ((char*)obj + field_offset));
break; break;
case 4: case 4:
*base_pc = op_getfield_4; PUSHI (*(jint*) ((char*)obj + field_offset));
break; break;
case 8: case 8:
*base_pc = op_getfield_8; PUSHL(*(jlong*) ((char*)obj + field_offset));
break; break;
} }
} }
else 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; NEXT_INSN;
insn_putstatic: insn_putstatic:
SAVE_PC; SAVE_PC;
{ {
unsigned char* base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2; jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index); _Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field; _Jv_Field *field = pool_data[fieldref_index].field;
...@@ -2085,37 +2035,44 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -2085,37 +2035,44 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
throw_incompatible_class_change_error throw_incompatible_class_change_error
(JvNewStringLatin1 ("field no longer static")); (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 ()) if (type->isPrimitive ())
{ {
switch (type->size_in_bytes) switch (type->size_in_bytes)
{ {
case 1: case 1:
*base_pc = op_putstatic_1; {
break; jint value = POPI();
*(jbyte*) (field->u.addr) = value;
break;
}
case 2: case 2:
*base_pc = op_putstatic_2; {
break; jint value = POPI();
*(jchar*) (field->u.addr) = value;
break;
}
case 4: case 4:
*base_pc = op_putstatic_4; {
break; jint value = POPI();
*(jint*) (field->u.addr) = value;
break;
}
case 8: case 8:
*base_pc = op_putstatic_8; {
break; jlong value = POPL();
*(jlong*) (field->u.addr) = value;
break;
}
} }
} }
else else
{ {
*base_pc = op_putstatic_a; jobject value = POPA();
*(jobject*) (field->u.addr) = value;
} }
// do the instruction again!
pc = base_pc;
} }
NEXT_INSN; NEXT_INSN;
...@@ -2123,7 +2080,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -2123,7 +2080,6 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
insn_putfield: insn_putfield:
SAVE_PC; SAVE_PC;
{ {
unsigned char* base_pc = pc-1;
jint fieldref_index = get2u (pc); pc += 2; jint fieldref_index = get2u (pc); pc += 2;
_Jv_ResolvePoolEntry (defining_class, fieldref_index); _Jv_ResolvePoolEntry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field; _Jv_Field *field = pool_data[fieldref_index].field;
...@@ -2134,229 +2090,58 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv) ...@@ -2134,229 +2090,58 @@ void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
throw_incompatible_class_change_error throw_incompatible_class_change_error
(JvNewStringLatin1 ("field is static")); (JvNewStringLatin1 ("field is static"));
jint field_offset = field->u.boffset;
if (field_offset > 0xffff)
JvThrow (new java::lang::VirtualMachineError);
if (type->isPrimitive ()) if (type->isPrimitive ())
{ {
switch (type->size_in_bytes) switch (type->size_in_bytes)
{ {
case 1: 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: 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: 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: case 8:
*base_pc = op_putfield_8; {
break; jlong value = POPL();
jobject obj = POPA();
NULLCHECK(obj);
*(jlong*) ((char*)obj + field_offset) = value;
break;
}
} }
} }
else 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; NEXT_INSN;
...@@ -2641,7 +2426,7 @@ throw_incompatible_class_change_error (jstring msg) ...@@ -2641,7 +2426,7 @@ throw_incompatible_class_change_error (jstring msg)
JvThrow (new java::lang::IncompatibleClassChangeError (msg)); JvThrow (new java::lang::IncompatibleClassChangeError (msg));
} }
#if !HANDLE_SEGV #ifndef HANDLE_SEGV
static java::lang::NullPointerException *null_pointer_exc; static java::lang::NullPointerException *null_pointer_exc;
static void static void
throw_null_pointer_exception () throw_null_pointer_exception ()
...@@ -2653,7 +2438,7 @@ throw_null_pointer_exception () ...@@ -2653,7 +2438,7 @@ throw_null_pointer_exception ()
} }
#endif #endif
#if !HANDLE_FPE #ifndef HANDLE_FPE
static java::lang::ArithmeticException *arithmetic_exc; static java::lang::ArithmeticException *arithmetic_exc;
static void static void
throw_arithmetic_exception () throw_arithmetic_exception ()
......
...@@ -368,12 +368,15 @@ _Jv_UnregisterClass (jclass the_class) ...@@ -368,12 +368,15 @@ _Jv_UnregisterClass (jclass the_class)
} }
_Jv_LoaderInfo **info = &(initiated_classes[hash]); _Jv_LoaderInfo **info = &(initiated_classes[hash]);
for ( ; *info; info = &((*info)->next)) for ( ; ; info = &((*info)->next))
{ {
while ((*info)->klass == the_class) while (*info && (*info)->klass == the_class)
{ {
*info = (*info)->next; *info = (*info)->next;
} }
if (*info == NULL)
break;
} }
_Jv_MonitorExit (&ClassClass); _Jv_MonitorExit (&ClassClass);
......
...@@ -19,6 +19,7 @@ details. */ ...@@ -19,6 +19,7 @@ details. */
#include <java/lang/Thread.h> #include <java/lang/Thread.h>
#include <java/lang/ThreadGroup.h> #include <java/lang/ThreadGroup.h>
#include <java/lang/IllegalArgumentException.h> #include <java/lang/IllegalArgumentException.h>
#include <java/lang/UnsupportedOperationException.h>
#include <java/lang/IllegalThreadStateException.h> #include <java/lang/IllegalThreadStateException.h>
#include <java/lang/InterruptedException.h> #include <java/lang/InterruptedException.h>
#include <java/lang/NullPointerException.h> #include <java/lang/NullPointerException.h>
...@@ -306,14 +307,16 @@ java::lang::Thread::start (void) ...@@ -306,14 +307,16 @@ java::lang::Thread::start (void)
void void
java::lang::Thread::stop (java::lang::Throwable *) java::lang::Thread::stop (java::lang::Throwable *)
{ {
JvFail ("java::lang::Thread::stop unimplemented"); _Jv_Throw (new UnsupportedOperationException
(JvNewStringLatin1 ("java::lang::Thread::stop unimplemented")));
} }
void void
java::lang::Thread::suspend (void) java::lang::Thread::suspend (void)
{ {
checkAccess (); checkAccess ();
JvFail ("java::lang::Thread::suspend unimplemented"); _Jv_Throw (new UnsupportedOperationException
(JvNewStringLatin1 ("java::lang::Thread::suspend unimplemented")));
} }
void void
......
...@@ -576,7 +576,7 @@ _Jv_PrepareClass(jclass klass) ...@@ -576,7 +576,7 @@ _Jv_PrepareClass(jclass klass)
} }
else if (imeth != 0) // it could be abstract else if (imeth != 0) // it could be abstract
{ {
_Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (im); _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
clz->methods[i].ncode = im->ncode (); clz->methods[i].ncode = im->ncode ();
} }
} }
...@@ -650,10 +650,20 @@ _Jv_PrepareClass(jclass klass) ...@@ -650,10 +650,20 @@ _Jv_PrepareClass(jclass klass)
+ (sizeof (void*) * (vtable_count))); + (sizeof (void*) * (vtable_count)));
vtable->clas = clz; vtable->clas = clz;
/* copy super class' vtable entries (index 0 goes unused). */ {
memcpy ((void*)&vtable->method[1], jclass effective_superclass = super_class;
(void*)&super_class->vtable->method[1],
sizeof (void*) * super_class->vtable_method_count); /* If super_class is abstract or an interface it has no vtable.
We need to find a real one... */
while (effective_superclass && effective_superclass->vtable == NULL)
effective_superclass = effective_superclass->superclass;
/* copy super class' vtable entries (index 0 goes unused). */
if (effective_superclass && effective_superclass->vtable)
memcpy ((void*)&vtable->method[1],
(void*)&effective_superclass->vtable->method[1],
sizeof (void*) * effective_superclass->vtable_method_count);
}
/* now, install our own vtable entries, reprise... */ /* now, install our own vtable entries, reprise... */
for (int i = 0; i < clz->method_count; i++) for (int i = 0; i < clz->method_count; i++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment