From 224b7b7b0c8a69e60e87a871a9ed828c99f389d8 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 24 Aug 2001 17:24:44 +0000 Subject: [PATCH] Field.java (toString): Use Method.appendClassName. * java/lang/reflect/Field.java (toString): Use Method.appendClassName. * java/lang/reflect/Constructor.java (toString): Use Method.appendClassName. * java/lang/reflect/Method.java: Reindented. (appendClassName): New method. (toString): Use it. * defineclass.cc (handleMethod ): Initialize `throws' field of method. (read_one_method_attribute): Handle Exceptions attribute. * java/lang/reflect/natMethod.cc (ClassClass): Removed. (ObjectClass): Removed. (getType): Compute `exception_types'. * java/lang/Class.h (struct _Jv_Method): Added `throws' field. From-SVN: r45153 --- libjava/ChangeLog | 17 +++ libjava/defineclass.cc | 39 +++++- libjava/java/lang/Class.h | 8 ++ libjava/java/lang/reflect/Constructor.java | 4 +- libjava/java/lang/reflect/Field.java | 6 +- libjava/java/lang/reflect/Method.java | 140 ++++++++++++--------- libjava/java/lang/reflect/natMethod.cc | 29 +++-- libjava/mauve-libgcj | 1 + 8 files changed, 166 insertions(+), 78 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index f7092d189518..a058e68eb7fc 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,20 @@ +2001-08-23 Tom Tromey + + * java/lang/reflect/Field.java (toString): Use + Method.appendClassName. + * java/lang/reflect/Constructor.java (toString): Use + Method.appendClassName. + * java/lang/reflect/Method.java: Reindented. + (appendClassName): New method. + (toString): Use it. + * defineclass.cc (handleMethod ): Initialize `throws' field of + method. + (read_one_method_attribute): Handle Exceptions attribute. + * java/lang/reflect/natMethod.cc (ClassClass): Removed. + (ObjectClass): Removed. + (getType): Compute `exception_types'. + * java/lang/Class.h (struct _Jv_Method): Added `throws' field. + 2001-08-21 Anthony Green * java/lang/natClassLoader.cc (findClass): Search for diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc index edf14cb098e1..7ef51dc6e2bf 100644 --- a/libjava/defineclass.cc +++ b/libjava/defineclass.cc @@ -526,10 +526,42 @@ void _Jv_ClassReader::read_one_method_attribute (int method_index) if (is_attribute_name (name, "Exceptions")) { - /* we ignore this for now */ - skip (length); + _Jv_Method *method = reinterpret_cast<_Jv_Method *> + (&def->methods[method_index]); + if (method->throws != NULL) + throw_class_format_error ("only one Exceptions attribute allowed per method"); + + int num_exceptions = read2u (); + // We use malloc here because the GC won't scan the method + // objects. FIXME this means a memory leak if we GC a class. + // (Currently we never do.) + _Jv_Utf8Const **exceptions = + (_Jv_Utf8Const **) _Jv_Malloc ((num_exceptions + 1) * sizeof (_Jv_Utf8Const *)); + + int out = 0; + _Jv_word *pool_data = def->constants.data; + for (int i = 0; i < num_exceptions; ++i) + { + try + { + int ndx = read2u (); + // JLS 2nd Ed. 4.7.5 requires that the tag not be 0. + if (ndx != 0) + { + check_tag (ndx, JV_CONSTANT_Class); + exceptions[out++] = pool_data[ndx].utf8; + } + } + catch (java::lang::Throwable *exc) + { + _Jv_Free (exceptions); + throw exc; + } + } + exceptions[out] = NULL; + method->throws = exceptions; } - + else if (is_attribute_name (name, "Code")) { int start_off = pos; @@ -1206,6 +1238,7 @@ void _Jv_ClassReader::handleMethod // intialize... method->ncode = 0; + method->throws = NULL; if (verify) { diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index ac992448df68..dfef0a6afbe2 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -64,10 +64,18 @@ struct _Jv_Constants struct _Jv_Method { + // Method name. _Jv_Utf8Const *name; + // Method signature. _Jv_Utf8Const *signature; + // Access flags. _Jv_ushort accflags; + // Pointer to underlying function. void *ncode; + // NULL-terminated list of exception class names; can be NULL if + // there are none such. + _Jv_Utf8Const **throws; + _Jv_Method *getNextMethod () { return this + 1; } }; diff --git a/libjava/java/lang/reflect/Constructor.java b/libjava/java/lang/reflect/Constructor.java index 2d527c3ba75d..cd07a43f26ef 100644 --- a/libjava/java/lang/reflect/Constructor.java +++ b/libjava/java/lang/reflect/Constructor.java @@ -77,11 +77,11 @@ public final class Constructor extends AccessibleObject implements Member StringBuffer b = new StringBuffer (); b.append(Modifier.toString(getModifiers())); b.append(" "); - b.append(getName()); + Method.appendClassName (b, declaringClass); b.append("("); for (int i = 0; i < parameter_types.length; ++i) { - b.append(parameter_types[i].getName()); + Method.appendClassName (b, parameter_types[i]); if (i < parameter_types.length - 1) b.append(","); } diff --git a/libjava/java/lang/reflect/Field.java b/libjava/java/lang/reflect/Field.java index 76243f30464e..aad51481d5d7 100644 --- a/libjava/java/lang/reflect/Field.java +++ b/libjava/java/lang/reflect/Field.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -257,9 +257,9 @@ public final class Field extends AccessibleObject implements Member Modifier.toString(mods, sbuf); sbuf.append(' '); } - sbuf.append(getType().getName()); + Method.appendClassName (sbuf, getType ()); sbuf.append(' '); - sbuf.append(getDeclaringClass().getName()); + Method.appendClassName (sbuf, getDeclaringClass()); sbuf.append('.'); sbuf.append(getName()); return sbuf.toString(); diff --git a/libjava/java/lang/reflect/Method.java b/libjava/java/lang/reflect/Method.java index e616670e587b..7bd0a3125116 100644 --- a/libjava/java/lang/reflect/Method.java +++ b/libjava/java/lang/reflect/Method.java @@ -25,24 +25,24 @@ import gnu.gcj.RawData; public final class Method extends AccessibleObject implements Member { public boolean equals (Object obj) - { - if (! (obj instanceof Method)) - return false; - Method m = (Method) obj; - return declaringClass == m.declaringClass && offset == m.offset; - } + { + if (! (obj instanceof Method)) + return false; + Method m = (Method) obj; + return declaringClass == m.declaringClass && offset == m.offset; + } public Class getDeclaringClass () - { - return declaringClass; - } + { + return declaringClass; + } public Class[] getExceptionTypes () - { - if (exception_types == null) - getType(); - return (Class[]) exception_types.clone(); - } + { + if (exception_types == null) + getType(); + return (Class[]) exception_types.clone(); + } public native int getModifiers (); @@ -51,62 +51,82 @@ public final class Method extends AccessibleObject implements Member private native void getType (); public Class[] getParameterTypes () - { - if (parameter_types == null) - getType(); - return (Class[]) parameter_types.clone(); - } + { + if (parameter_types == null) + getType(); + return (Class[]) parameter_types.clone(); + } public Class getReturnType () - { - if (return_type == null) - getType(); - return return_type; - } + { + if (return_type == null) + getType(); + return return_type; + } public int hashCode () - { - // FIXME. - return getName().hashCode() + declaringClass.getName().hashCode(); - } + { + // FIXME. + return getName().hashCode() + declaringClass.getName().hashCode(); + } public native Object invoke (Object obj, Object[] args) throws IllegalAccessException, IllegalArgumentException, - InvocationTargetException; + InvocationTargetException; + + // Append a class name to a string buffer. We try to print the + // fully-qualified name, the way that a Java programmer would expect + // it to be written. Weirdly, Class has no appropriate method for + // this. + static void appendClassName (StringBuffer buf, Class k) + { + if (k.isArray ()) + { + appendClassName (buf, k.getComponentType ()); + buf.append ("[]"); + } + else + { + // This is correct for primitive and reference types. Really + // we'd like `Main$Inner' to be printed as `Main.Inner', I + // think, but that is a pain. + buf.append (k.getName ()); + } + } public String toString () - { - if (parameter_types == null) - getType (); + { + if (parameter_types == null) + getType (); - StringBuffer b = new StringBuffer (); - Modifier.toString(getModifiers(), b); - b.append(" "); - b.append(return_type.getName()); - b.append(" "); - b.append(declaringClass.getName()); - b.append("."); - b.append(getName()); - b.append("("); - for (int i = 0; i < parameter_types.length; ++i) - { - b.append(parameter_types[i].getName()); - if (i < parameter_types.length - 1) - b.append(","); - } - b.append(")"); - if (exception_types.length > 0) - { - b.append(" throws "); - for (int i = 0; i < exception_types.length; ++i) - { - b.append(exception_types[i].getName()); - if (i < exception_types.length - 1) - b.append(","); - } - } - return b.toString(); - } + StringBuffer b = new StringBuffer (); + Modifier.toString(getModifiers(), b); + b.append(" "); + appendClassName (b, return_type); + b.append(" "); + appendClassName (b, declaringClass); + b.append("."); + b.append(getName()); + b.append("("); + for (int i = 0; i < parameter_types.length; ++i) + { + appendClassName (b, parameter_types[i]); + if (i < parameter_types.length - 1) + b.append(","); + } + b.append(")"); + if (exception_types.length > 0) + { + b.append(" throws "); + for (int i = 0; i < exception_types.length; ++i) + { + appendClassName (b, exception_types[i]); + if (i < exception_types.length - 1) + b.append(","); + } + } + return b.toString(); + } private Method () { diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc index f269d2fdcf1b..96cc13209ab9 100644 --- a/libjava/java/lang/reflect/natMethod.cc +++ b/libjava/java/lang/reflect/natMethod.cc @@ -1,6 +1,6 @@ // natMethod.cc - Native code for Method class. -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -38,10 +38,6 @@ details. */ #include #include -// FIXME: remove these -#define ObjectClass java::lang::Object::class$ -#define ClassClass java::lang::Class::class$ - #include #if USE_LIBFFI @@ -200,14 +196,27 @@ java::lang::reflect::Method::getName () void java::lang::reflect::Method::getType () { - _Jv_GetTypesFromSignature (_Jv_FromReflectedMethod (this), + _Jv_Method *method = _Jv_FromReflectedMethod (this); + _Jv_GetTypesFromSignature (method, declaringClass, ¶meter_types, &return_type); - // FIXME: for now we have no way to get exception information. - exception_types = (JArray *) JvNewObjectArray (0, &ClassClass, - NULL); + int count = 0; + if (method->throws != NULL) + { + while (method->throws[count] != NULL) + ++count; + } + + exception_types + = (JArray *) JvNewObjectArray (count, + &java::lang::Class::class$, + NULL); + jclass *elts = elements (exception_types); + for (int i = 0; i < count; ++i) + elts[i] = _Jv_FindClassFromSignature (method->throws[i]->data, + declaringClass->getClassLoader ()); } void @@ -254,7 +263,7 @@ _Jv_GetTypesFromSignature (jmethodID method, } JArray *args = (JArray *) - JvNewObjectArray (numArgs, &ClassClass, NULL); + JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL); jclass* argPtr = elements (args); for (ptr = sig->data; *ptr != '\0'; ptr++) { diff --git a/libjava/mauve-libgcj b/libjava/mauve-libgcj index f073835c3844..a80405cf2dfe 100644 --- a/libjava/mauve-libgcj +++ b/libjava/mauve-libgcj @@ -32,3 +32,4 @@ java.text.StringCharacterIterator.iter !java.text.DecimalFormatSymbols.DumpDefault12 !java.text.DecimalFormatSymbols.GetSet12 !java.text.resources +!java.lang.Math