This is the mail archive of the java-patches@gcc.gnu.org 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]
Other format: [Raw text]

PING: Reflection doesn't work across interfaces


Paging Tom Tromey...

--- Begin Message ---
Yes, really.

This is pretty amazing, but I've discovered that Method.invoke()
doesn't work when the Method is in an interface.

Andrew.



2004-03-26  Andrew Haley  <aph@redhat.com>

	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
	_Jv_LookupInterfaceMethodIdx to calcualte the address of a method
	in an interface.
	* include/jvm.h (_Jv_CallAnyMethodA): Add new arg: iface.

Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.62
diff -p -2 -c -r1.62 jvm.h
*** include/jvm.h	26 Oct 2003 02:25:41 -0000	1.62
--- include/jvm.h	26 Mar 2004 10:52:23 -0000
*************** extern jobject _Jv_CallAnyMethodA (jobje
*** 420,424 ****
  				   jmethodID meth, jboolean is_constructor,
  				   JArray<jclass> *parameter_types,
! 				   jobjectArray args);
  
  union jvalue;
--- 420,425 ----
  				   jmethodID meth, jboolean is_constructor,
  				   JArray<jclass> *parameter_types,
! 				   jobjectArray args,
! 				   jclass iface = NULL);
  
  union jvalue;
*************** extern void _Jv_CallAnyMethodA (jobject 
*** 431,435 ****
  				jvalue *args,
  				jvalue *result,
! 				jboolean is_jni_call = true);
  
  extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
--- 432,437 ----
  				jvalue *args,
  				jvalue *result,
! 				jboolean is_jni_call = true,
! 				jclass iface = NULL);
  
  extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
Index: java/lang/reflect/natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.36
diff -p -2 -c -r1.36 natMethod.cc
*** java/lang/reflect/natMethod.cc	30 Oct 2003 21:09:45 -0000	1.36
--- java/lang/reflect/natMethod.cc	26 Mar 2004 10:52:54 -0000
*************** java::lang::reflect::Method::invoke (job
*** 144,147 ****
--- 144,148 ----
  {
    using namespace java::lang::reflect;
+   jclass iface = NULL;
    
    if (parameter_types == NULL)
*************** java::lang::reflect::Method::invoke (job
*** 149,155 ****
      
    jmethodID meth = _Jv_FromReflectedMethod (this);
- 
    jclass objClass;
!   
    if (Modifier::isStatic(meth->accflags))
      {
--- 150,155 ----
      
    jmethodID meth = _Jv_FromReflectedMethod (this);
    jclass objClass;
! 
    if (Modifier::isStatic(meth->accflags))
      {
*************** java::lang::reflect::Method::invoke (job
*** 189,194 ****
      }
  
    return _Jv_CallAnyMethodA (obj, return_type, meth, false,
! 			     parameter_types, args);
  }
  
--- 189,197 ----
      }
  
+   if (declaringClass->isInterface())
+     iface = declaringClass;
+   
    return _Jv_CallAnyMethodA (obj, return_type, meth, false,
! 			     parameter_types, args, iface);
  }
  
*************** _Jv_CallAnyMethodA (jobject obj,
*** 342,346 ****
  		    jvalue *args,
  		    jvalue *result,
! 		    jboolean is_jni_call)
  {
    using namespace java::lang::reflect;
--- 345,350 ----
  		    jvalue *args,
  		    jvalue *result,
! 		    jboolean is_jni_call,
! 		    jclass iface)
  {
    using namespace java::lang::reflect;
*************** _Jv_CallAnyMethodA (jobject obj,
*** 470,474 ****
      {
        _Jv_VTable *vtable = *(_Jv_VTable **) obj;
!       ncode = vtable->get_method (meth->index);
      }
    else
--- 474,491 ----
      {
        _Jv_VTable *vtable = *(_Jv_VTable **) obj;
!       if (iface == NULL)
! 	ncode = vtable->get_method (meth->index);
!       else
! 	{
! 	  /* Okay, here's how it goes.  We want to know the method
! 	     offset in the list of methods declared by an interface,
! 	     starting at 1.  The offset in the method is the vtable
! 	     offset, not the offset in the interface, so we subtract
! 	     that.  We add 1 because we count interface methods
! 	     beginning at 1.  I think this is because of the initial
! 	     gc descriptor in the vtable.  */
! 	  jint offset = meth->index - JvGetFirstMethod (iface)->index + 1;
! 	  ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface, offset);
! 	}
      }
    else
*************** _Jv_CallAnyMethodA (jobject obj,
*** 545,549 ****
  		    jboolean is_constructor,
  		    JArray<jclass> *parameter_types,
! 		    jobjectArray args)
  {
    if (parameter_types->length == 0 && args == NULL)
--- 562,567 ----
  		    jboolean is_constructor,
  		    JArray<jclass> *parameter_types,
! 		    jobjectArray args,
! 		    jclass iface)
  {
    if (parameter_types->length == 0 && args == NULL)
*************** _Jv_CallAnyMethodA (jobject obj,
*** 613,617 ****
    		      _Jv_isVirtualMethod (meth),
  		      parameter_types, argvals, &ret_value,
! 		      false);
  
    jobject r;
--- 631,635 ----
    		      _Jv_isVirtualMethod (meth),
  		      parameter_types, argvals, &ret_value,
! 		      false, iface);
  
    jobject r;

--- End Message ---

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