Patch: FYI: AbstractMethodError -vs- linking

Tom Tromey tromey@redhat.com
Sat Feb 19 09:23:00 GMT 2005


I'm checking this in.

Today I ran across this:

http://java.sun.com/docs/books/vmspec/2nd-edition/html/ChangesAppendix.doc.html

We aren't supposed to raise an AbstractMethodError during class
preparation.  This patch removes this.  This is good for us since
jonas and OOo and probably other applications were having trouble in
this area due to our w3c upgrade.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* link.cc (make_vtable): Remove abstract method check.
	(append_partial_itable): Likewise.

Index: link.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/link.cc,v
retrieving revision 1.9
diff -u -r1.9 link.cc
--- link.cc 19 Feb 2005 01:16:28 -0000 1.9
+++ link.cc 19 Feb 2005 04:02:47 -0000
@@ -700,6 +700,13 @@
   throw new java::lang::NoSuchMethodError;
 }
 
+// This is put in empty vtable slots.
+static void
+_Jv_abstractMethodError (void)
+{
+  throw new java::lang::AbstractMethodError();
+}
+
 // Each superinterface of a class (i.e. each interface that the class
 // directly or indirectly implements) has a corresponding "Partial
 // Interface Dispatch Table" whose size is (number of methods + 1) words.
@@ -742,14 +749,14 @@
 	  if ((meth->accflags & Modifier::STATIC) != 0)
 	    throw new java::lang::IncompatibleClassChangeError
 	      (_Jv_GetMethodString (klass, meth));
-	  if ((meth->accflags & Modifier::ABSTRACT) != 0)
-	    throw new java::lang::AbstractMethodError
-	      (_Jv_GetMethodString (klass, meth));
 	  if ((meth->accflags & Modifier::PUBLIC) == 0)
 	    throw new java::lang::IllegalAccessError
 	      (_Jv_GetMethodString (klass, meth));
 
-	  itable[pos] = meth->ncode;
+ 	  if ((meth->accflags & Modifier::ABSTRACT) != 0)
+	    itable[pos] = (void *) &_Jv_abstractMethodError;
+	  else
+	    itable[pos] = meth->ncode;
 	}
       else
         {
@@ -1113,13 +1120,6 @@
   self->catch_classes->classname = (_Jv_Utf8Const *)-1;
 }
   
-// This is put in empty vtable slots.
-static void
-_Jv_abstractMethodError (void)
-{
-  throw new java::lang::AbstractMethodError();
-}
-
 // Set itable method indexes for members of interface IFACE.
 void
 _Jv_Linker::layout_interface_methods (jclass iface)
@@ -1211,6 +1211,8 @@
       if (meth->index == (_Jv_ushort) -1)
 	continue;
       if ((meth->accflags & Modifier::ABSTRACT))
+	// FIXME: it might be nice to have a libffi trampoline here,
+	// so we could pass in the method name and other information.
 	vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError);
       else
 	vtable->set_method(meth->index, meth->ncode);
@@ -1259,30 +1261,9 @@
   // override an old one.
   set_vtable_entries (klass, vtable);
 
-  // It is an error to have an abstract method in a concrete class.
-  if (! (klass->accflags & Modifier::ABSTRACT))
-    {
-      for (int i = 0; i < klass->vtable_method_count; ++i)
-	if (vtable->get_method(i) == (void *) &_Jv_abstractMethodError)
-	  {
-	    using namespace java::lang;
-	    jclass orig = klass;
-	    while (klass != NULL)
-	      {
-		for (int j = 0; j < klass->method_count; ++j)
-		  {
-		    if (klass->methods[j].index == i)
-		      throw new AbstractMethodError(_Jv_GetMethodString(klass,
-									&klass->methods[j],
-									orig));
-		  }
-		klass = klass->getSuperclass ();
-	      }
-	    // Couldn't find the name, which is weird.
-	    // But we still must throw the error.
-	    throw new AbstractMethodError ();
-	  }
-    }
+  // Note that we don't check for abstract methods here.  We used to,
+  // but there is a JVMS clarification that indicates that a check
+  // here would be too eager.  And, a simple test case confirms this.
 }
 
 // Lay out the class, allocating space for static fields and computing



More information about the Java-patches mailing list