This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Reflection doesn't work across interfaces
- From: Andrew Haley <aph at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Fri, 26 Mar 2004 11:10:22 GMT
- Subject: Reflection doesn't work across interfaces
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;