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