OSDN Git Service

2000-06-15 Bryce McKinlay <bryce@albatross.co.nz>
authorbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Jun 2000 11:58:18 +0000 (11:58 +0000)
committerbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Jun 2000 11:58:18 +0000 (11:58 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34562 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/java/lang/natClass.cc
libjava/prims.cc

index 7ec5cb1..db06390 100644 (file)
@@ -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.
index dfc3840..995e631 100644 (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)
 {
index 3a022f0..c7c764c 100644 (file)
@@ -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.