Patch: FYI: PR 7073

Tom Tromey tromey@redhat.com
Thu Jun 20 08:28:00 GMT 2002


I'm checking this in.

This fixes the main part of PR 7073.  There is already a patch pending
for the other part of the PR.

It turns out we need a small special case for interfaces when building
a new class at runtime.

Tested in x86 Linux; no regressions on the test suite.
In fact this code probably doesn't get tested at all :-(
(Andrew, we need your interpreter-testing patch)

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	For PR libgcj/7073:
	* resolve.cc (_Jv_PrepareClass): Only resolve superclass if it
	exists.
	* defineclass.cc (handleClassBegin): Superclass for interface is
	`null'.

Index: defineclass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/defineclass.cc,v
retrieving revision 1.27
diff -u -r1.27 defineclass.cc
--- defineclass.cc 10 Dec 2001 01:18:30 -0000 1.27
+++ defineclass.cc 20 Jun 2002 15:06:48 -0000
@@ -1,6 +1,6 @@
 // defineclass.cc - defining a class from .class format.
 
-/* Copyright (C) 1999, 2000, 2001  Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -895,20 +895,11 @@
   pool_data[this_class].clazz = def;
   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
 
-  if (super_class == 0)
+  if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
     {
-      // interfaces have java.lang.Object as super.
-      if (access_flags & Modifier::INTERFACE)
-	{
-	  def->superclass = (jclass)&java::lang::Object::class$;
-	}
-
       // FIXME: Consider this carefully!  
-      else if (!_Jv_equalUtf8Consts (def->name,
-				     java::lang::Object::class$.name))
-	{
-	  throw_no_class_def_found_error ("loading java.lang.Object");
-	}
+      if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
+	throw_no_class_def_found_error ("loading java.lang.Object");
     }
 
   // In the pre-loading state, it can be looked up in the
@@ -924,25 +915,30 @@
 
   if (super_class != 0)
     {
-      // load the super class
+      // Load the superclass.
       check_tag (super_class, JV_CONSTANT_Class);
       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
 
-      // load the super class using our defining loader
+      // Load the superclass using our defining loader.
       jclass the_super = _Jv_FindClass (super_name,
 					def->loader);
 
       // This will establish that we are allowed to be a subclass,
-      // and check for class circularity error
+      // and check for class circularity error.
       checkExtends (def, the_super);
 
-      def->superclass = the_super;
+      // Note: for an interface we will find Object as the
+      // superclass.  We still check it above to ensure class file
+      // validity, but we simply assign `null' to the actual field in
+      // this case.
+      def->superclass = (((access_flags & Modifier::INTERFACE))
+			 ? NULL : the_super);
       pool_data[super_class].clazz = the_super;
       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
     }
 
-  // now we've come past the circularity problem, we can 
-  // now say that we're loading...
+  // Now we've come past the circularity problem, we can 
+  // now say that we're loading.
 
   def->state = JV_STATE_LOADING;
   def->notifyAll ();
Index: resolve.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/resolve.cc,v
retrieving revision 1.28
diff -u -r1.28 resolve.cc
--- resolve.cc 8 Jan 2002 20:51:45 -0000 1.28
+++ resolve.cc 20 Jun 2002 15:06:49 -0000
@@ -516,11 +516,14 @@
   if (klass->state >= JV_STATE_PREPARED)
     return;
 
-  // make sure super-class is linked.  This involves taking a lock on
-  // the super class, so we use the Java method resolveClass, which will
-  // unlock it properly, should an exception happen.
+  // Make sure super-class is linked.  This involves taking a lock on
+  // the super class, so we use the Java method resolveClass, which
+  // will unlock it properly, should an exception happen.  If there's
+  // no superclass, do nothing -- Object will already have been
+  // resolved.
 
-  java::lang::ClassLoader::resolveClass0 (klass->superclass);
+  if (klass->superclass)
+    java::lang::ClassLoader::resolveClass0 (klass->superclass);
 
   _Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
 
@@ -529,8 +532,12 @@
   int instance_size;
   int static_size;
 
-  // java.lang.Object is never interpreted!
-  instance_size = clz->superclass->size ();
+  // Although java.lang.Object is never interpreted, an interface can
+  // have a null superclass.
+  if (clz->superclass)
+    instance_size = clz->superclass->size();
+  else
+    instance_size = java::lang::Object::class$.size();
   static_size   = 0;
 
   for (int i = 0; i < clz->field_count; i++)
@@ -646,9 +653,6 @@
 
   jclass super_class = clz->getSuperclass ();
 
-  if (super_class == 0)
-    throw_internal_error ("cannot handle interpreted base classes");
-
   for (int i = 0; i < clz->method_count; i++)
     {
       _Jv_Method *this_meth = &clz->methods[i];
@@ -707,6 +711,10 @@
        We need to find a real one... */
     while (effective_superclass && effective_superclass->vtable == NULL)
       effective_superclass = effective_superclass->superclass;
+
+    /* If we ended up without a superclass, use Object.  */
+    if (! effective_superclass)
+      effective_superclass = &java::lang::Object::class$;
 
     /* copy super class' vtable entries. */
     if (effective_superclass && effective_superclass->vtable)



More information about the Java-patches mailing list