This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: Fix for PR 258


Im going to check in this patch, which fixes PR 258. The type checking
code now falls back to a slower technique in the (fairly rare?) case
where the check can't be done using the constant time tables.

And just to be clear, I would like to point out that the rather amusing
"Abstract classes have no IDTs, so compare superclasses" code had
nothing to do with me ;-)

regards

  [ bryce ]

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 attempts.
	* 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.

Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natClass.cc,v
retrieving revision 1.25
diff -u -r1.25 natClass.cc
--- natClass.cc	2000/05/19 17:55:32	1.25
+++ natClass.cc	2000/06/15 11:26:04
@@ -921,24 +921,16 @@
 
   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;
@@ -951,6 +943,28 @@
 	}
     }
     
+  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;
 }
 
Index: prims.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/prims.cc,v
retrieving revision 1.31
diff -u -r1.31 prims.cc
--- prims.cc	2000/05/31 23:50:36	1.31
+++ prims.cc	2000/06/15 11:26:25
@@ -543,7 +543,7 @@
       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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]