Patch for correctly intializing interface class on Method.invoke() (Was: Line number support for interpreter)

Bryce McKinlay mckinlay@redhat.com
Thu May 20 15:07:00 GMT 2004


Mark Wielaard wrote:

>The following patch adds explicit initialization of interface classes to
>Method.invoke() and also does the test whether the declaringClass is an
>interface only when the method involved isn't a static method since
>interfaces cannot contain static methods.
>  
>

If other implementations initialize interfaces during Method.invoke(), 
which apparently from our discussions on IRC, they do, then we should do 
the same for compatibility - so your patch is fine. However, an 
interface should not have to be initialized in order to call 
Method.invoke() on it, assuming the method being invoked is not static. 
So, I think the real bug here is that we layout the interface methods at 
the wrong time, ie during initialization when it should be done during 
linking/preparation. So, I suggest the following patch (untested):

Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.77
diff -u -r1.77 natClass.cc
--- java/lang/natClass.cc       21 Apr 2004 19:26:22 -0000      1.77
+++ java/lang/natClass.cc       20 May 2004 14:18:25 -0000
@@ -790,9 +790,6 @@
        }
     }
 
-  if (isInterface ())
-    _Jv_LayoutInterfaceMethods (this);
-
   _Jv_PrepareConstantTimeTables (this);
 
   if (vtable == NULL)
Index: java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.65
diff -u -r1.65 natClassLoader.cc
--- java/lang/natClassLoader.cc 20 Apr 2004 01:38:46 -0000      1.65
+++ java/lang/natClassLoader.cc 20 May 2004 14:18:25 -0000
@@ -170,6 +170,9 @@
     }
 #endif /* INTERPRETER */
 
+  if (klass->isInterface ())
+    _Jv_LayoutInterfaceMethods (klass);
+
   klass->notifyAll ();
 
   _Jv_PushClass (klass);

>2004-05-20  Mark Wielaard  <mark@klomp.org>
>
>       * java/lang/reflect/natMethod.cc (invoke): Only check isInterface()
>       and set iface when method is non-static. Always initialize interface
>       classes.
>
>There is now a gnu.testlet.java.lang.Class.init test in Mauve.
>gij-3.3 gives a couple of failures since it initializes the interface
>class much too early. gij-3.4 (and gij CVS) crashes as soon as invoke()
>is called on the interface method (but correctly delay initializing the
>interface class). And with this patch gij CVS gives all PASSes for this
>test. All regression tests in libjava/testsuite also still PASS.
>
>OK to commit?
>  
>

OK, but perhaps shorten & change the comment to indicate that this is 
for compatibility with other implementations. It may also be worth 
updating the javadoc for invoke() to indicate what & when it initializes.

Thanks

Bryce

>Index: java/lang/reflect/natMethod.cc
>===================================================================
>RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
>retrieving revision 1.39
>diff -u -r1.39 natMethod.cc
>--- java/lang/reflect/natMethod.cc	20 Apr 2004 01:38:46 -0000	1.39
>+++ java/lang/reflect/natMethod.cc	20 May 2004 09:20:47 -0000
>@@ -165,6 +165,18 @@
>      
>       if (! _Jv_IsAssignableFrom (declaringClass, objClass))
>         throw new java::lang::IllegalArgumentException;
>+
>+      // If the declaring class of the method is an interface we will
>+      // have to explicitly initialize it.  Neither
>+      // Class.get(Declared)Method nor creating an Object of a class
>+      // that implements that interface has to initialize the
>+      // interface class.  So this may be the first active use of the
>+      // interface as class.
>+      if (declaringClass->isInterface ())
>+	{
>+	  _Jv_InitClass (declaringClass);
>+	  iface = declaringClass;
>+	}
>     }
> 
>   // Check accessibility, if required.
>@@ -188,9 +200,6 @@
> 	throw new IllegalAccessException;
>     }
> 
>-  if (declaringClass->isInterface())
>-    iface = declaringClass;
>-  
>   return _Jv_CallAnyMethodA (obj, return_type, meth, false,
> 			     parameter_types, args, iface);
> }
>  
>



More information about the Java-patches mailing list