diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-05 22:22:10 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-05 22:22:10 +0000 |
commit | 431cc03e029c60672e99eb33dfd337e5e7b0c753 (patch) | |
tree | 711ec302633170d1f9b65a055721609700aa5fbc /libjava | |
parent | dcf6eb8b028091efbcdd724c03b03633f23bcf0c (diff) | |
download | gcc-431cc03e029c60672e99eb33dfd337e5e7b0c753.tar.gz |
* java/lang/Class.h (_getMethods): Declare.
* java/lang/Class.java (_getMethods): Declare.
* java/lang/natClass.cc (getDeclaringClass): Always return NULL.
(getDeclaredClasses): Always return empty array.
(_getMethods): New method.
(getMethods): Wrote.
(getDeclaredMethod): Return `rmethod'.
(finit_name): New global.
(getDeclaredMethods): Check for finit_name.
(_getMethods): Likewise.
(getMethod): Only return public methods.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31245 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 12 | ||||
-rw-r--r-- | libjava/java/lang/Class.h | 2 | ||||
-rw-r--r-- | libjava/java/lang/Class.java | 1 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 136 |
4 files changed, 143 insertions, 8 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 2683e1ada5e..f0d0957c069 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,17 @@ 2000-01-05 Tom Tromey <tromey@cygnus.com> + * java/lang/Class.h (_getMethods): Declare. + * java/lang/Class.java (_getMethods): Declare. + * java/lang/natClass.cc (getDeclaringClass): Always return NULL. + (getDeclaredClasses): Always return empty array. + (_getMethods): New method. + (getMethods): Wrote. + (getDeclaredMethod): Return `rmethod'. + (finit_name): New global. + (getDeclaredMethods): Check for finit_name. + (_getMethods): Likewise. + (getMethod): Only return public methods. + * java/lang/reflect/natMethod.cc (get_ffi_type): Test size of jboolean and select correct ffi type on that basis. (_Jv_CallNonvirtualMethodA): Handle `void' return type. diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index 0b43ad31727..573683de215 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -105,6 +105,8 @@ public: void getSignature (java::lang::StringBuffer *buffer); static jstring getSignature (JArray<jclass> *, jboolean is_constructor); java::lang::reflect::Method *getMethod (jstring, JArray<jclass> *); + jint _getMethods (JArray<java::lang::reflect::Method *> *result, + jint offset); JArray<java::lang::reflect::Method *> *getMethods (void); jint getModifiers (void) diff --git a/libjava/java/lang/Class.java b/libjava/java/lang/Class.java index 4c49cd93b35..127cc52457d 100644 --- a/libjava/java/lang/Class.java +++ b/libjava/java/lang/Class.java @@ -94,6 +94,7 @@ public final class Class implements Serializable public native Method getMethod (String methodName, Class[] parameterTypes) throws NoSuchMethodException, SecurityException; + private native int _getMethods (Method[] result, int offset); public native Method[] getMethods () throws SecurityException; public native int getModifiers (); diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index 152be02b7ce..8362dcc079e 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -63,6 +63,7 @@ extern java::lang::Class ConstructorClass; static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3); static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8); static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6); +static _Jv_Utf8Const *finit_name = _Jv_makeUtf8Const ("$finit$", 7); @@ -310,6 +311,7 @@ java::lang::Class::getDeclaredMethod (jstring name, Method *rmethod = new Method (); rmethod->offset = (char*) (&methods[i]) - (char*) methods; rmethod->declaringClass = this; + return rmethod; } } JvThrow (new java::lang::NoSuchMethodException); @@ -326,7 +328,8 @@ java::lang::Class::getDeclaredMethods (void) _Jv_Method *method = &methods[i]; if (method->name == NULL || _Jv_equalUtf8Consts (method->name, clinit_name) - || _Jv_equalUtf8Consts (method->name, init_name)) + || _Jv_equalUtf8Consts (method->name, init_name) + || _Jv_equalUtf8Consts (method->name, finit_name)) continue; numMethods++; } @@ -339,7 +342,8 @@ java::lang::Class::getDeclaredMethods (void) _Jv_Method *method = &methods[i]; if (method->name == NULL || _Jv_equalUtf8Consts (method->name, clinit_name) - || _Jv_equalUtf8Consts (method->name, init_name)) + || _Jv_equalUtf8Consts (method->name, init_name) + || _Jv_equalUtf8Consts (method->name, finit_name)) continue; java::lang::reflect::Method* rmethod = new java::lang::reflect::Method (); @@ -370,16 +374,19 @@ JArray<jclass> * java::lang::Class::getDeclaredClasses (void) { checkMemberAccess (java::lang::reflect::Member::DECLARED); - JvFail ("java::lang::Class::getDeclaredClasses not implemented"); - return NULL; // Placate compiler. + // Until we have inner classes, it always makes sense to return an + // empty array. + JArray<jclass> *result + = (JArray<jclass> *) JvNewObjectArray (0, &ClassClass, NULL); + return result; } -// This is marked as unimplemented in the JCL book. jclass java::lang::Class::getDeclaringClass (void) { - JvFail ("java::lang::Class::getDeclaringClass unimplemented"); - return NULL; // Placate compiler. + // Until we have inner classes, it makes sense to always return + // NULL. + return NULL; } jint @@ -463,6 +470,11 @@ java::lang::Class::getMethod (jstring name, JArray<jclass> *param_types) { // Found it. using namespace java::lang::reflect; + + // Method must be public. + if (! Modifier::isPublic (methods[i].accflags)) + break; + Method *rmethod = new Method (); rmethod->offset = (char*) (&klass->methods[i]) - (char*) methods; rmethod->declaringClass = klass; @@ -473,10 +485,118 @@ java::lang::Class::getMethod (jstring name, JArray<jclass> *param_types) JvThrow (new java::lang::NoSuchMethodException); } +// This is a very slow implementation, since it re-scans all the +// methods we've already listed to make sure we haven't duplicated a +// method. It also over-estimates the required size, so we have to +// shrink the result array later. +jint +java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result, + jint offset) +{ + jint count = 0; + + // First examine all local methods + for (int i = isPrimitive () ? 0 : method_count; --i >= 0; ) + { + _Jv_Method *method = &methods[i]; + if (method->name == NULL + || _Jv_equalUtf8Consts (method->name, clinit_name) + || _Jv_equalUtf8Consts (method->name, init_name) + || _Jv_equalUtf8Consts (method->name, finit_name)) + continue; + // Only want public methods. + if (! java::lang::reflect::Modifier::isPublic (method->accflags)) + continue; + + // This is where we over-count the slots required if we aren't + // filling the result for real. + if (result != NULL) + { + jboolean add = true; + java::lang::reflect::Method **mp = elements (result); + // If we already have a method with this name and signature, + // then ignore this one. This can happen with virtual + // methods. + for (int j = 0; j < offset; ++j) + { + _Jv_Method *meth_2 = _Jv_FromReflectedMethod (mp[j]); + if (_Jv_equalUtf8Consts (method->name, meth_2->name) + && _Jv_equalUtf8Consts (method->signature, + meth_2->signature)) + { + add = false; + break; + } + } + if (! add) + continue; + } + + if (result != NULL) + { + using namespace java::lang::reflect; + Method *rmethod = new Method (); + rmethod->offset = (char *) method - (char *) methods; + rmethod->declaringClass = this; + Method **mp = elements (result); + mp[offset + count] = rmethod; + } + ++count; + } + offset += count; + + // Now examine superclasses. + if (getSuperclass () != NULL) + { + jint s_count = getSuperclass()->_getMethods (result, offset); + offset += s_count; + count += s_count; + } + + // Finally, examine interfaces. + for (int i = 0; i < interface_count; ++i) + { + int f_count = interfaces[i]->_getMethods (result, offset); + count += f_count; + offset += f_count; + } + + return count; +} + JArray<java::lang::reflect::Method *> * java::lang::Class::getMethods (void) { - JvFail ("java::lang::Class::getMethods not implemented"); + using namespace java::lang::reflect; + + // FIXME: security checks. + + // This will overestimate the size we need. + jint count = _getMethods (NULL, 0); + + JArray<Method *> *result + = ((JArray<Method *> *) JvNewObjectArray (count, &MethodClass, NULL)); + + // When filling the array for real, we get the actual count. Then + // we resize the array. + jint real_count = _getMethods (result, 0); + + if (real_count != count) + { + JArray<Method *> *r2 + = ((JArray<Method *> *) JvNewObjectArray (real_count, &MethodClass, + NULL)); + + Method **destp = elements (r2); + Method **srcp = elements (result); + + for (int i = 0; i < real_count; ++i) + *destp++ = *srcp++; + + result = r2; + } + + return result; } jboolean |