Proxies, again

Andrew Haley aph@redhat.com
Mon Apr 2 18:20:00 GMT 2007


OK, I'm going with this.

Andrew.


2007-04-02  Andrew Haley  <aph@redhat.com>

	* java/lang/reflect/natVMProxy.cc (run_proxy): Use
	_Jv_LookupProxyMethod to find the Method.
	If parameter_types->length == 0, pass a null paramameter list,
	not a zero-length parameter list.
	* java/lang/natClass.cc (_Jv_LookupProxyMethod): New function.
	* java/lang/Class.h (_Jv_LookupProxyMethod): Declare.

Index: java/lang/natClass.cc
===================================================================
--- java/lang/natClass.cc	(revision 123431)
+++ java/lang/natClass.cc	(working copy)
@@ -29,6 +29,7 @@
 #include <java/lang/reflect/Member.h>
 #include <java/lang/reflect/Method.h>
 #include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Proxy.h>
 #include <java/lang/reflect/Constructor.h>
 #include <java/lang/AbstractMethodError.h>
 #include <java/lang/ArrayStoreException.h>
@@ -1639,6 +1640,39 @@
   return NULL;
 }
 
+// The rules for finding proxy methods are different: first we search
+// the interfaces implemented by a proxy, then the methods declared in
+// class Proxy.
+
+java::lang::reflect::Method *
+_Jv_LookupProxyMethod (jclass proxyClass, _Jv_Utf8Const *name,
+		       _Jv_Utf8Const *signature)
+{
+  using namespace java::lang::reflect;
+  jclass declaringClass;
+  _Jv_Method * m;
+
+  for (int i = 0; i < proxyClass->interface_count; i++)
+    {
+      declaringClass = proxyClass->interfaces[i];
+      m = _Jv_GetMethodLocal (declaringClass, name, signature);
+      if (m)
+	break;
+    }
+  if (!m)
+    m = _Jv_LookupDeclaredMethod (&Proxy::class$,
+				  name,
+				  signature,
+				  &declaringClass);
+
+  Method *rmethod = new Method ();
+  rmethod->offset = (char*) m - (char*) declaringClass->methods;
+  rmethod->declaringClass = declaringClass;
+  return rmethod;
+}
+
+
+
 java::lang::reflect::Method *
 _Jv_GetReflectedMethod (jclass klass, _Jv_Utf8Const *name,
 		       _Jv_Utf8Const *signature)
Index: java/lang/reflect/natVMProxy.cc
===================================================================
--- java/lang/reflect/natVMProxy.cc	(revision 123431)
+++ java/lang/reflect/natVMProxy.cc	(working copy)
@@ -301,6 +301,8 @@
 	   void **args,
 	   void*user_data)
 {
+  using namespace java::lang::reflect;
+
   Proxy *proxy = *(Proxy**)args[0];
   ncode_closure *self = (ncode_closure *) user_data;
 
@@ -312,17 +314,22 @@
   Thread *thread = Thread::currentThread();
   _Jv_InterpFrame frame_desc (self->self, thread, proxy->getClass());
 
-  Method *meth = _Jv_GetReflectedMethod (proxy->getClass(), 
-					 self->self->name,
-					 self->self->signature);
+  Method *meth = _Jv_LookupProxyMethod (proxy->getClass(), 
+					self->self->name,
+					self->self->signature);
   JArray<jclass> *parameter_types = meth->internalGetParameterTypes ();
   JArray<jclass> *exception_types = meth->internalGetExceptionTypes ();
 
   InvocationHandler *handler = proxy->h;
-  void *poo 
-    = _Jv_NewObjectArray (parameter_types->length, &Object::class$, NULL);
-  JArray<jobject> *argsArray = (JArray<jobject> *) poo;
-  jobject *jargs = elements(argsArray);
+  JArray<jobject> *argsArray = NULL;
+  jobject *jargs = NULL;
+  if (parameter_types->length)
+    {
+      void *poo 
+	= _Jv_NewObjectArray (parameter_types->length, &Object::class$, NULL);
+      argsArray = (JArray<jobject> *) poo;
+      jargs = elements(argsArray);
+    }
 
   // FIXME: It must be possible to use fast interface dispatch here,
   // but I've not quite figured out how to do it.
Index: java/lang/Class.h
===================================================================
--- java/lang/Class.h	(revision 123431)
+++ java/lang/Class.h	(working copy)
@@ -237,6 +237,8 @@
 java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass klass, 
 						    _Jv_Utf8Const *name,
 						    _Jv_Utf8Const *signature);
+java::lang::reflect::Method *_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *,
+						    _Jv_Utf8Const *);
 jfieldID JvGetFirstInstanceField (jclass);
 jint JvNumInstanceFields (jclass);
 jfieldID JvGetFirstStaticField (jclass);
@@ -542,6 +544,9 @@
   friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass klass, 
 						    _Jv_Utf8Const *name,
 						    _Jv_Utf8Const *signature);
+  friend java::lang::reflect::Method *::_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *,
+							       _Jv_Utf8Const *);
+
   friend jfieldID (::JvGetFirstInstanceField) (jclass);
   friend jint (::JvNumInstanceFields) (jclass);
   friend jfieldID (::JvGetFirstStaticField) (jclass);
Index: headers.txt
===================================================================
--- headers.txt	(revision 123431)
+++ headers.txt	(working copy)
@@ -57,11 +57,13 @@
 prepend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
 prepend jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
 prepend ::java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
+prepend ::java::lang::reflect::Method *_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *, _Jv_Utf8Const *);
 friend jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);
 friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
 friend class java::lang::Class;
 friend class java::io::ObjectInputStream;
 friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
+friend java::lang::reflect::Method* ::_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *, _Jv_Utf8Const *);
 
 class gnu/gcj/runtime/ExtensionClassLoader
 friend class ::java::lang::ClassLoader;

-- 
Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, UK
Registered in England and Wales No. 3798903



More information about the Java-patches mailing list