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
This commit is contained in:
Bryce McKinlay 2000-06-15 11:58:18 +00:00 committed by Bryce McKinlay
parent ecb3185ea3
commit d655f87d6f
3 changed files with 41 additions and 16 deletions

View file

@ -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)
{