From d655f87d6f2f59e00401a483f7f824dea25d1bd4 Mon Sep 17 00:00:00 2001 From: Bryce McKinlay Date: Thu, 15 Jun 2000 11:58:18 +0000 Subject: [PATCH] 2000-06-15 Bryce McKinlay 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 --- libjava/ChangeLog | 11 +++++++++ libjava/java/lang/natClass.cc | 44 +++++++++++++++++++++++------------ libjava/prims.cc | 2 +- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 7ec5cb1185f..db0639020e1 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,14 @@ +2000-06-15 Bryce McKinlay + + 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 * 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 dfc3840a6a0..995e631ace5 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 3a022f0380a..c7c764c604f 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.