aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryce McKinlay <bryce@albatross.co.nz>2000-06-15 11:58:18 +0000
committerBryce McKinlay <bryce@gcc.gnu.org>2000-06-15 12:58:18 +0100
commitd655f87d6f2f59e00401a483f7f824dea25d1bd4 (patch)
tree0b9fe4dc58f8743700d1abbcfca867013097d4b5
parentecb3185ea3697fce050ad04805a8aebd0ece6570 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--libjava/java/lang/natClass.cc44
-rw-r--r--libjava/prims.cc2
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.