natVMProxy.cc (ncode_closure.meth): Delete.
2007-03-05 Andrew Haley <aph@redhat.com> * java/lang/reflect/natVMProxy.cc (ncode_closure.meth): Delete. (generateProxyClass): Don't pass method to ncode. (run_proxy): Call _Jv_GetReflectedMethod to find the proxy method. * java/lang/reflect/Method.h: Rebuild. * java/lang/reflect/Method.java (internalGetParameterTypes, internalGetExceptionTypes): New methods. * headers.txt (class java/lang/reflect/Method): Declare _Jv_GetReflectedMethod. Be its friend. * java/lang/natClass.cc (_Jv_GetReflectedMethod): New method. * java/lang/Class.h: Declare it. Be its friend. From-SVN: r122554
This commit is contained in:
parent
f4a2a1deec
commit
a29114a3be
8 changed files with 83 additions and 13 deletions
|
@ -225,6 +225,9 @@ jboolean _Jv_InterfaceAssignableFrom (jclass, jclass);
|
|||
|
||||
_Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*, jclass * = NULL);
|
||||
java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass klass,
|
||||
_Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature);
|
||||
jfieldID JvGetFirstInstanceField (jclass);
|
||||
jint JvNumInstanceFields (jclass);
|
||||
jfieldID JvGetFirstStaticField (jclass);
|
||||
|
@ -529,6 +532,9 @@ private:
|
|||
|
||||
friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*, jclass *);
|
||||
friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass klass,
|
||||
_Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature);
|
||||
friend jfieldID (::JvGetFirstInstanceField) (jclass);
|
||||
friend jint (::JvNumInstanceFields) (jclass);
|
||||
friend jfieldID (::JvGetFirstStaticField) (jclass);
|
||||
|
|
|
@ -1630,6 +1630,26 @@ _Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
_Jv_GetReflectedMethod (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature)
|
||||
{
|
||||
for (; klass; klass = klass->getSuperclass())
|
||||
{
|
||||
_Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
|
||||
if (meth)
|
||||
{
|
||||
using namespace java::lang::reflect;
|
||||
Method *rmethod = new Method ();
|
||||
rmethod->offset = (char*) meth - (char*) klass->methods;
|
||||
rmethod->declaringClass = klass;
|
||||
return rmethod;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
|
||||
// NOTE: MCACHE_SIZE should be a power of 2 minus one.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
|
||||
jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
|
||||
::java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
|
||||
|
||||
class java::lang::reflect::Method : public ::java::lang::reflect::AccessibleObject
|
||||
{
|
||||
|
@ -29,7 +30,13 @@ public:
|
|||
jboolean isVarArgs();
|
||||
::java::lang::Class * getReturnType();
|
||||
JArray< ::java::lang::Class * > * getParameterTypes();
|
||||
public: // actually package-private
|
||||
JArray< ::java::lang::Class * > * internalGetParameterTypes();
|
||||
public:
|
||||
JArray< ::java::lang::Class * > * getExceptionTypes();
|
||||
public: // actually package-private
|
||||
JArray< ::java::lang::Class * > * internalGetExceptionTypes();
|
||||
public:
|
||||
jboolean equals(::java::lang::Object *);
|
||||
jint hashCode();
|
||||
::java::lang::String * toString();
|
||||
|
@ -71,6 +78,7 @@ public:
|
|||
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*);
|
||||
};
|
||||
|
||||
#endif // __java_lang_reflect_Method__
|
||||
|
|
|
@ -153,6 +153,15 @@ public final class Method
|
|||
return (Class<?>[]) parameter_types.clone();
|
||||
}
|
||||
|
||||
// Just like getParameterTypes, but don't clone the array.
|
||||
// Package private for use by VMProxy.
|
||||
final Class<?>[] internalGetParameterTypes ()
|
||||
{
|
||||
if (parameter_types == null)
|
||||
getType();
|
||||
return (Class<?>[]) parameter_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception types this method says it throws, in no particular
|
||||
* order. If the method has no throws clause, returns a 0-length array
|
||||
|
@ -167,6 +176,15 @@ public final class Method
|
|||
return (Class<?>[]) exception_types.clone();
|
||||
}
|
||||
|
||||
// Just like getExceptionTypes, but don't clone the array.
|
||||
// Package private for use by VMProxy.
|
||||
final Class<?>[] internalGetExceptionTypes ()
|
||||
{
|
||||
if (exception_types == null)
|
||||
getType();
|
||||
return (Class<?>[]) exception_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two objects to see if they are semantically equivalent.
|
||||
* Two Methods are semantically equivalent if they have the same declaring
|
||||
|
|
|
@ -66,7 +66,7 @@ using namespace java::lang::reflect;
|
|||
using namespace java::lang;
|
||||
|
||||
typedef void (*closure_fun) (ffi_cif*, void*, void**, void*);
|
||||
static void *ncode (_Jv_Method *self, closure_fun fun, Method *meth);
|
||||
static void *ncode (_Jv_Method *self, closure_fun fun);
|
||||
static void run_proxy (ffi_cif*, void*, void**, void*);
|
||||
|
||||
typedef jobject invoke_t (jobject, Proxy *, Method *, JArray< jobject > *);
|
||||
|
@ -165,7 +165,7 @@ java::lang::reflect::VMProxy::generateProxyClass
|
|||
// the interfaces of which it is a proxy will also be reachable,
|
||||
// so this is safe.
|
||||
method = imethod;
|
||||
method.ncode = ncode (&method, run_proxy, elements(d->methods)[i]);
|
||||
method.ncode = ncode (&method, run_proxy);
|
||||
method.accflags &= ~Modifier::ABSTRACT;
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,6 @@ unbox (jobject o, jclass klass, void *rvalue, FFI_TYPE type)
|
|||
JvFail ("Bad ffi type in proxy");
|
||||
}
|
||||
|
||||
|
||||
// run_proxy is the entry point for all proxy methods. It boxes up
|
||||
// all the arguments and then invokes the invocation handler's invoke()
|
||||
// method. Exceptions are caught and propagated.
|
||||
|
@ -291,7 +290,6 @@ unbox (jobject o, jclass klass, void *rvalue, FFI_TYPE type)
|
|||
typedef struct {
|
||||
ffi_closure closure;
|
||||
ffi_cif cif;
|
||||
Method *meth;
|
||||
_Jv_Method *self;
|
||||
ffi_type *arg_types[0];
|
||||
} ncode_closure;
|
||||
|
@ -313,9 +311,15 @@ run_proxy (ffi_cif *cif,
|
|||
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);
|
||||
JArray<jclass> *parameter_types = meth->internalGetParameterTypes ();
|
||||
JArray<jclass> *exception_types = meth->internalGetExceptionTypes ();
|
||||
|
||||
InvocationHandler *handler = proxy->h;
|
||||
void *poo
|
||||
= _Jv_NewObjectArray (self->meth->parameter_types->length, &Object::class$, NULL);
|
||||
= _Jv_NewObjectArray (parameter_types->length, &Object::class$, NULL);
|
||||
JArray<jobject> *argsArray = (JArray<jobject> *) poo;
|
||||
jobject *jargs = elements(argsArray);
|
||||
|
||||
|
@ -331,14 +335,14 @@ run_proxy (ffi_cif *cif,
|
|||
|
||||
// Copy and box all the args.
|
||||
int index = 1;
|
||||
for (int i = 0; i < self->meth->parameter_types->length; i++, index++)
|
||||
jargs[i] = box (args[index], elements(self->meth->parameter_types)[i],
|
||||
for (int i = 0; i < parameter_types->length; i++, index++)
|
||||
jargs[i] = box (args[index], elements(parameter_types)[i],
|
||||
cif->arg_types[index]->type);
|
||||
|
||||
jobject ret;
|
||||
try
|
||||
{
|
||||
ret = invoke (handler, proxy, self->meth, argsArray);
|
||||
ret = invoke (handler, proxy, meth, argsArray);
|
||||
}
|
||||
catch (Throwable *t)
|
||||
{
|
||||
|
@ -346,15 +350,15 @@ run_proxy (ffi_cif *cif,
|
|||
|| _Jv_IsInstanceOf (t, &Error::class$))
|
||||
throw t;
|
||||
|
||||
Class **throwables = elements (self->meth->exception_types);
|
||||
for (int i = 0; i < self->meth->exception_types->length; i++)
|
||||
Class **throwables = elements (exception_types);
|
||||
for (int i = 0; i < exception_types->length; i++)
|
||||
if (_Jv_IsInstanceOf (t, throwables[i]))
|
||||
throw t;
|
||||
|
||||
throw new UndeclaredThrowableException (t);
|
||||
}
|
||||
|
||||
unbox (ret, self->meth->return_type, rvalue, cif->rtype->type);
|
||||
unbox (ret, meth->return_type, rvalue, cif->rtype->type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -362,7 +366,7 @@ run_proxy (ffi_cif *cif,
|
|||
// the address of its closure.
|
||||
|
||||
static void *
|
||||
ncode (_Jv_Method *self, closure_fun fun, Method *meth)
|
||||
ncode (_Jv_Method *self, closure_fun fun)
|
||||
{
|
||||
using namespace java::lang::reflect;
|
||||
|
||||
|
@ -379,7 +383,6 @@ ncode (_Jv_Method *self, closure_fun fun, Method *meth)
|
|||
&closure->cif,
|
||||
&closure->arg_types[0],
|
||||
NULL);
|
||||
closure->meth = meth;
|
||||
closure->self = self;
|
||||
|
||||
JvAssert ((self->accflags & Modifier::NATIVE) == 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue