Commit a1aba4f9 by Tom Tromey Committed by Tom Tromey

natClassLoader.cc (defineClass0): Removed erroneous comment.

	* java/lang/natClassLoader.cc (defineClass0): Removed erroneous
	comment.
	* java/lang/ClassLoader.java (defineClass): Use chained
	exception when rethrowing.
	* defineclass.cc (handleClassBegin): Mark class as interpreted.
	* java/lang/reflect/Modifier.java (INVISIBLE, INTERPRETED): New
	constants.
	* resolve.cc (_Jv_PrepareMissingMethods): New function.
	(_Jv_PrepareClass): Use it.
	* include/java-interp.h (_Jv_IsInterpretedClass): Rewrote.
	(_Jv_InterpClass): _Jv_PrepareMissingMethods now friend.
	* java/lang/Class.h (Class::getModifiers): Mask with ALL_FLAGS.
	(Class): _Jv_PrepareMissingMethods now friend.
	* java/lang/natClassLoader.cc (defineClass0): Use JvSynchronize.
	Record `NULL' for system class loader.
	(_Jv_RegisterInitiatingLoader): Use JvSynchronize.  Special case
	system class loader.
	(_Jv_FindClassInCache): Likewise.
	(_Jv_UnregisterClass): Use JvSynchronize.  Free old loader info.
	(_Jv_FindClass): Special case system class loader.
	* java/lang/natClass.cc (_Jv_abstractMethodError): New function.
	(_Jv_SetVTableEntries): Put _Jv_abstractMethodError into empty
	vtable slots.
	(_Jv_LayoutVTableMethods): Don't generate vtable slot for a method
	in a final class.
	(_getDeclaredMethod): Don't return synthetic methods.
	(getDeclaredMethods): Likewise.
	(_getMethod): Likewise.
	(_getMethods): Likewise.

From-SVN: r60319
parent 38540594
2002-12-19 Tom Tromey <tromey@redhat.com>
* java/lang/natClassLoader.cc (defineClass0): Removed erroneous
comment.
* java/lang/ClassLoader.java (defineClass): Use chained
exception when rethrowing.
* defineclass.cc (handleClassBegin): Mark class as interpreted.
* java/lang/reflect/Modifier.java (INVISIBLE, INTERPRETED): New
constants.
* resolve.cc (_Jv_PrepareMissingMethods): New function.
(_Jv_PrepareClass): Use it.
* include/java-interp.h (_Jv_IsInterpretedClass): Rewrote.
(_Jv_InterpClass): _Jv_PrepareMissingMethods now friend.
* java/lang/Class.h (Class::getModifiers): Mask with ALL_FLAGS.
(Class): _Jv_PrepareMissingMethods now friend.
* java/lang/natClassLoader.cc (defineClass0): Use JvSynchronize.
Record `NULL' for system class loader.
(_Jv_RegisterInitiatingLoader): Use JvSynchronize. Special case
system class loader.
(_Jv_FindClassInCache): Likewise.
(_Jv_UnregisterClass): Use JvSynchronize. Free old loader info.
(_Jv_FindClass): Special case system class loader.
* java/lang/natClass.cc (_Jv_abstractMethodError): New function.
(_Jv_SetVTableEntries): Put _Jv_abstractMethodError into empty
vtable slots.
(_Jv_LayoutVTableMethods): Don't generate vtable slot for a method
in a final class.
(_getDeclaredMethod): Don't return synthetic methods.
(getDeclaredMethods): Likewise.
(_getMethod): Likewise.
(_getMethods): Likewise.
2002-12-18 Raif Naffah <raif@fl.net.au> 2002-12-18 Raif Naffah <raif@fl.net.au>
* java/math/BigInteger.java (euclidInv): Make sure quot and rem are in * java/math/BigInteger.java (euclidInv): Make sure quot and rem are in
......
...@@ -890,7 +890,7 @@ _Jv_ClassReader::handleClassBegin ...@@ -890,7 +890,7 @@ _Jv_ClassReader::handleClassBegin
throw_no_class_def_found_error (msg); throw_no_class_def_found_error (msg);
} }
def->accflags = access_flags; def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
pool_data[this_class].clazz = def; pool_data[this_class].clazz = def;
pool_tags[this_class] = JV_CONSTANT_ResolvedClass; pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
......
...@@ -21,6 +21,7 @@ details. */ ...@@ -21,6 +21,7 @@ details. */
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <java/lang/ClassLoader.h> #include <java/lang/ClassLoader.h>
#include <java/lang/reflect/Modifier.h>
#include <gnu/gcj/runtime/StackTrace.h> #include <gnu/gcj/runtime/StackTrace.h>
extern "C" { extern "C" {
...@@ -30,7 +31,7 @@ extern "C" { ...@@ -30,7 +31,7 @@ extern "C" {
extern inline jboolean extern inline jboolean
_Jv_IsInterpretedClass (jclass c) _Jv_IsInterpretedClass (jclass c)
{ {
return (c->loader != 0); return (c->accflags & java::lang::reflect::Modifier::INTERPRETED) != 0;
} }
struct _Jv_ResolvedMethod; struct _Jv_ResolvedMethod;
...@@ -158,6 +159,7 @@ class _Jv_InterpClass : public java::lang::Class ...@@ -158,6 +159,7 @@ class _Jv_InterpClass : public java::lang::Class
friend class _Jv_ClassReader; friend class _Jv_ClassReader;
friend class _Jv_InterpMethod; friend class _Jv_InterpMethod;
friend void _Jv_PrepareClass(jclass); friend void _Jv_PrepareClass(jclass);
friend void _Jv_PrepareMissingMethods (jclass base2, jclass iface_class);
friend void _Jv_InitField (jobject, jclass, int); friend void _Jv_InitField (jobject, jclass, int);
#ifdef JV_MARKOBJ_DECL #ifdef JV_MARKOBJ_DECL
friend JV_MARKOBJ_DECL; friend JV_MARKOBJ_DECL;
......
...@@ -182,9 +182,9 @@ public: ...@@ -182,9 +182,9 @@ public:
JArray<java::lang::reflect::Method *> *getMethods (void); JArray<java::lang::reflect::Method *> *getMethods (void);
inline jint getModifiers (void) inline jint getModifiers (void)
{ {
return accflags; return accflags & java::lang::reflect::Modifier::ALL_FLAGS;
} }
jstring getName (void); jstring getName (void);
...@@ -348,6 +348,7 @@ private: ...@@ -348,6 +348,7 @@ private:
_Jv_Utf8Const *method_signature); _Jv_Utf8Const *method_signature);
friend void _Jv_PrepareClass (jclass); friend void _Jv_PrepareClass (jclass);
friend void _Jv_PrepareMissingMethods (jclass base, jclass iface_class);
friend class _Jv_ClassReader; friend class _Jv_ClassReader;
friend class _Jv_InterpClass; friend class _Jv_InterpClass;
......
...@@ -468,17 +468,18 @@ public abstract class ClassLoader ...@@ -468,17 +468,18 @@ public abstract class ClassLoader
{ {
throw x; // rethrow throw x; // rethrow
} }
catch (java.lang.VirtualMachineError x) catch (VirtualMachineError x)
{ {
throw x; // rethrow throw x; // rethrow
} }
catch (java.lang.Throwable x) catch (Throwable x)
{ {
// This should never happen, or we are beyond spec. // This should never happen, or we are beyond spec.
throw new InternalError ("Unexpected exception " InternalError r = new InternalError ("Unexpected exception "
+ "while defining class " + "while defining class "
+ name + ": " + name);
+ x.toString ()); r.initCause(x);
throw r;
} }
} }
......
...@@ -343,7 +343,9 @@ java::lang::Class::_getDeclaredMethod (jstring name, ...@@ -343,7 +343,9 @@ java::lang::Class::_getDeclaredMethod (jstring name,
while (--i >= 0) while (--i >= 0)
{ {
if (_Jv_equalUtf8Consts (methods[i].name, utf_name) if (_Jv_equalUtf8Consts (methods[i].name, utf_name)
&& _Jv_equaln (methods[i].signature, partial_sig, p_len)) && _Jv_equaln (methods[i].signature, partial_sig, p_len)
&& (methods[i].accflags
& java::lang::reflect::Modifier::INVISIBLE) == 0)
{ {
// Found it. // Found it.
using namespace java::lang::reflect; using namespace java::lang::reflect;
...@@ -368,7 +370,9 @@ java::lang::Class::getDeclaredMethods (void) ...@@ -368,7 +370,9 @@ java::lang::Class::getDeclaredMethods (void)
if (method->name == NULL if (method->name == NULL
|| _Jv_equalUtf8Consts (method->name, clinit_name) || _Jv_equalUtf8Consts (method->name, clinit_name)
|| _Jv_equalUtf8Consts (method->name, init_name) || _Jv_equalUtf8Consts (method->name, init_name)
|| _Jv_equalUtf8Consts (method->name, finit_name)) || _Jv_equalUtf8Consts (method->name, finit_name)
|| (methods[i].accflags
& java::lang::reflect::Modifier::INVISIBLE) != 0)
continue; continue;
numMethods++; numMethods++;
} }
...@@ -382,7 +386,9 @@ java::lang::Class::getDeclaredMethods (void) ...@@ -382,7 +386,9 @@ java::lang::Class::getDeclaredMethods (void)
if (method->name == NULL if (method->name == NULL
|| _Jv_equalUtf8Consts (method->name, clinit_name) || _Jv_equalUtf8Consts (method->name, clinit_name)
|| _Jv_equalUtf8Consts (method->name, init_name) || _Jv_equalUtf8Consts (method->name, init_name)
|| _Jv_equalUtf8Consts (method->name, finit_name)) || _Jv_equalUtf8Consts (method->name, finit_name)
|| (methods[i].accflags
& java::lang::reflect::Modifier::INVISIBLE) != 0)
continue; continue;
java::lang::reflect::Method* rmethod java::lang::reflect::Method* rmethod
= new java::lang::reflect::Method (); = new java::lang::reflect::Method ();
...@@ -514,7 +520,9 @@ java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types) ...@@ -514,7 +520,9 @@ java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
{ {
// FIXME: access checks. // FIXME: access checks.
if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name) if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
&& _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)) && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)
&& (klass->methods[i].accflags
& java::lang::reflect::Modifier::INVISIBLE) == 0)
{ {
// Found it. // Found it.
using namespace java::lang::reflect; using namespace java::lang::reflect;
...@@ -565,7 +573,9 @@ java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result, ...@@ -565,7 +573,9 @@ java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
if (method->name == NULL if (method->name == NULL
|| _Jv_equalUtf8Consts (method->name, clinit_name) || _Jv_equalUtf8Consts (method->name, clinit_name)
|| _Jv_equalUtf8Consts (method->name, init_name) || _Jv_equalUtf8Consts (method->name, init_name)
|| _Jv_equalUtf8Consts (method->name, finit_name)) || _Jv_equalUtf8Consts (method->name, finit_name)
|| (method->accflags
& java::lang::reflect::Modifier::INVISIBLE) != 0)
continue; continue;
// Only want public methods. // Only want public methods.
if (! java::lang::reflect::Modifier::isPublic (method->accflags)) if (! java::lang::reflect::Modifier::isPublic (method->accflags))
...@@ -1564,6 +1574,13 @@ isVirtualMethod (_Jv_Method *meth) ...@@ -1564,6 +1574,13 @@ isVirtualMethod (_Jv_Method *meth)
&& meth->name->data[0] != '<'); && meth->name->data[0] != '<');
} }
// This is put in empty vtable slots.
static void
_Jv_abstractMethodError (void)
{
throw new java::lang::AbstractMethodError();
}
// Prepare virtual method declarations in KLASS, and any superclasses as // Prepare virtual method declarations in KLASS, and any superclasses as
// required, by determining their vtable index, setting method->index, and // required, by determining their vtable index, setting method->index, and
// finally setting the class's vtable_method_count. Must be called with the // finally setting the class's vtable_method_count. Must be called with the
...@@ -1594,13 +1611,16 @@ _Jv_LayoutVTableMethods (jclass klass) ...@@ -1594,13 +1611,16 @@ _Jv_LayoutVTableMethods (jclass klass)
continue; continue;
if (superclass != NULL) if (superclass != NULL)
super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, {
meth->signature); super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name,
meth->signature);
}
if (super_meth) if (super_meth)
meth->index = super_meth->index; meth->index = super_meth->index;
else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL)) else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL)
meth->index = index++; && ! (klass->accflags & java::lang::reflect::Modifier::FINAL))
meth->index = index++;
} }
klass->vtable_method_count = index; klass->vtable_method_count = index;
...@@ -1626,8 +1646,7 @@ _Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags) ...@@ -1626,8 +1646,7 @@ _Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags)
continue; continue;
if ((meth->accflags & Modifier::ABSTRACT)) if ((meth->accflags & Modifier::ABSTRACT))
{ {
// FIXME: we should set abstract slots to a function that vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError);
// throws AbstractMethodError. How can we do that on IA-64?
flags[meth->index] = false; flags[meth->index] = false;
} }
else else
......
...@@ -56,17 +56,18 @@ java::lang::ClassLoader::defineClass0 (jstring name, ...@@ -56,17 +56,18 @@ java::lang::ClassLoader::defineClass0 (jstring name,
sizeof (_Jv_InterpClass)); sizeof (_Jv_InterpClass));
_Jv_InitNewClassFields (klass); _Jv_InitNewClassFields (klass);
// synchronize on the class, so that it is not // Synchronize on the class, so that it is not attempted initialized
// attempted initialized until we're done loading. // until we're done loading.
_Jv_MonitorEnter (klass); JvSynchronize sync (klass);
// record which is the defining loader // Record the defining loader. For the system class loader, we
klass->loader = this; // record NULL.
if (this != java::lang::ClassLoader::getSystemClassLoader())
klass->loader = this;
// register that we are the initiating loader...
if (name != 0) if (name != 0)
{ {
_Jv_Utf8Const * name2 = _Jv_makeUtf8Const (name); _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
if (! _Jv_VerifyClassName (name2)) if (! _Jv_VerifyClassName (name2))
throw new java::lang::ClassFormatError throw new java::lang::ClassFormatError
...@@ -86,16 +87,8 @@ java::lang::ClassLoader::defineClass0 (jstring name, ...@@ -86,16 +87,8 @@ java::lang::ClassLoader::defineClass0 (jstring name,
_Jv_UnregisterClass (klass); _Jv_UnregisterClass (klass);
_Jv_MonitorExit (klass); // If EX is not a ClassNotFoundException, that's ok, because we
// account for the possibility in defineClass().
// FIXME: Here we may want to test that EX does
// indeed represent a valid exception. That is,
// anything but ClassNotFoundException,
// or some kind of Error.
// FIXME: Rewrite this as a cleanup instead of
// as a catch handler.
throw ex; throw ex;
} }
...@@ -104,10 +97,6 @@ java::lang::ClassLoader::defineClass0 (jstring name, ...@@ -104,10 +97,6 @@ java::lang::ClassLoader::defineClass0 (jstring name,
// if everything proceeded sucessfully, we're loaded. // if everything proceeded sucessfully, we're loaded.
JvAssert (klass->state == JV_STATE_LOADED); JvAssert (klass->state == JV_STATE_LOADED);
// if an exception is generated, this is initially missed.
// however, we come back here in handleException0 below...
_Jv_MonitorExit (klass);
return klass; return klass;
#else // INTERPRETER #else // INTERPRETER
...@@ -293,10 +282,11 @@ _Jv_PrepareCompiledClass (jclass klass) ...@@ -293,10 +282,11 @@ _Jv_PrepareCompiledClass (jclass klass)
// Hash function for Utf8Consts. // Hash function for Utf8Consts.
#define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN) #define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN)
struct _Jv_LoaderInfo { struct _Jv_LoaderInfo
_Jv_LoaderInfo *next; {
java::lang::Class *klass; _Jv_LoaderInfo *next;
java::lang::ClassLoader *loader; java::lang::Class *klass;
java::lang::ClassLoader *loader;
}; };
static _Jv_LoaderInfo *initiated_classes[HASH_LEN]; static _Jv_LoaderInfo *initiated_classes[HASH_LEN];
...@@ -309,9 +299,12 @@ static jclass loaded_classes[HASH_LEN]; ...@@ -309,9 +299,12 @@ static jclass loaded_classes[HASH_LEN];
jclass jclass
_Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) _Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{ {
_Jv_MonitorEnter (&java::lang::Class::class$); JvSynchronize sync (&java::lang::Class::class$);
jint hash = HASH_UTF (name); jint hash = HASH_UTF (name);
if (loader && loader == java::lang::ClassLoader::getSystemClassLoader())
loader = NULL;
// first, if LOADER is a defining loader, then it is also initiating // first, if LOADER is a defining loader, then it is also initiating
jclass klass; jclass klass;
for (klass = loaded_classes[hash]; klass; klass = klass->next) for (klass = loaded_classes[hash]; klass; klass = klass->next)
...@@ -337,15 +330,13 @@ _Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) ...@@ -337,15 +330,13 @@ _Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
} }
} }
_Jv_MonitorExit (&java::lang::Class::class$);
return klass; return klass;
} }
void void
_Jv_UnregisterClass (jclass the_class) _Jv_UnregisterClass (jclass the_class)
{ {
_Jv_MonitorEnter (&java::lang::Class::class$); JvSynchronize sync (&java::lang::Class::class$);
jint hash = HASH_UTF(the_class->name); jint hash = HASH_UTF(the_class->name);
jclass *klass = &(loaded_classes[hash]); jclass *klass = &(loaded_classes[hash]);
...@@ -363,29 +354,32 @@ _Jv_UnregisterClass (jclass the_class) ...@@ -363,29 +354,32 @@ _Jv_UnregisterClass (jclass the_class)
{ {
while (*info && (*info)->klass == the_class) while (*info && (*info)->klass == the_class)
{ {
_Jv_LoaderInfo *old = *info;
*info = (*info)->next; *info = (*info)->next;
_Jv_Free (old);
} }
if (*info == NULL) if (*info == NULL)
break; break;
} }
_Jv_MonitorExit (&java::lang::Class::class$);
} }
void void
_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
{ {
// non-gc alloc! if (loader && loader == java::lang::ClassLoader::getSystemClassLoader())
_Jv_LoaderInfo *info = (_Jv_LoaderInfo *) _Jv_Malloc (sizeof(_Jv_LoaderInfo)); loader = NULL;
// This information can't be visible to the GC.
_Jv_LoaderInfo *info
= (_Jv_LoaderInfo *) _Jv_Malloc (sizeof(_Jv_LoaderInfo));
jint hash = HASH_UTF(klass->name); jint hash = HASH_UTF(klass->name);
_Jv_MonitorEnter (&java::lang::Class::class$); JvSynchronize sync (&java::lang::Class::class$);
info->loader = loader; info->loader = loader;
info->klass = klass; info->klass = klass;
info->next = initiated_classes[hash]; info->next = initiated_classes[hash];
initiated_classes[hash] = info; initiated_classes[hash] = info;
_Jv_MonitorExit (&java::lang::Class::class$);
} }
// This function is called many times during startup, before main() is // This function is called many times during startup, before main() is
...@@ -471,6 +465,9 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) ...@@ -471,6 +465,9 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{ {
jstring sname = _Jv_NewStringUTF (name->data); jstring sname = _Jv_NewStringUTF (name->data);
java::lang::ClassLoader *sys
= java::lang::ClassLoader::getSystemClassLoader ();
if (loader) if (loader)
{ {
// Load using a user-defined loader, jvmspec 5.3.2 // Load using a user-defined loader, jvmspec 5.3.2
...@@ -479,14 +476,14 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) ...@@ -479,14 +476,14 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
// If "loader" delegated the loadClass operation to another // If "loader" delegated the loadClass operation to another
// loader, explicitly register that it is also an initiating // loader, explicitly register that it is also an initiating
// loader of the given class. // loader of the given class.
if (klass && (klass->getClassLoader () != loader)) java::lang::ClassLoader *delegate = (loader == sys
? NULL
: loader);
if (klass && klass->getClassLoaderInternal () != delegate)
_Jv_RegisterInitiatingLoader (klass, loader); _Jv_RegisterInitiatingLoader (klass, loader);
} }
else else
{ {
java::lang::ClassLoader *sys
= java::lang::ClassLoader::getSystemClassLoader ();
// Load using the bootstrap loader jvmspec 5.3.1. // Load using the bootstrap loader jvmspec 5.3.1.
klass = sys->loadClass (sname, false); klass = sys->loadClass (sname, false);
......
/* java.lang.reflect.Modifier /* java.lang.reflect.Modifier
Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -158,6 +158,17 @@ public class Modifier ...@@ -158,6 +158,17 @@ public class Modifier
static final int ALL_FLAGS = 0xfff; static final int ALL_FLAGS = 0xfff;
/** /**
* GCJ-LOCAL: This access flag is set on methods we declare
* internally but which must not be visible to reflection.
*/
static final int INVISIBLE = 0x1000;
/**
* GCJ-LOCAL: This access flag is set on interpreted classes.
*/
static final int INTERPRETED = 0x1000;
/**
* Check whether the given modifier is abstract. * Check whether the given modifier is abstract.
* @param mod the modifier. * @param mod the modifier.
* @return <code>true</code> if abstract, <code>false</code> otherwise. * @return <code>true</code> if abstract, <code>false</code> otherwise.
......
...@@ -238,7 +238,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index) ...@@ -238,7 +238,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
// First search the class itself. // First search the class itself.
the_method = _Jv_SearchMethodInClass (owner, klass, the_method = _Jv_SearchMethodInClass (owner, klass,
method_name, method_signature); method_name, method_signature);
if (the_method != 0) if (the_method != 0)
{ {
...@@ -246,9 +246,10 @@ _Jv_ResolvePoolEntry (jclass klass, int index) ...@@ -246,9 +246,10 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
goto end_of_method_search; goto end_of_method_search;
} }
// If we are resolving an interface method, search the interface's // If we are resolving an interface method, search the
// superinterfaces (A superinterface is not an interface's superclass - // interface's superinterfaces (A superinterface is not an
// a superinterface is implemented by the interface). // interface's superclass - a superinterface is implemented by
// the interface).
if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref) if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref)
{ {
_Jv_ifaces ifaces; _Jv_ifaces ifaces;
...@@ -257,8 +258,8 @@ _Jv_ResolvePoolEntry (jclass klass, int index) ...@@ -257,8 +258,8 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *)); ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *));
_Jv_GetInterfaces (owner, &ifaces); _Jv_GetInterfaces (owner, &ifaces);
for (int i=0; i < ifaces.count; i++) for (int i = 0; i < ifaces.count; i++)
{ {
jclass cls = ifaces.list[i]; jclass cls = ifaces.list[i];
the_method = _Jv_SearchMethodInClass (cls, klass, method_name, the_method = _Jv_SearchMethodInClass (cls, klass, method_name,
...@@ -269,9 +270,9 @@ _Jv_ResolvePoolEntry (jclass klass, int index) ...@@ -269,9 +270,9 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
break; break;
} }
} }
_Jv_Free (ifaces.list); _Jv_Free (ifaces.list);
if (the_method != 0) if (the_method != 0)
goto end_of_method_search; goto end_of_method_search;
} }
...@@ -281,7 +282,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index) ...@@ -281,7 +282,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
cls = cls->getSuperclass ()) cls = cls->getSuperclass ())
{ {
the_method = _Jv_SearchMethodInClass (cls, klass, the_method = _Jv_SearchMethodInClass (cls, klass,
method_name, method_signature); method_name, method_signature);
if (the_method != 0) if (the_method != 0)
{ {
found_class = cls; found_class = cls;
...@@ -363,6 +364,58 @@ _Jv_SearchMethodInClass (jclass cls, jclass klass, ...@@ -363,6 +364,58 @@ _Jv_SearchMethodInClass (jclass cls, jclass klass,
return 0; return 0;
} }
// A helper for _Jv_PrepareClass. This adds missing `Miranda methods'
// to a class.
void
_Jv_PrepareMissingMethods (jclass base2, jclass iface_class)
{
_Jv_InterpClass *base = reinterpret_cast<_Jv_InterpClass *> (base2);
for (int i = 0; i < iface_class->interface_count; ++i)
{
for (int j = 0; j < iface_class->interfaces[i]->method_count; ++j)
{
_Jv_Method *meth = &iface_class->interfaces[i]->methods[j];
// Don't bother with <clinit>.
if (meth->name->data[0] == '<')
continue;
_Jv_Method *new_meth = _Jv_LookupDeclaredMethod (base, meth->name,
meth->signature);
if (! new_meth)
{
// We assume that such methods are very unlikely, so we
// just reallocate the method array each time one is
// found. This greatly simplifies the searching --
// otherwise we have to make sure that each such method
// found is really unique among all superinterfaces.
int new_count = base->method_count + 1;
_Jv_Method *new_m
= (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method)
* new_count);
memcpy (new_m, base->methods,
sizeof (_Jv_Method) * base->method_count);
// Add new method.
new_m[base->method_count] = *meth;
new_m[base->method_count].index = (_Jv_ushort) -1;
new_m[base->method_count].accflags
|= java::lang::reflect::Modifier::INVISIBLE;
_Jv_MethodBase **new_im
= (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
* new_count);
memcpy (new_im, base->interpreted_methods,
sizeof (_Jv_MethodBase *) * base->method_count);
base->methods = new_m;
base->interpreted_methods = new_im;
base->method_count = new_count;
}
}
_Jv_PrepareMissingMethods (base, iface_class->interfaces[i]);
}
}
void void
_Jv_PrepareClass(jclass klass) _Jv_PrepareClass(jclass klass)
{ {
...@@ -516,13 +569,24 @@ _Jv_PrepareClass(jclass klass) ...@@ -516,13 +569,24 @@ _Jv_PrepareClass(jclass klass)
} }
} }
if (clz->accflags & Modifier::INTERFACE) if ((clz->accflags & Modifier::INTERFACE))
{ {
clz->state = JV_STATE_PREPARED; clz->state = JV_STATE_PREPARED;
clz->notifyAll (); clz->notifyAll ();
return; return;
} }
// A class might have so-called "Miranda methods". This is a method
// that is declared in an interface and not re-declared in an
// abstract class. Some compilers don't emit declarations for such
// methods in the class; this will give us problems since we expect
// a declaration for any method requiring a vtable entry. We handle
// this here by searching for such methods and constructing new
// internal declarations for them. We only need to do this for
// abstract classes.
if ((clz->accflags & Modifier::ABSTRACT))
_Jv_PrepareMissingMethods (clz, clz);
clz->vtable_method_count = -1; clz->vtable_method_count = -1;
_Jv_MakeVTable (clz); _Jv_MakeVTable (clz);
......
2002-12-19 Tom Tromey <tromey@redhat.com>
* libjava.jacks/jacks.xfail: Updated.
2002-12-18 Tom Tromey <tromey@redhat.com> 2002-12-18 Tom Tromey <tromey@redhat.com>
* libjava.lang/pr8945.java: New file. * libjava.lang/pr8945.java: New file.
......
...@@ -151,12 +151,8 @@ ...@@ -151,12 +151,8 @@
8.1.2-enclosing-4 8.1.2-enclosing-4
8.1.2-enclosing-5 8.1.2-enclosing-5
8.1.3-object-3 8.1.3-object-3
8.1.3-superclass-10 8.1.3-superclass-5
8.1.3-superclass-12 8.1.3-superclass-6
8.1.3-superclass-13
8.1.4-superinterface-8
8.1.4-superinterface-10
8.1.4-superinterface-11
8.2-accessibility-inherited-member-5 8.2-accessibility-inherited-member-5
8.8.5.1-example-1 8.8.5.1-example-1
8.8.5.1-example-3 8.8.5.1-example-3
...@@ -218,9 +214,14 @@ ...@@ -218,9 +214,14 @@
8.6-checked-exception-10 8.6-checked-exception-10
8.6-checked-exception-11 8.6-checked-exception-11
8.6-checked-exception-12 8.6-checked-exception-12
8.6-complete-1
8.6-complete-4
8.6-complete-5
8.6-abrupt-1 8.6-abrupt-1
8.6-abrupt-4 8.6-abrupt-4
8.5-inheritance-4 8.5-inheritance-1
8.5-inheritance-2
8.5-inheritance-3
8.5-inheritance-6 8.5-inheritance-6
8.5.2-non-static-member-usage-2 8.5.2-non-static-member-usage-2
8.4.6-miranda-2 8.4.6-miranda-2
...@@ -262,6 +263,8 @@ ...@@ -262,6 +263,8 @@
8.4.3-bad-1 8.4.3-bad-1
8.4.3-bad-2 8.4.3-bad-2
8.7-abrupt-1 8.7-abrupt-1
8.7-complete-1
8.7-complete-3
5.1.3-dti-1 5.1.3-dti-1
5.1.3-dti-2 5.1.3-dti-2
5.1.3-fti-1 5.1.3-fti-1
...@@ -448,7 +451,7 @@ ...@@ -448,7 +451,7 @@
15.9.1-unqualified-concrete-6 15.9.1-unqualified-concrete-6
15.9.1-unqualified-concrete-7 15.9.1-unqualified-concrete-7
15.9.1-unqualified-concrete-10 15.9.1-unqualified-concrete-10
15.9.1-unqualified-concrete-15 15.9.1-unqualified-concrete-14
15.9.1-qualified-concrete-6 15.9.1-qualified-concrete-6
15.9.1-qualified-concrete-7 15.9.1-qualified-concrete-7
15.9.1-qualified-concrete-10 15.9.1-qualified-concrete-10
...@@ -456,7 +459,7 @@ ...@@ -456,7 +459,7 @@
15.9.1-qualified-concrete-14 15.9.1-qualified-concrete-14
15.9.1-qualified-concrete-16 15.9.1-qualified-concrete-16
15.9.1-qualified-concrete-20 15.9.1-qualified-concrete-20
15.9.1-qualified-concrete-23 15.9.1-qualified-concrete-24
15.28-primitive-9 15.28-primitive-9
15.28-primitive-15 15.28-primitive-15
15.28-primitive-16 15.28-primitive-16
...@@ -601,9 +604,6 @@ ...@@ -601,9 +604,6 @@
9.1.1-in-interface-3 9.1.1-in-interface-3
9.1.1-in-interface-9 9.1.1-in-interface-9
9.1.1-in-interface-16 9.1.1-in-interface-16
9.1.2-interface-3
9.1.2-interface-5
9.1.2-interface-6
9.1.2-supertype-1 9.1.2-supertype-1
9.2-implicit-2 9.2-implicit-2
9.2-implicit-3 9.2-implicit-3
...@@ -680,10 +680,6 @@ ...@@ -680,10 +680,6 @@
6.6.2.1-protected-instance-method-6 6.6.2.1-protected-instance-method-6
6.6.2.1-protected-instance-method-7 6.6.2.1-protected-instance-method-7
6.6.2.1-protected-type-2 6.6.2.1-protected-type-2
6.6.2.1-protected-type-4
6.6.2.1-protected-type-5
6.6.2.1-protected-type-7
6.6.2.1-protected-type-8
6.6.1-8 6.6.1-8
6.6.1-11 6.6.1-11
6.6.1-array-2 6.6.1-array-2
...@@ -711,14 +707,14 @@ ...@@ -711,14 +707,14 @@
6.5.6.1-local-4 6.5.6.1-local-4
6.5.6.1-field-6 6.5.6.1-field-6
6.5.6.1-explicit-constructor-2 6.5.6.1-explicit-constructor-2
6.5.4.2-qualified-1
6.5.4.1-simple-6 6.5.4.1-simple-6
6.5.4.1-simple-8 6.5.4.1-simple-10
6.5.4.1-simple-11
6.5.1-type-15 6.5.1-type-15
6.5.1-type-16 6.5.1-type-16
6.5.1-type-19 6.5.1-type-19
6.5.1-typeorpackage-1
6.5.1-typeorpackage-2 6.5.1-typeorpackage-2
6.5.5.2-type-4
6.5.5.2-type-5 6.5.5.2-type-5
6.5.5.2-type-6 6.5.5.2-type-6
6.5.5.2-type-7 6.5.5.2-type-7
...@@ -733,9 +729,10 @@ ...@@ -733,9 +729,10 @@
6.5.5.1-nested-19 6.5.5.1-nested-19
6.5.5.1-nested-20 6.5.5.1-nested-20
6.5.5.1-nested-21 6.5.5.1-nested-21
6.5.5.1-nested-22
6.5.5.1-nested-23 6.5.5.1-nested-23
6.3-1 6.3-1
7.4.2-subpackage-1
7.4.2-subpackage-2
7.5.1-canonical-3 7.5.1-canonical-3
7.5.1-accessible-1 7.5.1-accessible-1
7.5.1-duplicate-4 7.5.1-duplicate-4
...@@ -743,8 +740,6 @@ ...@@ -743,8 +740,6 @@
7.5.2-accessible-1 7.5.2-accessible-1
7.5.2-accessible-3 7.5.2-accessible-3
7.5.2-duplicate-3 7.5.2-duplicate-3
7.1-named-5
7.1-named-6
7.1-named-7 7.1-named-7
7.6-unnamed-scope-1 7.6-unnamed-scope-1
4.5.4-static-1 4.5.4-static-1
...@@ -805,7 +800,6 @@ non-jls-zip-2 ...@@ -805,7 +800,6 @@ non-jls-zip-2
14-runtime-jump-1 14-runtime-jump-1
14-runtime-jump-2 14-runtime-jump-2
14.3.1-runtime-3 14.3.1-runtime-3
14.19.2-runtime-try-1
8.1.2-runtime-1 8.1.2-runtime-1
6.6.1-runtime-privateconstructor-1 6.6.1-runtime-privateconstructor-1
8.8.3-runtime-inner-4 8.8.3-runtime-inner-4
...@@ -831,11 +825,11 @@ non-jls-zip-2 ...@@ -831,11 +825,11 @@ non-jls-zip-2
15.11.1-runtime-static-1 15.11.1-runtime-static-1
15.11.1-runtime-static-2 15.11.1-runtime-static-2
15.11.1-runtime-static-3 15.11.1-runtime-static-3
15.11.1-runtime-static-4
15.12.3-runtime-mode-1 15.12.3-runtime-mode-1
15.12.3-runtime-mode-2 15.12.3-runtime-mode-2
15.12.3-runtime-mode-3 15.12.3-runtime-mode-3
15.12.3-runtime-mode-4 15.12.3-runtime-mode-4
15.12.3-runtime-mode-5
15.12.3-runtime-mode-6 15.12.3-runtime-mode-6
15.12.4.1-runtime-static-1 15.12.4.1-runtime-static-1
15.12.4.1-runtime-static-2 15.12.4.1-runtime-static-2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment