diff options
author | Bryce McKinlay <bryce@albatross.co.nz> | 2000-06-15 11:58:18 +0000 |
---|---|---|
committer | Bryce McKinlay <bryce@gcc.gnu.org> | 2000-06-15 12:58:18 +0100 |
commit | d655f87d6f2f59e00401a483f7f824dea25d1bd4 (patch) | |
tree | 0b9fe4dc58f8743700d1abbcfca867013097d4b5 | |
parent | ecb3185ea3697fce050ad04805a8aebd0ece6570 (diff) | |
download | gcc-d655f87d6f2f59e00401a483f7f824dea25d1bd4.zip gcc-d655f87d6f2f59e00401a483f7f824dea25d1bd4.tar.gz gcc-d655f87d6f2f59e00401a483f7f824dea25d1bd4.tar.bz2 |
2000-06-15 Bryce McKinlay <bryce@albatross.co.nz>
Fix for PR java.lang/258:
* prims.cc (_Jv_PrimClass): Set state of primitive class to
JV_STATE_DONE, to prevent accidental initialization.
* java/lang/natClass.cc (_Jv_IsAssignableFrom): Call
_Jv_InterfaceAssignableFrom if target is an interface and source is
an interface or an abstract class. Remove redundant initializeClass
calls. Remove duplicate if_idt test.
* java/lang/Class.h (_Jv_InterfaceAssignableFrom): New function.
From-SVN: r34562
-rw-r--r-- | libjava/ChangeLog | 11 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 44 | ||||
-rw-r--r-- | libjava/prims.cc | 2 |
3 files changed, 41 insertions, 16 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 7ec5cb1..db06390 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,14 @@ +2000-06-15 Bryce McKinlay <bryce@albatross.co.nz> + + Fix for PR java.lang/258: + * prims.cc (_Jv_PrimClass): Set state of primitive class to + JV_STATE_DONE, to prevent accidental initialization. + * java/lang/natClass.cc (_Jv_IsAssignableFrom): Call + _Jv_InterfaceAssignableFrom if target is an interface and source is an + interface or an abstract class. Remove redundant initializeClass calls. + Remove duplicate if_idt test. + * java/lang/Class.h (_Jv_InterfaceAssignableFrom): New function. + 2000-05-31 Tom Tromey <tromey@cygnus.com> * prims.cc (DECLARE_PRIM_TYPE): Define a vtable as well. diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index dfc3840..995e631 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -921,24 +921,16 @@ _Jv_IsAssignableFrom (jclass target, jclass source) if (target->isInterface()) { - // Abstract classes have no IDTs, so compare superclasses instead. - if (java::lang::reflect::Modifier::isAbstract (source->accflags)) - { - jclass super = source->getSuperclass(); - return super ? _Jv_IsAssignableFrom (target, super) : false; - } - - if (source->state != JV_STATE_DONE) - source->initializeClass (); - if (target->state != JV_STATE_DONE) - target->initializeClass (); - + // Abstract classes have no IDT, and IDTs provide no way to check + // two interfaces for assignability. + if (__builtin_expect + (java::lang::reflect::Modifier::isAbstract (source->accflags) + || source->isInterface(), false)) + return _Jv_InterfaceAssignableFrom (target, source); + _Jv_IDispatchTable *cl_idt = source->idt; _Jv_IDispatchTable *if_idt = target->idt; - if (if_idt == NULL) // The interface has no implementations - return false; - if (__builtin_expect ((if_idt == NULL), false)) return false; // No class implementing TARGET has been loaded. jshort cl_iindex = cl_idt->cls.iindex; @@ -954,6 +946,28 @@ _Jv_IsAssignableFrom (jclass target, jclass source) return false; } +// Interface type checking, the slow way. Returns TRUE if IFACE is a +// superinterface of SOURCE. This is used when SOURCE is also an interface, +// or a class with no interface dispatch table. +jboolean +_Jv_InterfaceAssignableFrom (jclass iface, jclass source) +{ + for (int i = 0; i < source->interface_count; i++) + { + jclass interface = source->interfaces[i]; + if (iface == interface + || _Jv_InterfaceAssignableFrom (iface, interface)) + return true; + } + + if (!source->isInterface() + && source->superclass + && _Jv_InterfaceAssignableFrom (iface, source->superclass)) + return true; + + return false; +} + jboolean _Jv_IsInstanceOf(jobject obj, jclass cl) { diff --git a/libjava/prims.cc b/libjava/prims.cc index 3a022f0..c7c764c 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -543,7 +543,7 @@ public: interfaces = NULL; loader = NULL; interface_count = 0; - state = JV_STATE_NOTHING; + state = JV_STATE_DONE; thread = NULL; // Note that we have to set `methods' to NULL. |