diff options
author | Tom Tromey <tromey@redhat.com> | 2002-12-19 19:31:55 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2002-12-19 19:31:55 +0000 |
commit | a1aba4f9a58dd40b19f7aeb117ab1a3bcc2a2cca (patch) | |
tree | f9577aaed149db0eda3cc774a016793bce9754d6 /libjava/resolve.cc | |
parent | 385405940e8b05e4d8e1ad9136f6c9f86b279b07 (diff) | |
download | gcc-a1aba4f9a58dd40b19f7aeb117ab1a3bcc2a2cca.zip gcc-a1aba4f9a58dd40b19f7aeb117ab1a3bcc2a2cca.tar.gz gcc-a1aba4f9a58dd40b19f7aeb117ab1a3bcc2a2cca.tar.bz2 |
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
Diffstat (limited to 'libjava/resolve.cc')
-rw-r--r-- | libjava/resolve.cc | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/libjava/resolve.cc b/libjava/resolve.cc index e195c333..00785ee 100644 --- a/libjava/resolve.cc +++ b/libjava/resolve.cc @@ -238,7 +238,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index) // First search the class itself. the_method = _Jv_SearchMethodInClass (owner, klass, - method_name, method_signature); + method_name, method_signature); if (the_method != 0) { @@ -246,9 +246,10 @@ _Jv_ResolvePoolEntry (jclass klass, int index) goto end_of_method_search; } - // If we are resolving an interface method, search the interface's - // superinterfaces (A superinterface is not an interface's superclass - - // a superinterface is implemented by the interface). + // If we are resolving an interface method, search the + // interface's superinterfaces (A superinterface is not an + // interface's superclass - a superinterface is implemented by + // the interface). if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref) { _Jv_ifaces ifaces; @@ -257,8 +258,8 @@ _Jv_ResolvePoolEntry (jclass klass, int index) ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *)); _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]; the_method = _Jv_SearchMethodInClass (cls, klass, method_name, @@ -269,9 +270,9 @@ _Jv_ResolvePoolEntry (jclass klass, int index) break; } } - + _Jv_Free (ifaces.list); - + if (the_method != 0) goto end_of_method_search; } @@ -281,7 +282,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index) cls = cls->getSuperclass ()) { the_method = _Jv_SearchMethodInClass (cls, klass, - method_name, method_signature); + method_name, method_signature); if (the_method != 0) { found_class = cls; @@ -363,6 +364,58 @@ _Jv_SearchMethodInClass (jclass cls, jclass klass, 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 _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->notifyAll (); 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; _Jv_MakeVTable (clz); |