+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.
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 ()
_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()));
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,
{
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;
+ }
}
}