aboutsummaryrefslogtreecommitdiff
path: root/libjava/link.cc
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2005-12-08 14:19:13 +0000
committerAndrew Haley <aph@gcc.gnu.org>2005-12-08 14:19:13 +0000
commit9edd0f5e69ca58b69405b4422907c07abdcc5a7e (patch)
treee764f1b2a5c7d9e67d1a6fc89048373154d65bc7 /libjava/link.cc
parente00388458d34ab0954df5d12c9d45ee0fd794e58 (diff)
downloadgcc-9edd0f5e69ca58b69405b4422907c07abdcc5a7e.zip
gcc-9edd0f5e69ca58b69405b4422907c07abdcc5a7e.tar.gz
gcc-9edd0f5e69ca58b69405b4422907c07abdcc5a7e.tar.bz2
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
Diffstat (limited to 'libjava/link.cc')
-rw-r--r--libjava/link.cc76
1 files changed, 58 insertions, 18 deletions
diff --git a/libjava/link.cc b/libjava/link.cc
index 2d6b199..7070d72 100644
--- a/libjava/link.cc
+++ b/libjava/link.cc
@@ -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;
+ }
}
}