Object.h (throwNoSuchMethodError): New method.

2005-12-08  Andrew Haley  <aph@redhat.com>

        * java/lang/Object.h (throwNoSuchMethodError): New method.
        * java/lang/Object.java (throwNoSuchMethodError): New method.
        * include/jvm.h (_Jv_ThrowNoSuchFieldError): Declare.
        * link.cc (_Jv_ThrowNoSuchFieldError): New.
        (link_symbol_table): Don't throw a NoSuchFieldError if a field is
        missing.  Instead, set the otable entry to zero.
        (link_symbol_table): If we don't find a nonstatic method, insert
        the vtable offset of Object.throwNoSuchMethodError() into the
        otable.

From-SVN: r108231
This commit is contained in:
Andrew Haley 2005-12-08 14:19:13 +00:00 committed by Andrew Haley
parent e00388458d
commit 9edd0f5e69
5 changed files with 85 additions and 18 deletions

View File

@ -1,3 +1,15 @@
2005-12-08 Andrew Haley <aph@redhat.com>
* java/lang/Object.h (throwNoSuchMethodError): New method.
* java/lang/Object.java (throwNoSuchMethodError): New method.
* include/jvm.h (_Jv_ThrowNoSuchFieldError): Declare.
* link.cc (_Jv_ThrowNoSuchFieldError): New.
(link_symbol_table): Don't throw a NoSuchFieldError if a field is
missing. Instead, set the otable entry to zero.
(link_symbol_table): If we don't find a nonstatic method, insert
the vtable offset of Object.throwNoSuchMethodError() into the
otable.
2005-12-05 Tom Tromey <tromey@redhat.com>
* testsuite/libjava.compile/rh174912.java: New file.

View File

@ -442,6 +442,10 @@ extern "C" void _Jv_ThrowBadArrayIndex (jint bad_index)
__attribute__((noreturn));
extern "C" void _Jv_ThrowNullPointerException (void)
__attribute__((noreturn));
extern "C" void _Jv_ThrowNoSuchMethodError (void)
__attribute__((noreturn));
extern "C" void _Jv_ThrowNoSuchFieldError (int)
__attribute__((noreturn));
extern "C" jobject _Jv_NewArray (jint type, jint size)
__attribute__((__malloc__));
extern "C" jobject _Jv_NewMultiArray (jclass klass, jint dims, ...)

View File

@ -83,6 +83,9 @@ private:
// Initialize the sync_info field. Not called with JV_HASH_SYNCHRONIZATION.
void sync_init (void);
public:
virtual void throwNoSuchMethodError (void);
};
#endif /* __JAVA_LANG_OBJECT_H__ */

View File

@ -506,6 +506,14 @@ public class Object
// completeness (some day we'll be able to auto-generate Object.h).
private final native void sync_init();
// If we fail to find a method at class loading time we put the
// vtable index of this method in its place: any attempt to call
// that method will result in an error.
void throwNoSuchMethodError()
{
throw new NoSuchMethodError("in " + getClass());
}
// Note that we don't mention the sync_info field here. If we do,
// jc1 will not work correctly.
}

View File

@ -713,6 +713,17 @@ _Jv_ThrowNoSuchMethodError ()
throw new java::lang::NoSuchMethodError;
}
// Throw a NoSuchFieldError. Called by compiler-generated code when
// an otable entry is zero. OTABLE_INDEX is the index in the caller's
// otable that refers to the missing field. This index may be used to
// print diagnostic information about the field.
void
_Jv_ThrowNoSuchFieldError (int /* otable_index */)
{
throw new java::lang::NoSuchFieldError;
}
// This is put in empty vtable slots.
void
_Jv_ThrowAbstractMethodError ()
@ -915,12 +926,6 @@ _Jv_Linker::link_symbol_table (jclass klass)
_Jv_Utf8Const *signature = sym.signature;
{
static char *bounce = (char *)_Jv_ThrowNoSuchMethodError;
ptrdiff_t offset = (char *)(klass->vtable) - bounce;
klass->otable->offsets[index] = offset;
}
if (target_class == NULL)
throw new java::lang::NoClassDefFoundError
(_Jv_NewStringUTF (sym.class_name->chars()));
@ -948,14 +953,41 @@ _Jv_Linker::link_symbol_table (jclass klass)
meth = _Jv_LookupDeclaredMethod(target_class, sym.name,
sym.signature);
if (meth != NULL)
// Every class has a throwNoSuchMethodErrorIndex method that
// it inherits from java.lang.Object. Find its vtable
// offset.
static int throwNoSuchMethodErrorIndex;
if (throwNoSuchMethodErrorIndex == 0)
{
int offset = _Jv_VTable::idx_to_offset (meth->index);
if (offset == -1)
JvFail ("Bad method index");
JvAssert (meth->index < target_class->vtable_method_count);
klass->otable->offsets[index] = offset;
Utf8Const* name
= _Jv_makeUtf8Const ("throwNoSuchMethodError",
strlen ("throwNoSuchMethodError"));
_Jv_Method* meth
= _Jv_LookupDeclaredMethod (&java::lang::Object::class$,
name, gcj::void_signature);
throwNoSuchMethodErrorIndex
= _Jv_VTable::idx_to_offset (meth->index);
}
// If we don't find a nonstatic method, insert the
// vtable index of Object.throwNoSuchMethodError().
// This defers the missing method error until an attempt
// is made to execute it.
{
int offset;
if (meth != NULL)
offset = _Jv_VTable::idx_to_offset (meth->index);
else
offset = throwNoSuchMethodErrorIndex;
if (offset == -1)
JvFail ("Bad method index");
JvAssert (meth->index < target_class->vtable_method_count);
klass->otable->offsets[index] = offset;
}
if (debug_link)
fprintf (stderr, " offsets[%d] = %d (class %s@%p : %s(%s))\n",
(int)index,
@ -971,12 +1003,20 @@ _Jv_Linker::link_symbol_table (jclass klass)
{
wait_for_state(target_class, JV_STATE_PREPARED);
jclass found_class;
_Jv_Field *the_field = find_field (klass, target_class, &found_class,
sym.name, sym.signature);
if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
throw new java::lang::IncompatibleClassChangeError;
else
klass->otable->offsets[index] = the_field->u.boffset;
_Jv_Field *the_field = NULL;
try
{
the_field = find_field (klass, target_class, &found_class,
sym.name, sym.signature);
if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
throw new java::lang::IncompatibleClassChangeError;
else
klass->otable->offsets[index] = the_field->u.boffset;
}
catch (java::lang::NoSuchFieldError *err)
{
klass->otable->offsets[index] = 0;
}
}
}