OSDN Git Service

2005-12-08 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Dec 2005 14:19:13 +0000 (14:19 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Dec 2005 14:19:13 +0000 (14:19 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108231 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/include/jvm.h
libjava/java/lang/Object.h
libjava/java/lang/Object.java
libjava/link.cc

index c920ffe..57f1d4d 100644 (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.
index 8d34059..85caa40 100644 (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, ...)
index bf68a72..54fd447 100644 (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__ */
index dbe3411..e81a48a 100644 (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.
 }
index 2d6b199..7070d72 100644 (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;
+         }
       }
     }