aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-05 22:22:10 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-05 22:22:10 +0000
commit431cc03e029c60672e99eb33dfd337e5e7b0c753 (patch)
tree711ec302633170d1f9b65a055721609700aa5fbc /libjava
parentdcf6eb8b028091efbcdd724c03b03633f23bcf0c (diff)
* 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/ChangeLog12
-rw-r--r--libjava/java/lang/Class.h2
-rw-r--r--libjava/java/lang/Class.java1
-rw-r--r--libjava/java/lang/natClass.cc136
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