summaryrefslogtreecommitdiff
path: root/libjava/java/lang/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/reflect')
-rw-r--r--libjava/java/lang/reflect/AccessibleObject.h36
-rw-r--r--libjava/java/lang/reflect/AnnotatedElement.h24
-rw-r--r--libjava/java/lang/reflect/Array.h46
-rw-r--r--libjava/java/lang/reflect/Array.java458
-rw-r--r--libjava/java/lang/reflect/Constructor.h65
-rw-r--r--libjava/java/lang/reflect/Constructor.java424
-rw-r--r--libjava/java/lang/reflect/Field.h98
-rw-r--r--libjava/java/lang/reflect/Field.java817
-rw-r--r--libjava/java/lang/reflect/GenericArrayType.h19
-rw-r--r--libjava/java/lang/reflect/GenericDeclaration.h21
-rw-r--r--libjava/java/lang/reflect/GenericSignatureFormatError.h22
-rw-r--r--libjava/java/lang/reflect/InvocationHandler.h21
-rw-r--r--libjava/java/lang/reflect/InvocationTargetException.h28
-rw-r--r--libjava/java/lang/reflect/MalformedParameterizedTypeException.h22
-rw-r--r--libjava/java/lang/reflect/Member.h24
-rw-r--r--libjava/java/lang/reflect/Method.h84
-rw-r--r--libjava/java/lang/reflect/Method.java501
-rw-r--r--libjava/java/lang/reflect/Modifier.h58
-rw-r--r--libjava/java/lang/reflect/Modifier.java375
-rw-r--r--libjava/java/lang/reflect/ParameterizedType.h23
-rw-r--r--libjava/java/lang/reflect/Proxy$ClassFactory.h78
-rw-r--r--libjava/java/lang/reflect/Proxy$ProxyData.h37
-rw-r--r--libjava/java/lang/reflect/Proxy$ProxySignature.h28
-rw-r--r--libjava/java/lang/reflect/Proxy$ProxyType.h28
-rw-r--r--libjava/java/lang/reflect/Proxy.h32
-rw-r--r--libjava/java/lang/reflect/ReflectPermission.h23
-rw-r--r--libjava/java/lang/reflect/Type.h18
-rw-r--r--libjava/java/lang/reflect/TypeVariable.h23
-rw-r--r--libjava/java/lang/reflect/UndeclaredThrowableException.h26
-rw-r--r--libjava/java/lang/reflect/VMProxy.h28
-rw-r--r--libjava/java/lang/reflect/VMProxy.java140
-rw-r--r--libjava/java/lang/reflect/WildcardType.h22
-rw-r--r--libjava/java/lang/reflect/natArray.cc360
-rw-r--r--libjava/java/lang/reflect/natConstructor.cc93
-rw-r--r--libjava/java/lang/reflect/natField.cc449
-rw-r--r--libjava/java/lang/reflect/natMethod.cc701
-rw-r--r--libjava/java/lang/reflect/natVMProxy.cc459
37 files changed, 5711 insertions, 0 deletions
diff --git a/libjava/java/lang/reflect/AccessibleObject.h b/libjava/java/lang/reflect/AccessibleObject.h
new file mode 100644
index 000000000..d140e300c
--- /dev/null
+++ b/libjava/java/lang/reflect/AccessibleObject.h
@@ -0,0 +1,36 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_AccessibleObject__
+#define __java_lang_reflect_AccessibleObject__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::AccessibleObject : public ::java::lang::Object
+{
+
+public: // actually protected
+ AccessibleObject();
+public:
+ virtual jboolean isAccessible();
+ static void setAccessible(JArray< ::java::lang::reflect::AccessibleObject * > *, jboolean);
+ virtual void setAccessible(jboolean);
+private:
+ static void checkPermission();
+ void secureSetAccessible(jboolean);
+public:
+ virtual ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ virtual JArray< ::java::lang::annotation::Annotation * > * getAnnotations();
+ virtual JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ virtual jboolean isAnnotationPresent(::java::lang::Class *);
+public: // actually package-private
+ jboolean __attribute__((aligned(__alignof__( ::java::lang::Object)))) flag;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_AccessibleObject__
diff --git a/libjava/java/lang/reflect/AnnotatedElement.h b/libjava/java/lang/reflect/AnnotatedElement.h
new file mode 100644
index 000000000..5792b75e0
--- /dev/null
+++ b/libjava/java/lang/reflect/AnnotatedElement.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_AnnotatedElement__
+#define __java_lang_reflect_AnnotatedElement__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::AnnotatedElement : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *) = 0;
+ virtual JArray< ::java::lang::annotation::Annotation * > * getAnnotations() = 0;
+ virtual JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations() = 0;
+ virtual jboolean isAnnotationPresent(::java::lang::Class *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_AnnotatedElement__
diff --git a/libjava/java/lang/reflect/Array.h b/libjava/java/lang/reflect/Array.h
new file mode 100644
index 000000000..48df7d3fa
--- /dev/null
+++ b/libjava/java/lang/reflect/Array.h
@@ -0,0 +1,46 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Array__
+#define __java_lang_reflect_Array__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Array : public ::java::lang::Object
+{
+
+ Array();
+public:
+ static ::java::lang::Object * newInstance(::java::lang::Class *, jint);
+ static ::java::lang::Object * newInstance(::java::lang::Class *, JArray< jint > *);
+ static jint getLength(::java::lang::Object *);
+ static ::java::lang::Object * get(::java::lang::Object *, jint);
+ static jboolean getBoolean(::java::lang::Object *, jint);
+ static jbyte getByte(::java::lang::Object *, jint);
+ static jchar getChar(::java::lang::Object *, jint);
+ static jshort getShort(::java::lang::Object *, jint);
+ static jint getInt(::java::lang::Object *, jint);
+ static jlong getLong(::java::lang::Object *, jint);
+ static jfloat getFloat(::java::lang::Object *, jint);
+ static jdouble getDouble(::java::lang::Object *, jint);
+private:
+ static ::java::lang::Class * getElementType(::java::lang::Object *, jint);
+ static void set(::java::lang::Object *, jint, ::java::lang::Object *, ::java::lang::Class *);
+public:
+ static void set(::java::lang::Object *, jint, ::java::lang::Object *);
+ static void setBoolean(::java::lang::Object *, jint, jboolean);
+ static void setByte(::java::lang::Object *, jint, jbyte);
+ static void setChar(::java::lang::Object *, jint, jchar);
+ static void setShort(::java::lang::Object *, jint, jshort);
+ static void setInt(::java::lang::Object *, jint, jint);
+ static void setLong(::java::lang::Object *, jint, jlong);
+ static void setFloat(::java::lang::Object *, jint, jfloat);
+ static void setDouble(::java::lang::Object *, jint, jdouble);
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Array__
diff --git a/libjava/java/lang/reflect/Array.java b/libjava/java/lang/reflect/Array.java
new file mode 100644
index 000000000..639cc0e02
--- /dev/null
+++ b/libjava/java/lang/reflect/Array.java
@@ -0,0 +1,458 @@
+/* java.lang.reflect.Array - manipulate arrays by reflection
+ Copyright (C) 1998, 1999, 2001, 2003, 2005, 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Array holds static helper functions that allow you to create and
+ * manipulate arrays by reflection. Operations know how to perform widening
+ * conversions, but throw {@link IllegalArgumentException} if you attempt
+ * a narrowing conversion. Also, when accessing primitive arrays, this
+ * class performs object wrapping and unwrapping as necessary.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes. Note also that the shorthand <code>Object[].class</code>
+ * is a convenient way to get array Classes.<p>
+ *
+ * <B>Performance note:</B> This class performs best when it does not have
+ * to convert primitive types. The further along the chain it has to convert,
+ * the worse performance will be. You're best off using the array as whatever
+ * type it already is, and then converting the result. You will do even
+ * worse if you do this and use the generic set() function.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @see java.lang.Boolean#TYPE
+ * @see java.lang.Byte#TYPE
+ * @see java.lang.Short#TYPE
+ * @see java.lang.Character#TYPE
+ * @see java.lang.Integer#TYPE
+ * @see java.lang.Long#TYPE
+ * @see java.lang.Float#TYPE
+ * @see java.lang.Double#TYPE
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Array
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangreflect");
+ }
+ }
+
+ /**
+ * This class is uninstantiable.
+ */
+ private Array()
+ {
+ }
+
+ /**
+ * Creates a new single-dimensioned array.
+ * @param componentType the type of the array to create
+ * @param length the length of the array to create
+ * @return the created array, cast to an Object
+ * @throws NullPointerException if <code>componentType</code> is null
+ * @throws IllegalArgumentException if <code>componentType</code> is
+ * <code>Void.TYPE</code>
+ * @throws NegativeArraySizeException when length is less than 0
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ public static native Object newInstance(Class<?> componentType, int length);
+
+ /**
+ * Creates a new multi-dimensioned array. The new array has the same
+ * component type as the argument class, and the number of dimensions
+ * in the new array is the sum of the dimensions of the argument class
+ * and the length of the argument dimensions. Virtual Machine limitations
+ * forbid too many dimensions (usually 255 is the maximum); but even
+ * 50 dimensions of 2 elements in each dimension would exceed your memory
+ * long beforehand!
+ *
+ * @param componentType the type of the array to create.
+ * @param dimensions the dimensions of the array to create. Each element
+ * in <code>dimensions</code> makes another dimension of the new
+ * array. Thus, <code>Array.newInstance(java.lang.Boolean,
+ * new int[]{1,2,3})</code> is the same as
+ * <code>new java.lang.Boolean[1][2][3]</code>
+ * @return the created array, cast to an Object
+ * @throws NullPointerException if componentType or dimension is null
+ * @throws IllegalArgumentException if the the size of
+ * <code>dimensions</code> is 0 or exceeds the maximum number of
+ * array dimensions in the VM; or if componentType is Void.TYPE
+ * @throws NegativeArraySizeException when any of the dimensions is less
+ * than 0
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ public static native Object newInstance(Class<?> elementType, int[] dimensions);
+
+ /**
+ * Gets the array length.
+ * @param array the array
+ * @return the length of the array
+ * @throws IllegalArgumentException if <code>array</code> is not an array
+ * @throws NullPointerException if <code>array</code> is null
+ */
+ public static native int getLength(Object array);
+
+ /**
+ * Gets an element of an array. Primitive elements will be wrapped in
+ * the corresponding class type.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not an array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #getBoolean(Object, int)
+ * @see #getByte(Object, int)
+ * @see #getChar(Object, int)
+ * @see #getShort(Object, int)
+ * @see #getInt(Object, int)
+ * @see #getLong(Object, int)
+ * @see #getFloat(Object, int)
+ * @see #getDouble(Object, int)
+ */
+ public static native Object get(Object array, int index);
+
+ /**
+ * Gets an element of a boolean array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the boolean element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a boolean
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native boolean getBoolean(Object array, int index);
+
+ /**
+ * Gets an element of a byte array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the byte element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native byte getByte(Object array, int index);
+
+ /**
+ * Gets an element of a char array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the char element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a char
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native char getChar(Object array, int index);
+
+ /**
+ * Gets an element of a short array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the short element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte
+ * or char array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native short getShort(Object array, int index);
+
+ /**
+ * Gets an element of an int array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the int element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, or int array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native int getInt(Object array, int index);
+
+ /**
+ * Gets an element of a long array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the long element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, or long array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native long getLong(Object array, int index);
+
+ /**
+ * Gets an element of a float array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the float element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, long, or float array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native float getFloat(Object array, int index);
+
+ /**
+ * Gets an element of a double array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the double element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native double getDouble(Object array, int index);
+
+ private static native Class getElementType(Object array, int index);
+
+ private static native void set(Object array, int index,
+ Object value, Class elType);
+
+ /**
+ * Sets an element of an array. If the array is primitive, then the new
+ * value is unwrapped and widened.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not an array,
+ * or the array is primitive and unwrapping value fails, or the
+ * value is not assignable to the array component type
+ * @throws NullPointerException if array is null, or if array is primitive
+ * and value is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #setBoolean(Object, int, boolean)
+ * @see #setByte(Object, int, byte)
+ * @see #setChar(Object, int, char)
+ * @see #setShort(Object, int, short)
+ * @see #setInt(Object, int, int)
+ * @see #setLong(Object, int, long)
+ * @see #setFloat(Object, int, float)
+ * @see #setDouble(Object, int, double)
+ */
+ public static void set(Object array, int index, Object value)
+ {
+ Class elType = getElementType(array, index);
+ if (! elType.isPrimitive())
+ set(array, index, value, elType);
+ else if (value instanceof Byte)
+ setByte(array, index, ((Byte) value).byteValue());
+ else if (value instanceof Short)
+ setShort(array, index, ((Short) value).shortValue());
+ else if (value instanceof Integer)
+ setInt(array, index, ((Integer) value).intValue());
+ else if (value instanceof Long)
+ setLong(array, index, ((Long) value).longValue());
+ else if (value instanceof Float)
+ setFloat(array, index, ((Float) value).floatValue());
+ else if (value instanceof Double)
+ setDouble(array, index, ((Double) value).doubleValue());
+ else if (value instanceof Character)
+ setChar(array, index, ((Character) value).charValue());
+ else if (value instanceof Boolean)
+ setBoolean(array, index, ((Boolean) value).booleanValue());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Sets an element of a boolean array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a boolean
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setBoolean(Object array, int index, boolean value);
+
+ /**
+ * Sets an element of a byte array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * short, int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setByte(Object array, int index, byte value);
+
+ /**
+ * Sets an element of a char array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a char,
+ * int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setChar(Object array, int index, char value);
+
+ /**
+ * Sets an element of a short array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a short,
+ * int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setShort(Object array, int index, short value);
+
+ /**
+ * Sets an element of an int array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not an int,
+ * long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setInt(Object array, int index, int value);
+
+ /**
+ * Sets an element of a long array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a long,
+ * float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setLong(Object array, int index, long value);
+
+ /**
+ * Sets an element of a float array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a float
+ * or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setFloat(Object array, int index, float value);
+
+ /**
+ * Sets an element of a double array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a double
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setDouble(Object array, int index, double value);
+}
diff --git a/libjava/java/lang/reflect/Constructor.h b/libjava/java/lang/reflect/Constructor.h
new file mode 100644
index 000000000..5a200bc11
--- /dev/null
+++ b/libjava/java/lang/reflect/Constructor.h
@@ -0,0 +1,65 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Constructor__
+#define __java_lang_reflect_Constructor__
+
+#pragma interface
+
+#include <java/lang/reflect/AccessibleObject.h>
+#include <gcj/array.h>
+
+
+jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
+jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+
+class java::lang::reflect::Constructor : public ::java::lang::reflect::AccessibleObject
+{
+
+ Constructor();
+public:
+ ::java::lang::Class * getDeclaringClass();
+ ::java::lang::String * getName();
+private:
+ jint getModifiersInternal();
+public:
+ jint getModifiers();
+ jboolean isSynthetic();
+ jboolean isVarArgs();
+ JArray< ::java::lang::Class * > * getParameterTypes();
+ JArray< ::java::lang::Class * > * getExceptionTypes();
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+ ::java::lang::String * toString();
+public: // actually package-private
+ static void addTypeParameters(::java::lang::StringBuilder *, JArray< ::java::lang::reflect::TypeVariable * > *);
+public:
+ ::java::lang::String * toGenericString();
+ ::java::lang::Object * newInstance(JArray< ::java::lang::Object * > *);
+ JArray< ::java::lang::reflect::TypeVariable * > * getTypeParameters();
+private:
+ ::java::lang::String * getSignature();
+public:
+ JArray< ::java::lang::reflect::Type * > * getGenericExceptionTypes();
+ JArray< ::java::lang::reflect::Type * > * getGenericParameterTypes();
+ ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotations();
+private:
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotationsInternal();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotationsInternal();
+ void getType();
+ static const jint CONSTRUCTOR_MODIFIERS = 7;
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::reflect::AccessibleObject)))) declaringClass;
+ JArray< ::java::lang::Class * > * exception_types;
+ JArray< ::java::lang::Class * > * parameter_types;
+ jint offset;
+public:
+ static ::java::lang::Class class$;
+
+ friend jmethodID (::_Jv_FromReflectedConstructor) (java::lang::reflect::Constructor *);
+ friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
+ friend class java::lang::Class;
+};
+
+#endif // __java_lang_reflect_Constructor__
diff --git a/libjava/java/lang/reflect/Constructor.java b/libjava/java/lang/reflect/Constructor.java
new file mode 100644
index 000000000..adebc600a
--- /dev/null
+++ b/libjava/java/lang/reflect/Constructor.java
@@ -0,0 +1,424 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+import java.lang.annotation.Annotation;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Tom Tromey <tromey@redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor<T> extends AccessibleObject
+ implements Member, GenericDeclaration
+{
+ private static final int CONSTRUCTOR_MODIFIERS
+ = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+ /**
+ * This class is uninstantiable except from native code.
+ */
+ private Constructor ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this constructor.
+ * @return the class that declared this member
+ */
+ public Class<T> getDeclaringClass ()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this constructor (the non-qualified name of the class
+ * it was declared in).
+ * @return the name of this constructor
+ */
+ public String getName()
+ {
+ return declaringClass.getName();
+ }
+
+ /**
+ * Return the raw modifiers for this constructor. In particular
+ * this will include the synthetic and varargs bits.
+ * @return the constructor's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
+ * class to interpret the values. A constructor can only have a subset of the
+ * following modifiers: public, private, protected.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers ()
+ {
+ return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+ }
+
+ /**
+ * Return true if this constructor is synthetic, false otherwise.
+ * A synthetic member is one which is created by the compiler,
+ * and which does not appear in the user's source code.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs constructor, that is if
+ * the constructor takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Get the parameter list for this constructor, in declaration order. If the
+ * constructor takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the constructor's parameters
+ */
+ public Class<?>[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType ();
+ return (Class<?>[]) parameter_types.clone();
+ }
+
+ /**
+ * Get the exception types this constructor says it throws, in no particular
+ * order. If the constructor has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the constructor's throws clause
+ */
+ public Class<?>[] getExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ return (Class<?>[]) exception_types.clone();
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Constructors are semantically equivalent if they have the same
+ * declaring class and the same parameter list.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not.
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Constructor))
+ return false;
+ Constructor c = (Constructor) obj;
+ return declaringClass == c.declaringClass && offset == c.offset;
+ }
+
+ /**
+ * Get the hash code for the Constructor. The Constructor hash code is the
+ * hash code of the declaring class's name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode ()
+ {
+ return declaringClass.getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Constructor. A Constructor's String
+ * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
+ * throws &lt;exceptions&gt;", where everything after ')' is omitted if
+ * there are no exceptions.<br> Example:
+ * <code>public java.io.FileInputStream(java.lang.Runnable)
+ * throws java.io.FileNotFoundException</code>
+ *
+ * @return the String representation of the Constructor
+ */
+ public String toString()
+ {
+ if (parameter_types == null)
+ getType ();
+ StringBuffer b = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, b);
+ b.append(" ");
+ }
+ Method.appendClassName (b, declaringClass);
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ Method.appendClassName (b, parameter_types[i]);
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ return b.toString();
+ }
+
+ static <X extends GenericDeclaration>
+ void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
+ {
+ if (typeArgs.length == 0)
+ return;
+ sb.append('<');
+ for (int i = 0; i < typeArgs.length; ++i)
+ {
+ if (i > 0)
+ sb.append(',');
+ sb.append(typeArgs[i]);
+ }
+ sb.append("> ");
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ addTypeParameters(sb, getTypeParameters());
+ sb.append(getDeclaringClass().getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; ++i)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Create a new instance by invoking the constructor. Arguments are
+ * automatically unwrapped and widened, if needed.<p>
+ *
+ * If this class is abstract, you will get an
+ * <code>InstantiationException</code>. If the constructor takes 0
+ * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * If this Constructor enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not create this object in similar compiled code. If the class
+ * is uninitialized, you trigger class initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Then, the constructor is invoked. If it completes normally, the return
+ * value will be the new object. If it completes abruptly, the exception is
+ * wrapped in an <code>InvocationTargetException</code>.
+ *
+ * @param args the arguments to the constructor
+ * @return the newly created object
+ * @throws IllegalAccessException if the constructor could not normally be
+ * called by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * or if the arguments types are wrong even with a widening
+ * conversion
+ * @throws InstantiationException if the class is abstract
+ * @throws InvocationTargetException if the constructor throws an exception
+ * @throws ExceptionInInitializerError if construction triggered class
+ * initialization, which then failed
+ */
+ public native T newInstance (Object... args)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor has no type
+ * variables.
+ *
+ * @return the type variables associated with this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Constructor<T>>[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this constructor. If there
+ * is no Signature attribute, return null.
+ */
+ private native String getSignature();
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this constructor, in declaration order.
+ * An array of size zero is returned if this constructor takes no
+ * parameters.
+ *
+ * @return a list of the types of the constructor's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annoClass)
+ {
+ Annotation[] annos = getDeclaredAnnotations();
+ for (int i = 0; i < annos.length; ++i)
+ if (annos[i].annotationType() == annoClass)
+ return (T) annos[i];
+ return null;
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ public Annotation[][] getParameterAnnotations()
+ {
+ // FIXME: should check that we have the right number
+ // of parameters ...?
+ Annotation[][] result = getParameterAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0][0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+ private native Annotation[][] getParameterAnnotationsInternal();
+
+ // Update cached values from method descriptor in class.
+ private native void getType ();
+
+ // Declaring class.
+ private Class<T> declaringClass;
+
+ // Exception types.
+ private Class[] exception_types;
+ // Parameter types.
+ private Class[] parameter_types;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/libjava/java/lang/reflect/Field.h b/libjava/java/lang/reflect/Field.h
new file mode 100644
index 000000000..0af95652d
--- /dev/null
+++ b/libjava/java/lang/reflect/Field.h
@@ -0,0 +1,98 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Field__
+#define __java_lang_reflect_Field__
+
+#pragma interface
+
+#include <java/lang/reflect/AccessibleObject.h>
+#include <gcj/array.h>
+
+
+jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID, jboolean);
+jobject _Jv_getFieldInternal (java::lang::reflect::Field *f, jclass c, jobject o);
+
+class java::lang::reflect::Field : public ::java::lang::reflect::AccessibleObject
+{
+
+public: // actually package-private
+ Field();
+public:
+ ::java::lang::Class * getDeclaringClass();
+ ::java::lang::String * getName();
+private:
+ jint getModifiersInternal();
+public:
+ jint getModifiers();
+ jboolean isSynthetic();
+ jboolean isEnumConstant();
+ ::java::lang::Class * getType();
+ jboolean equals(::java::lang::Object *);
+ jint hashCode();
+ ::java::lang::String * toString();
+ ::java::lang::String * toGenericString();
+ ::java::lang::Object * get(::java::lang::Object *);
+ jboolean getBoolean(::java::lang::Object *);
+ jbyte getByte(::java::lang::Object *);
+ jchar getChar(::java::lang::Object *);
+ jshort getShort(::java::lang::Object *);
+ jint getInt(::java::lang::Object *);
+ jlong getLong(::java::lang::Object *);
+ jfloat getFloat(::java::lang::Object *);
+ jdouble getDouble(::java::lang::Object *);
+private:
+ jboolean getBoolean(::java::lang::Class *, ::java::lang::Object *);
+ jchar getChar(::java::lang::Class *, ::java::lang::Object *);
+ jbyte getByte(::java::lang::Class *, ::java::lang::Object *);
+ jshort getShort(::java::lang::Class *, ::java::lang::Object *);
+ jint getInt(::java::lang::Class *, ::java::lang::Object *);
+ jlong getLong(::java::lang::Class *, ::java::lang::Object *);
+ jfloat getFloat(::java::lang::Class *, ::java::lang::Object *);
+ jdouble getDouble(::java::lang::Class *, ::java::lang::Object *);
+ ::java::lang::Object * get(::java::lang::Class *, ::java::lang::Object *);
+public:
+ void set(::java::lang::Object *, ::java::lang::Object *);
+ void setBoolean(::java::lang::Object *, jboolean);
+ void setByte(::java::lang::Object *, jbyte);
+ void setChar(::java::lang::Object *, jchar);
+ void setShort(::java::lang::Object *, jshort);
+ void setInt(::java::lang::Object *, jint);
+ void setLong(::java::lang::Object *, jlong);
+ void setFloat(::java::lang::Object *, jfloat);
+ void setDouble(::java::lang::Object *, jdouble);
+ ::java::lang::reflect::Type * getGenericType();
+ ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+private:
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotationsInternal();
+ ::java::lang::String * getSignature();
+public: // actually package-private
+ void setByte(::java::lang::Class *, ::java::lang::Object *, jbyte, jboolean);
+ void setShort(::java::lang::Class *, ::java::lang::Object *, jshort, jboolean);
+ void setInt(::java::lang::Class *, ::java::lang::Object *, jint, jboolean);
+ void setLong(::java::lang::Class *, ::java::lang::Object *, jlong, jboolean);
+ void setFloat(::java::lang::Class *, ::java::lang::Object *, jfloat, jboolean);
+ void setDouble(::java::lang::Class *, ::java::lang::Object *, jdouble, jboolean);
+ void setChar(::java::lang::Class *, ::java::lang::Object *, jchar, jboolean);
+ void setBoolean(::java::lang::Class *, ::java::lang::Object *, jboolean, jboolean);
+ void set(::java::lang::Class *, ::java::lang::Object *, ::java::lang::Object *, ::java::lang::Class *, jboolean);
+private:
+ void set(::java::lang::Class *, ::java::lang::Object *, ::java::lang::Object *);
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::reflect::AccessibleObject)))) declaringClass;
+ ::java::lang::String * name;
+ jint offset;
+ ::java::lang::Class * type;
+public: // actually package-private
+ static const jint FIELD_MODIFIERS = 223;
+public:
+ static ::java::lang::Class class$;
+
+ friend jfieldID (::_Jv_FromReflectedField) (java::lang::reflect::Field *);
+ friend jobject (::_Jv_JNI_ToReflectedField) (_Jv_JNIEnv*, jclass, jfieldID, jboolean);
+ friend class java::lang::Class;
+ friend jobject (::_Jv_getFieldInternal) (java::lang::reflect::Field *f, jclass c, jobject o);
+};
+
+#endif // __java_lang_reflect_Field__
diff --git a/libjava/java/lang/reflect/Field.java b/libjava/java/lang/reflect/Field.java
new file mode 100644
index 000000000..61db14df5
--- /dev/null
+++ b/libjava/java/lang/reflect/Field.java
@@ -0,0 +1,817 @@
+/* java.lang.reflect.Field - reflection of Java fields
+ Copyright (C) 1998, 2001, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+import java.lang.annotation.Annotation;
+
+/**
+ * The Field class represents a member variable of a class. It also allows
+ * dynamic access to a member, via reflection. This works for both
+ * static and instance fields. Operations on Field objects know how to
+ * do widening conversions, but throw {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Field regardless of location, but get and set access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Per Bothner <bothner@cygnus.com>
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Field
+ extends AccessibleObject implements Member
+{
+ private Class declaringClass;
+ private String name;
+
+ // Offset in bytes from the start of declaringClass's fields array.
+ private int offset;
+
+ // The Class (or primitive TYPE) of this field.
+ private Class type;
+
+ static final int FIELD_MODIFIERS
+ = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+ | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+ | Modifier.VOLATILE;
+
+ // This is instantiated by Class sometimes, but it uses C++ and
+ // avoids the Java protection check.
+ Field ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this field, or the class where this field
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class<?> getDeclaringClass()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this field.
+ * @return the name of this field
+ */
+ public native String getName();
+
+ /**
+ * Return the raw modifiers for this field.
+ * @return the field's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this field uses. Use the <code>Modifier</code>
+ * class to interpret the values. A field can only have a subset of the
+ * following modifiers: public, private, protected, static, final,
+ * transient, and volatile.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return getModifiersInternal() & FIELD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this field is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this field represents an enum constant,
+ * false otherwise.
+ * @since 1.5
+ */
+ public boolean isEnumConstant()
+ {
+ return (getModifiersInternal() & Modifier.ENUM) != 0;
+ }
+
+ /**
+ * Gets the type of this field.
+ * @return the type of this field
+ */
+ public native Class<?> getType();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Fields are semantically equivalent if they have the same declaring
+ * class, name, and type. Since you can't creat a Field except through
+ * the VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals (Object fld)
+ {
+ if (! (fld instanceof Field))
+ return false;
+ Field f = (Field) fld;
+ return declaringClass == f.declaringClass && offset == f.offset;
+ }
+
+ /**
+ * Get the hash code for the Field. The Field hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object.
+ */
+ public int hashCode()
+ {
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Field. A Field's String
+ * representation is "&lt;modifiers&gt; &lt;type&gt;
+ * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+ * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+ *
+ * @return the String representation of the Field
+ */
+ public String toString ()
+ {
+ StringBuffer sbuf = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, sbuf);
+ sbuf.append(' ');
+ }
+ Method.appendClassName (sbuf, getType ());
+ sbuf.append(' ');
+ Method.appendClassName (sbuf, getDeclaringClass());
+ sbuf.append('.');
+ sbuf.append(getName());
+ return sbuf.toString();
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getGenericType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName());
+ return sb.toString();
+ }
+
+ /**
+ * Get the value of this Field. If it is primitive, it will be wrapped
+ * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. If the field
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is accessed, and primitives are wrapped (but not
+ * necessarily in new objects). This method accesses the field of the
+ * declaring class, even if the instance passed in belongs to a subclass
+ * which declares another field to hide this one.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>o</code> is not an instance of
+ * the class or interface declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #getBoolean(Object)
+ * @see #getByte(Object)
+ * @see #getChar(Object)
+ * @see #getShort(Object)
+ * @see #getInt(Object)
+ * @see #getLong(Object)
+ * @see #getFloat(Object)
+ * @see #getDouble(Object)
+ */
+ public Object get(Object obj)
+ throws IllegalAccessException
+ {
+ return get(null, obj);
+ }
+
+ /**
+ * Get the value of this boolean Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public boolean getBoolean(Object obj)
+ throws IllegalAccessException
+ {
+ return getBoolean(null, obj);
+ }
+
+ /**
+ * Get the value of this byte Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public byte getByte(Object obj)
+ throws IllegalAccessException
+ {
+ return getByte(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a char. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char field of
+ * <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public char getChar(Object obj)
+ throws IllegalAccessException
+ {
+ return getChar(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a short. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte or short
+ * field of <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public short getShort(Object obj)
+ throws IllegalAccessException
+ {
+ return getShort(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as an int. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, or
+ * int field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public int getInt(Object obj)
+ throws IllegalAccessException
+ {
+ return getInt(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a long. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * or long field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public long getLong(Object obj)
+ throws IllegalAccessException
+ {
+ return getLong(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a float. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, or float field of <code>o</code>, or if <code>o</code> is
+ * not an instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public float getFloat(Object obj)
+ throws IllegalAccessException
+ {
+ return getFloat(null, obj);
+ }
+
+ /**
+ * Get the value of this Field as a double. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, float, or double field of <code>o</code>, or if
+ * <code>o</code> is not an instance of the declaring class of this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public double getDouble(Object obj)
+ throws IllegalAccessException
+ {
+ return getDouble(null, obj);
+ }
+
+ private native boolean getBoolean (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native char getChar (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native byte getByte (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native short getShort (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native int getInt (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native long getLong (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native float getFloat (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native double getDouble (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native Object get (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Set the value of this Field. If it is a primitive field, the value
+ * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. This also
+ * occurs whether or not there is access control if the field is final.
+ * If the field is primitive, and unwrapping your argument fails, you will
+ * get an <code>IllegalArgumentException</code>; likewise, this error
+ * happens if <code>value</code> cannot be cast to the correct object type.
+ * If the field is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is set with the widened value. This method accesses
+ * the field of the declaring class, even if the instance passed in belongs
+ * to a subclass which declares another field to hide this one.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>value</code> cannot be
+ * converted by a widening conversion to the underlying type of
+ * the Field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #setBoolean(Object, boolean)
+ * @see #setByte(Object, byte)
+ * @see #setChar(Object, char)
+ * @see #setShort(Object, short)
+ * @see #setInt(Object, int)
+ * @see #setLong(Object, long)
+ * @see #setFloat(Object, float)
+ * @see #setDouble(Object, double)
+ */
+ public void set(Object object, Object value)
+ throws IllegalAccessException
+ {
+ set(null, object, value);
+ }
+
+ /**
+ * Set this boolean Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setBoolean(Object obj, boolean b)
+ throws IllegalAccessException
+ {
+ setBoolean(null, obj, b, true);
+ }
+
+ /**
+ * Set this byte Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setByte(Object obj, byte b)
+ throws IllegalAccessException
+ {
+ setByte(null, obj, b, true);
+ }
+
+ /**
+ * Set this char Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setChar(Object obj, char c)
+ throws IllegalAccessException
+ {
+ setChar(null, obj, c, true);
+ }
+
+ /**
+ * Set this short Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setShort(Object obj, short s)
+ throws IllegalAccessException
+ {
+ setShort(null, obj, s, true);
+ }
+
+ /**
+ * Set this int Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not an int, long, float, or
+ * double field, or if <code>o</code> is not an instance of the
+ * class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setInt(Object obj, int i)
+ throws IllegalAccessException
+ {
+ setInt(null, obj, i, true);
+ }
+
+ /**
+ * Set this long Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a long, float, or double
+ * field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setLong(Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setLong(null, obj, l, true);
+ }
+
+ /**
+ * Set this float Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a float or long field, or
+ * if <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setFloat(Object obj, float f)
+ throws IllegalAccessException
+ {
+ setFloat(null, obj, f, true);
+ }
+
+ /**
+ * Set this double Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a double field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setDouble(Object obj, double d)
+ throws IllegalAccessException
+ {
+ setDouble(null, obj, d, true);
+ }
+
+ /**
+ * Return the generic type of the field. If the field type is not a generic
+ * type, the method returns the same as <code>getType()</code>.
+ *
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericType()
+ {
+ String signature = getSignature();
+ if (signature == null)
+ return getType();
+ FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
+ signature);
+ return p.getFieldType();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annoClass)
+ {
+ Annotation[] annos = getDeclaredAnnotations();
+ for (int i = 0; i < annos.length; ++i)
+ if (annos[i].annotationType() == annoClass)
+ return (T) annos[i];
+ return null;
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+
+ /**
+ * Return the String in the Signature attribute for this field. If there
+ * is no Signature attribute, return null.
+ */
+ private native String getSignature();
+
+ native void setByte (Class caller, Object obj, byte b, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setShort (Class caller, Object obj, short s, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setInt (Class caller, Object obj, int i, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setLong (Class caller, Object obj, long l, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setFloat (Class caller, Object obj, float f, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setDouble (Class caller, Object obj, double d,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setChar (Class caller, Object obj, char c, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setBoolean (Class caller, Object obj, boolean b,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void set (Class caller, Object obj, Object val, Class type,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private void set (Class caller, Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ Class type = getType();
+ if (! type.isPrimitive())
+ set(caller, object, value, type, true);
+ else if (value instanceof Byte)
+ setByte(caller, object, ((Byte) value).byteValue(), true);
+ else if (value instanceof Short)
+ setShort (caller, object, ((Short) value).shortValue(), true);
+ else if (value instanceof Integer)
+ setInt(caller, object, ((Integer) value).intValue(), true);
+ else if (value instanceof Long)
+ setLong(caller, object, ((Long) value).longValue(), true);
+ else if (value instanceof Float)
+ setFloat(caller, object, ((Float) value).floatValue(), true);
+ else if (value instanceof Double)
+ setDouble(caller, object, ((Double) value).doubleValue(), true);
+ else if (value instanceof Character)
+ setChar(caller, object, ((Character) value).charValue(), true);
+ else if (value instanceof Boolean)
+ setBoolean(caller, object, ((Boolean) value).booleanValue(), true);
+ else
+ throw new IllegalArgumentException();
+ }
+}
diff --git a/libjava/java/lang/reflect/GenericArrayType.h b/libjava/java/lang/reflect/GenericArrayType.h
new file mode 100644
index 000000000..cdeb0b2a3
--- /dev/null
+++ b/libjava/java/lang/reflect/GenericArrayType.h
@@ -0,0 +1,19 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_GenericArrayType__
+#define __java_lang_reflect_GenericArrayType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::GenericArrayType : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::reflect::Type * getGenericComponentType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_GenericArrayType__
diff --git a/libjava/java/lang/reflect/GenericDeclaration.h b/libjava/java/lang/reflect/GenericDeclaration.h
new file mode 100644
index 000000000..5c484ea96
--- /dev/null
+++ b/libjava/java/lang/reflect/GenericDeclaration.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_GenericDeclaration__
+#define __java_lang_reflect_GenericDeclaration__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::GenericDeclaration : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::TypeVariable * > * getTypeParameters() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_GenericDeclaration__
diff --git a/libjava/java/lang/reflect/GenericSignatureFormatError.h b/libjava/java/lang/reflect/GenericSignatureFormatError.h
new file mode 100644
index 000000000..c46c9264a
--- /dev/null
+++ b/libjava/java/lang/reflect/GenericSignatureFormatError.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_GenericSignatureFormatError__
+#define __java_lang_reflect_GenericSignatureFormatError__
+
+#pragma interface
+
+#include <java/lang/ClassFormatError.h>
+
+class java::lang::reflect::GenericSignatureFormatError : public ::java::lang::ClassFormatError
+{
+
+public:
+ GenericSignatureFormatError();
+private:
+ static const jlong serialVersionUID = 6709919147137911034LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_GenericSignatureFormatError__
diff --git a/libjava/java/lang/reflect/InvocationHandler.h b/libjava/java/lang/reflect/InvocationHandler.h
new file mode 100644
index 000000000..722195321
--- /dev/null
+++ b/libjava/java/lang/reflect/InvocationHandler.h
@@ -0,0 +1,21 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_InvocationHandler__
+#define __java_lang_reflect_InvocationHandler__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::InvocationHandler : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Object * invoke(::java::lang::Object *, ::java::lang::reflect::Method *, JArray< ::java::lang::Object * > *) = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_InvocationHandler__
diff --git a/libjava/java/lang/reflect/InvocationTargetException.h b/libjava/java/lang/reflect/InvocationTargetException.h
new file mode 100644
index 000000000..37e229c29
--- /dev/null
+++ b/libjava/java/lang/reflect/InvocationTargetException.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_InvocationTargetException__
+#define __java_lang_reflect_InvocationTargetException__
+
+#pragma interface
+
+#include <java/lang/Exception.h>
+
+class java::lang::reflect::InvocationTargetException : public ::java::lang::Exception
+{
+
+public: // actually protected
+ InvocationTargetException();
+public:
+ InvocationTargetException(::java::lang::Throwable *);
+ InvocationTargetException(::java::lang::Throwable *, ::java::lang::String *);
+ virtual ::java::lang::Throwable * getTargetException();
+ virtual ::java::lang::Throwable * getCause();
+private:
+ static const jlong serialVersionUID = 4085088731926701167LL;
+ ::java::lang::Throwable * __attribute__((aligned(__alignof__( ::java::lang::Exception)))) target;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_InvocationTargetException__
diff --git a/libjava/java/lang/reflect/MalformedParameterizedTypeException.h b/libjava/java/lang/reflect/MalformedParameterizedTypeException.h
new file mode 100644
index 000000000..a48f669c0
--- /dev/null
+++ b/libjava/java/lang/reflect/MalformedParameterizedTypeException.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_MalformedParameterizedTypeException__
+#define __java_lang_reflect_MalformedParameterizedTypeException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::reflect::MalformedParameterizedTypeException : public ::java::lang::RuntimeException
+{
+
+public:
+ MalformedParameterizedTypeException();
+private:
+ static const jlong serialVersionUID = -5696557788586220964LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_MalformedParameterizedTypeException__
diff --git a/libjava/java/lang/reflect/Member.h b/libjava/java/lang/reflect/Member.h
new file mode 100644
index 000000000..9e3522be0
--- /dev/null
+++ b/libjava/java/lang/reflect/Member.h
@@ -0,0 +1,24 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Member__
+#define __java_lang_reflect_Member__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Member : public ::java::lang::Object
+{
+
+public:
+ virtual ::java::lang::Class * getDeclaringClass() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ virtual jint getModifiers() = 0;
+ virtual jboolean isSynthetic() = 0;
+ static const jint DECLARED = 1;
+ static const jint PUBLIC = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_Member__
diff --git a/libjava/java/lang/reflect/Method.h b/libjava/java/lang/reflect/Method.h
new file mode 100644
index 000000000..8a843d5d1
--- /dev/null
+++ b/libjava/java/lang/reflect/Method.h
@@ -0,0 +1,84 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Method__
+#define __java_lang_reflect_Method__
+
+#pragma interface
+
+#include <java/lang/reflect/AccessibleObject.h>
+#include <gcj/array.h>
+
+
+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
+{
+
+ Method();
+public:
+ ::java::lang::Class * getDeclaringClass();
+ ::java::lang::String * getName();
+private:
+ jint getModifiersInternal();
+public:
+ jint getModifiers();
+ jboolean isBridge();
+ jboolean isSynthetic();
+ 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();
+ ::java::lang::String * toGenericString();
+ ::java::lang::Object * invoke(::java::lang::Object *, JArray< ::java::lang::Object * > *);
+ JArray< ::java::lang::reflect::TypeVariable * > * getTypeParameters();
+private:
+ ::java::lang::String * getSignature();
+public:
+ JArray< ::java::lang::reflect::Type * > * getGenericExceptionTypes();
+ JArray< ::java::lang::reflect::Type * > * getGenericParameterTypes();
+ ::java::lang::reflect::Type * getGenericReturnType();
+ ::java::lang::Object * getDefaultValue();
+ ::java::lang::annotation::Annotation * getAnnotation(::java::lang::Class *);
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotations();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotations();
+private:
+ JArray< ::java::lang::annotation::Annotation * > * getDeclaredAnnotationsInternal();
+ JArray< JArray< ::java::lang::annotation::Annotation * > * > * getParameterAnnotationsInternal();
+ void getType();
+public: // actually package-private
+ static void appendClassName(::java::lang::StringBuffer *, ::java::lang::Class *);
+ static const jint METHOD_MODIFIERS = 3391;
+private:
+ ::java::lang::Class * __attribute__((aligned(__alignof__( ::java::lang::reflect::AccessibleObject)))) declaringClass;
+public: // actually package-private
+ JArray< ::java::lang::Class * > * exception_types;
+private:
+ ::java::lang::String * name;
+public: // actually package-private
+ JArray< ::java::lang::Class * > * parameter_types;
+ ::java::lang::Class * return_type;
+private:
+ jint offset;
+public:
+ static ::java::lang::Class class$;
+
+ 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*);
+};
+
+#endif // __java_lang_reflect_Method__
diff --git a/libjava/java/lang/reflect/Method.java b/libjava/java/lang/reflect/Method.java
new file mode 100644
index 000000000..878210abb
--- /dev/null
+++ b/libjava/java/lang/reflect/Method.java
@@ -0,0 +1,501 @@
+// Method.java - Represent method of class or interface.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+import gnu.gcj.RawData;
+import gnu.java.lang.reflect.MethodSignatureParser;
+import java.lang.annotation.Annotation;
+
+/**
+ * The Method class represents a member method of a class. It also allows
+ * dynamic invocation, via reflection. This works for both static and
+ * instance methods. Invocation on Method objects knows how to do
+ * widening conversions, but throws {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Method regardless of location, but invocation access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Tom Tromey <tromey@redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getDeclaredMethods()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Method
+ extends AccessibleObject implements Member, GenericDeclaration
+{
+ static final int METHOD_MODIFIERS
+ = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+ | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+ | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+ /**
+ * This class is uninstantiable.
+ */
+ private Method ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this method, or the class where this method
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class<?> getDeclaringClass()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this method.
+ * @return the name of this method
+ */
+ public native String getName ();
+
+ /**
+ * Return the raw modifiers for this method.
+ * @return the method's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this method uses. Use the <code>Modifier</code>
+ * class to interpret the values. A method can only have a subset of the
+ * following modifiers: public, private, protected, abstract, static,
+ * final, synchronized, native, and strictfp.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return getModifiersInternal() & METHOD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this method is a bridge method. A bridge method
+ * is generated by the compiler in some situations involving
+ * generics and inheritance.
+ * @since 1.5
+ */
+ public boolean isBridge()
+ {
+ return (getModifiersInternal() & Modifier.BRIDGE) != 0;
+ }
+
+ /**
+ * Return true if this method is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs method, that is if
+ * the method takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Gets the return type of this method.
+ * @return the type of this method
+ */
+ public Class<?> getReturnType ()
+ {
+ if (return_type == null)
+ getType();
+ return return_type;
+ }
+
+ /**
+ * Get the parameter list for this method, in declaration order. If the
+ * method takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the method's parameters
+ */
+ public Class<?>[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType();
+ 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
+ * (not null).
+ *
+ * @return a list of the types in the method's throws clause
+ */
+ public Class<?>[] getExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ 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
+ * class, name, and parameter list. This ignores different exception
+ * clauses or return types.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Method))
+ return false;
+ Method m = (Method) obj;
+ return declaringClass == m.declaringClass && offset == m.offset;
+ }
+
+ /**
+ * Get the hash code for the Method. The Method hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode()
+ {
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Method. A Method's String
+ * representation is "&lt;modifiers&gt; &lt;returntype&gt;
+ * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
+ * everything after ')' is omitted if there are no exceptions.<br> Example:
+ * <code>public static int run(java.lang.Runnable,int)</code>
+ *
+ * @return the String representation of the Method
+ */
+ public String toString()
+ {
+ if (parameter_types == null)
+ getType ();
+
+ StringBuffer b = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, 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();
+ }
+
+ public String toGenericString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ Constructor.addTypeParameters(sb, getTypeParameters());
+ sb.append(getGenericReturnType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Invoke the method. Arguments are automatically unwrapped and widened,
+ * and the result is automatically wrapped, if needed.<p>
+ *
+ * If the method is static, <code>o</code> will be ignored. Otherwise,
+ * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
+ * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
+ * you will get a <code>NullPointerException</code> if <code>o</code> is
+ * null, and an <code>IllegalArgumentException</code> if it is incompatible
+ * with the declaring class of the method. If the method takes 0 arguments,
+ * you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * Next, if this Method enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not acces this method in similar compiled code. If the method
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the method is invoked. If it completes normally, the return value
+ * will be null for a void method, a wrapped object for a primitive return
+ * method, or the actual return of an Object method. If it completes
+ * abruptly, the exception is wrapped in an
+ * <code>InvocationTargetException</code>.
+ *
+ * @param o the object to invoke the method on
+ * @param args the arguments to the method
+ * @return the return value of the method, wrapped in the appropriate
+ * wrapper if it is primitive
+ * @throws IllegalAccessException if the method could not normally be called
+ * by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * if the arguments types are wrong even with a widening conversion;
+ * or if <code>o</code> is not an instance of the class or interface
+ * declaring this method
+ * @throws InvocationTargetException if the method throws an exception
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static method triggered
+ * class initialization, which then failed
+ */
+ public native Object invoke (Object obj, Object... args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Method>[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this method. If there
+ * is no Signature attribute, return null.
+ */
+ private native String getSignature();
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this method, in declaration order.
+ * An array of size zero is returned if this method declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this method.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this method, in declaration order.
+ * An array of size zero is returned if this method takes no
+ * parameters.
+ *
+ * @return a list of the types of the method's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ /**
+ * Returns the return type of this method.
+ *
+ * @return the return type of this method
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericReturnType()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getReturnType();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericReturnType();
+ }
+
+ /**
+ * If this method is an annotation method, returns the default
+ * value for the method. If there is no default value, or if the
+ * method is not a member of an annotation type, returns null.
+ * Primitive types are wrapped.
+ *
+ * @throws TypeNotPresentException if the method returns a Class,
+ * and the class cannot be found
+ *
+ * @since 1.5
+ */
+ public native Object getDefaultValue();
+
+ public <T extends Annotation> T getAnnotation(Class<T> annoClass)
+ {
+ Annotation[] annos = getDeclaredAnnotations();
+ for (int i = 0; i < annos.length; ++i)
+ if (annos[i].annotationType() == annoClass)
+ return (T) annos[i];
+ return null;
+ }
+
+ public Annotation[] getDeclaredAnnotations()
+ {
+ Annotation[] result = getDeclaredAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0];
+ return result;
+ }
+
+ public Annotation[][] getParameterAnnotations()
+ {
+ // FIXME: should check that we have the right number
+ // of parameters ...?
+ Annotation[][] result = getParameterAnnotationsInternal();
+ if (result == null)
+ result = new Annotation[0][0];
+ return result;
+ }
+
+ private native Annotation[] getDeclaredAnnotationsInternal();
+ private native Annotation[][] getParameterAnnotationsInternal();
+
+ private native void getType ();
+
+ // 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 ());
+ }
+ }
+
+ // Declaring class.
+ private Class declaringClass;
+
+ // Exception types.
+ Class[] exception_types;
+ // Name cache. (Initially null.)
+ private String name;
+ // Parameter types.
+ Class[] parameter_types;
+ // Return type.
+ Class return_type;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/libjava/java/lang/reflect/Modifier.h b/libjava/java/lang/reflect/Modifier.h
new file mode 100644
index 000000000..4ee474a95
--- /dev/null
+++ b/libjava/java/lang/reflect/Modifier.h
@@ -0,0 +1,58 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Modifier__
+#define __java_lang_reflect_Modifier__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Modifier : public ::java::lang::Object
+{
+
+public:
+ Modifier();
+ static jboolean isAbstract(jint);
+ static jboolean isFinal(jint);
+ static jboolean isInterface(jint);
+ static jboolean isNative(jint);
+ static jboolean isPrivate(jint);
+ static jboolean isProtected(jint);
+ static jboolean isPublic(jint);
+ static jboolean isStatic(jint);
+ static jboolean isStrict(jint);
+ static jboolean isSynchronized(jint);
+ static jboolean isTransient(jint);
+ static jboolean isVolatile(jint);
+ static ::java::lang::String * toString(jint);
+public: // actually package-private
+ static ::java::lang::StringBuilder * toString(jint, ::java::lang::StringBuilder *);
+ static ::java::lang::StringBuffer * toString(jint, ::java::lang::StringBuffer *);
+public:
+ static const jint PUBLIC = 1;
+ static const jint PRIVATE = 2;
+ static const jint PROTECTED = 4;
+ static const jint STATIC = 8;
+ static const jint FINAL = 16;
+ static const jint SYNCHRONIZED = 32;
+ static const jint VOLATILE = 64;
+ static const jint TRANSIENT = 128;
+ static const jint NATIVE = 256;
+ static const jint INTERFACE = 512;
+ static const jint ABSTRACT = 1024;
+ static const jint STRICT = 2048;
+public: // actually package-private
+ static const jint SUPER = 32;
+ static const jint ALL_FLAGS = 4095;
+ static const jint BRIDGE = 64;
+ static const jint VARARGS = 128;
+ static const jint SYNTHETIC = 4096;
+ static const jint ENUM = 16384;
+ static const jint INVISIBLE = 32768;
+ static const jint INTERPRETED = 4096;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Modifier__
diff --git a/libjava/java/lang/reflect/Modifier.java b/libjava/java/lang/reflect/Modifier.java
new file mode 100644
index 000000000..f9a9ca2c9
--- /dev/null
+++ b/libjava/java/lang/reflect/Modifier.java
@@ -0,0 +1,375 @@
+/* java.lang.reflect.Modifier
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+/**
+ * Modifier is a helper class with static methods to determine whether an
+ * int returned from getModifiers() represents static, public, protected,
+ * native, final, etc... and provides an additional method to print
+ * out all of the modifiers in an int in order.
+ * <p>
+ * The methods in this class use the bitmask values in the VM spec to
+ * determine the modifiers of an int. This means that a VM must return a
+ * standard mask, conformant with the VM spec. I don't know if this is how
+ * Sun does it, but I'm willing to bet money that it is.
+ *
+ * @author John Keiser
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Member#getModifiers()
+ * @see Method#getModifiers()
+ * @see Field#getModifiers()
+ * @see Constructor#getModifiers()
+ * @see Class#getModifiers()
+ * @since 1.1
+ */
+public class Modifier
+{
+ /** <STRONG>This constructor really shouldn't be here ... there are no
+ * instance methods or variables of this class, so instantiation is
+ * worthless. However, this function is in the 1.1 spec, so it is added
+ * for completeness.</STRONG>
+ */
+ public Modifier()
+ {
+ }
+
+ /**
+ * Public: accessible from any other class.
+ */
+ public static final int PUBLIC = 0x0001;
+
+ /**
+ * Private: accessible only from the same enclosing class.
+ */
+ public static final int PRIVATE = 0x0002;
+
+ /**
+ * Protected: accessible only to subclasses, or within the package.
+ */
+ public static final int PROTECTED = 0x0004;
+
+ /**
+ * Static:<br><ul>
+ * <li>Class: no enclosing instance for nested class.</li>
+ * <li>Field or Method: can be accessed or invoked without an
+ * instance of the declaring class.</li>
+ * </ul>
+ */
+ public static final int STATIC = 0x0008;
+
+ /**
+ * Final:<br><ul>
+ * <li>Class: no subclasses allowed.</li>
+ * <li>Field: cannot be changed.</li>
+ * <li>Method: cannot be overriden.</li>
+ * </ul>
+ */
+ public static final int FINAL = 0x0010;
+
+ /**
+ * Synchronized: Method: lock the class while calling this method.
+ */
+ public static final int SYNCHRONIZED = 0x0020;
+
+ /**
+ * Volatile: Field: cannot be cached.
+ */
+ public static final int VOLATILE = 0x0040;
+
+ /**
+ * Transient: Field: not serialized or deserialized.
+ */
+ public static final int TRANSIENT = 0x0080;
+
+ /**
+ * Native: Method: use JNI to call this method.
+ */
+ public static final int NATIVE = 0x0100;
+
+ /**
+ * Interface: Class: is an interface.
+ */
+ public static final int INTERFACE = 0x0200;
+
+ /**
+ * Abstract:<br><ul>
+ * <li>Class: may not be instantiated.</li>
+ * <li>Method: may not be called.</li>
+ * </ul>
+ */
+ public static final int ABSTRACT = 0x0400;
+
+ /**
+ * Strictfp: Method: expressions are FP-strict.<p>
+ * Also used as a modifier for classes, to mean that all initializers
+ * and constructors are FP-strict, but does not show up in
+ * Class.getModifiers.
+ */
+ public static final int STRICT = 0x0800;
+
+
+ /**
+ * Super - treat invokespecial as polymorphic so that super.foo() works
+ * according to the JLS. This is a reuse of the synchronized constant
+ * to patch a hole in JDK 1.0. *shudder*.
+ */
+ static final int SUPER = 0x0020;
+
+ /**
+ * All the flags, only used by code in this package.
+ */
+ static final int ALL_FLAGS = 0xfff;
+
+ /**
+ * Flag indicating a bridge method.
+ */
+ static final int BRIDGE = 0x40;
+
+ /**
+ * Flag indicating a varargs method.
+ */
+ static final int VARARGS = 0x80;
+
+ /**
+ * Flag indicating a synthetic member.
+ */
+ static final int SYNTHETIC = 0x1000;
+
+ /**
+ * Flag indicating an enum constant or an enum class.
+ */
+ static final int ENUM = 0x4000;
+
+ /**
+ * GCJ-LOCAL: This access flag is set on methods we declare
+ * internally but which must not be visible to reflection.
+ */
+ static final int INVISIBLE = 0x8000;
+
+ /**
+ * GCJ-LOCAL: This access flag is set on interpreted classes.
+ */
+ static final int INTERPRETED = 0x1000;
+
+ /**
+ * Check whether the given modifier is abstract.
+ * @param mod the modifier.
+ * @return <code>true</code> if abstract, <code>false</code> otherwise.
+ */
+ public static boolean isAbstract(int mod)
+ {
+ return (mod & ABSTRACT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is final.
+ * @param mod the modifier.
+ * @return <code>true</code> if final, <code>false</code> otherwise.
+ */
+ public static boolean isFinal(int mod)
+ {
+ return (mod & FINAL) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is an interface.
+ * @param mod the modifier.
+ * @return <code>true</code> if an interface, <code>false</code> otherwise.
+ */
+ public static boolean isInterface(int mod)
+ {
+ return (mod & INTERFACE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is native.
+ * @param mod the modifier.
+ * @return <code>true</code> if native, <code>false</code> otherwise.
+ */
+ public static boolean isNative(int mod)
+ {
+ return (mod & NATIVE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is private.
+ * @param mod the modifier.
+ * @return <code>true</code> if private, <code>false</code> otherwise.
+ */
+ public static boolean isPrivate(int mod)
+ {
+ return (mod & PRIVATE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is protected.
+ * @param mod the modifier.
+ * @return <code>true</code> if protected, <code>false</code> otherwise.
+ */
+ public static boolean isProtected(int mod)
+ {
+ return (mod & PROTECTED) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is public.
+ * @param mod the modifier.
+ * @return <code>true</code> if public, <code>false</code> otherwise.
+ */
+ public static boolean isPublic(int mod)
+ {
+ return (mod & PUBLIC) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is static.
+ * @param mod the modifier.
+ * @return <code>true</code> if static, <code>false</code> otherwise.
+ */
+ public static boolean isStatic(int mod)
+ {
+ return (mod & STATIC) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is strictfp.
+ * @param mod the modifier.
+ * @return <code>true</code> if strictfp, <code>false</code> otherwise.
+ */
+ public static boolean isStrict(int mod)
+ {
+ return (mod & STRICT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is synchronized.
+ * @param mod the modifier.
+ * @return <code>true</code> if synchronized, <code>false</code> otherwise.
+ */
+ public static boolean isSynchronized(int mod)
+ {
+ return (mod & SYNCHRONIZED) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is transient.
+ * @param mod the modifier.
+ * @return <code>true</code> if transient, <code>false</code> otherwise.
+ */
+ public static boolean isTransient(int mod)
+ {
+ return (mod & TRANSIENT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is volatile.
+ * @param mod the modifier.
+ * @return <code>true</code> if volatile, <code>false</code> otherwise.
+ */
+ public static boolean isVolatile(int mod)
+ {
+ return (mod & VOLATILE) != 0;
+ }
+
+ /**
+ * Get a string representation of all the modifiers represented by the
+ * given int. The keywords are printed in this order:
+ * <code>&lt;public|protected|private&gt; abstract static final transient
+ * volatile synchronized native strictfp interface</code>.
+ *
+ * @param mod the modifier.
+ * @return the String representing the modifiers.
+ */
+ public static String toString(int mod)
+ {
+ return toString(mod, new StringBuffer()).toString();
+ }
+
+ /**
+ * Package helper method that can take a StringBuilder.
+ * @param mod the modifier
+ * @param r the StringBuilder to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuilder toString(int mod, StringBuilder r)
+ {
+ r.append(toString(mod, new StringBuffer()));
+ return r;
+ }
+
+ /**
+ * Package helper method that can take a StringBuffer.
+ * @param mod the modifier
+ * @param r the StringBuffer to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuffer toString(int mod, StringBuffer r)
+ {
+ if (isPublic(mod))
+ r.append("public ");
+ if (isProtected(mod))
+ r.append("protected ");
+ if (isPrivate(mod))
+ r.append("private ");
+ if (isAbstract(mod))
+ r.append("abstract ");
+ if (isStatic(mod))
+ r.append("static ");
+ if (isFinal(mod))
+ r.append("final ");
+ if (isTransient(mod))
+ r.append("transient ");
+ if (isVolatile(mod))
+ r.append("volatile ");
+ if (isSynchronized(mod))
+ r.append("synchronized ");
+ if (isNative(mod))
+ r.append("native ");
+ if (isStrict(mod))
+ r.append("strictfp ");
+ if (isInterface(mod))
+ r.append("interface ");
+
+ // Trim trailing space.
+ if ((mod & ALL_FLAGS) != 0)
+ r.setLength(r.length() - 1);
+ return r;
+ }
+}
diff --git a/libjava/java/lang/reflect/ParameterizedType.h b/libjava/java/lang/reflect/ParameterizedType.h
new file mode 100644
index 000000000..dab9ad953
--- /dev/null
+++ b/libjava/java/lang/reflect/ParameterizedType.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_ParameterizedType__
+#define __java_lang_reflect_ParameterizedType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::ParameterizedType : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::Type * > * getActualTypeArguments() = 0;
+ virtual ::java::lang::reflect::Type * getOwnerType() = 0;
+ virtual ::java::lang::reflect::Type * getRawType() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_ParameterizedType__
diff --git a/libjava/java/lang/reflect/Proxy$ClassFactory.h b/libjava/java/lang/reflect/Proxy$ClassFactory.h
new file mode 100644
index 000000000..c4cfb883d
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ClassFactory.h
@@ -0,0 +1,78 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ClassFactory__
+#define __java_lang_reflect_Proxy$ClassFactory__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy$ClassFactory : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ClassFactory(::java::lang::reflect::Proxy$ProxyData *);
+private:
+ void emitMethod(jint, JArray< ::java::lang::Class * > *);
+public: // actually package-private
+ ::java::lang::Class * generate(::java::lang::ClassLoader *);
+private:
+ void putU1(jint);
+ void putU2(jint);
+ void putU4(jint);
+ void putConst(jint);
+ void putLoad(jint, ::java::lang::Class *);
+ ::java::lang::String * wrapper(::java::lang::Class *);
+ jchar utf8Info(::java::lang::String *);
+ jchar classInfo(::java::lang::String *);
+ jchar classInfo(::java::lang::Class *);
+ jchar refInfo(jbyte, ::java::lang::String *, ::java::lang::String *, ::java::lang::String *);
+ jchar nameAndTypeInfo(::java::lang::String *, ::java::lang::String *);
+ ::java::lang::String * toUtf8(::java::lang::String *);
+ jchar poolIndex(::java::lang::String *);
+ static const jbyte FIELD = 1;
+ static const jbyte METHOD = 2;
+ static const jbyte INTERFACE = 3;
+ static ::java::lang::String * CTOR_SIG;
+ static ::java::lang::String * INVOKE_SIG;
+ static const jchar ACONST_NULL = 1;
+ static const jchar ICONST_0 = 3;
+ static const jchar BIPUSH = 16;
+ static const jchar SIPUSH = 17;
+ static const jchar ILOAD = 21;
+ static const jchar ILOAD_0 = 26;
+ static const jchar ALOAD_0 = 42;
+ static const jchar ALOAD_1 = 43;
+ static const jchar AALOAD = 50;
+ static const jchar AASTORE = 83;
+ static const jchar DUP = 89;
+ static const jchar DUP_X1 = 90;
+ static const jchar SWAP = 95;
+ static const jchar IRETURN = 172;
+ static const jchar LRETURN = 173;
+ static const jchar FRETURN = 174;
+ static const jchar DRETURN = 175;
+ static const jchar ARETURN = 176;
+ static const jchar RETURN = 177;
+ static const jchar GETSTATIC = 178;
+ static const jchar GETFIELD = 180;
+ static const jchar INVOKEVIRTUAL = 182;
+ static const jchar INVOKESPECIAL = 183;
+ static const jchar INVOKEINTERFACE = 185;
+ static const jchar NEW = 187;
+ static const jchar ANEWARRAY = 189;
+ static const jchar ATHROW = 191;
+ static const jchar CHECKCAST = 192;
+ ::java::lang::StringBuffer * __attribute__((aligned(__alignof__( ::java::lang::Object)))) pool;
+ ::java::lang::StringBuffer * stream;
+ ::java::util::Map * poolEntries;
+ ::java::lang::String * qualName;
+ JArray< ::java::lang::reflect::Method * > * methods;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ClassFactory__
diff --git a/libjava/java/lang/reflect/Proxy$ProxyData.h b/libjava/java/lang/reflect/Proxy$ProxyData.h
new file mode 100644
index 000000000..2c0d91e5e
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ProxyData.h
@@ -0,0 +1,37 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ProxyData__
+#define __java_lang_reflect_Proxy$ProxyData__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy$ProxyData : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ProxyData();
+private:
+ static ::java::lang::String * getPackage(::java::lang::Class *);
+public: // actually package-private
+ static ::java::lang::reflect::Proxy$ProxyData * getProxyData(::java::lang::reflect::Proxy$ProxyType *);
+private:
+ static jboolean isCoreObjectMethod(::java::lang::reflect::Method *);
+public: // actually package-private
+ ::java::lang::String * __attribute__((aligned(__alignof__( ::java::lang::Object)))) pack;
+ JArray< ::java::lang::Class * > * interfaces;
+ JArray< ::java::lang::reflect::Method * > * methods;
+ JArray< JArray< ::java::lang::Class * > * > * exceptions;
+private:
+ static jint count;
+public: // actually package-private
+ jint id;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ProxyData__
diff --git a/libjava/java/lang/reflect/Proxy$ProxySignature.h b/libjava/java/lang/reflect/Proxy$ProxySignature.h
new file mode 100644
index 000000000..ae0f028de
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ProxySignature.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ProxySignature__
+#define __java_lang_reflect_Proxy$ProxySignature__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Proxy$ProxySignature : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ProxySignature(::java::lang::reflect::Method *);
+ void checkCompatibility(::java::lang::reflect::Proxy$ProxySignature *);
+public:
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+public: // actually package-private
+ static ::java::util::HashMap * coreMethods;
+ ::java::lang::reflect::Method * __attribute__((aligned(__alignof__( ::java::lang::Object)))) method;
+ ::java::util::Set * exceptions;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ProxySignature__
diff --git a/libjava/java/lang/reflect/Proxy$ProxyType.h b/libjava/java/lang/reflect/Proxy$ProxyType.h
new file mode 100644
index 000000000..da7653539
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy$ProxyType.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy$ProxyType__
+#define __java_lang_reflect_Proxy$ProxyType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy$ProxyType : public ::java::lang::Object
+{
+
+public: // actually package-private
+ Proxy$ProxyType(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+public:
+ jint hashCode();
+ jboolean equals(::java::lang::Object *);
+public: // actually package-private
+ ::java::lang::ClassLoader * __attribute__((aligned(__alignof__( ::java::lang::Object)))) loader;
+ JArray< ::java::lang::Class * > * interfaces;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy$ProxyType__
diff --git a/libjava/java/lang/reflect/Proxy.h b/libjava/java/lang/reflect/Proxy.h
new file mode 100644
index 000000000..4dad2cffd
--- /dev/null
+++ b/libjava/java/lang/reflect/Proxy.h
@@ -0,0 +1,32 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Proxy__
+#define __java_lang_reflect_Proxy__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::Proxy : public ::java::lang::Object
+{
+
+public: // actually protected
+ Proxy(::java::lang::reflect::InvocationHandler *);
+public:
+ static ::java::lang::Class * getProxyClass(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+ static ::java::lang::Object * newProxyInstance(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *, ::java::lang::reflect::InvocationHandler *);
+ static jboolean isProxyClass(::java::lang::Class *);
+ static ::java::lang::reflect::InvocationHandler * getInvocationHandler(::java::lang::Object *);
+private:
+ static const jlong serialVersionUID = -2222568056686623797LL;
+ static ::java::util::Map * proxyClasses;
+public: // actually protected
+ ::java::lang::reflect::InvocationHandler * __attribute__((aligned(__alignof__( ::java::lang::Object)))) h;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_Proxy__
diff --git a/libjava/java/lang/reflect/ReflectPermission.h b/libjava/java/lang/reflect/ReflectPermission.h
new file mode 100644
index 000000000..0e6a7c32e
--- /dev/null
+++ b/libjava/java/lang/reflect/ReflectPermission.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_ReflectPermission__
+#define __java_lang_reflect_ReflectPermission__
+
+#pragma interface
+
+#include <java/security/BasicPermission.h>
+
+class java::lang::reflect::ReflectPermission : public ::java::security::BasicPermission
+{
+
+public:
+ ReflectPermission(::java::lang::String *);
+ ReflectPermission(::java::lang::String *, ::java::lang::String *);
+private:
+ static const jlong serialVersionUID = 7412737110241507485LL;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_ReflectPermission__
diff --git a/libjava/java/lang/reflect/Type.h b/libjava/java/lang/reflect/Type.h
new file mode 100644
index 000000000..55c317fa4
--- /dev/null
+++ b/libjava/java/lang/reflect/Type.h
@@ -0,0 +1,18 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_Type__
+#define __java_lang_reflect_Type__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+
+class java::lang::reflect::Type : public ::java::lang::Object
+{
+
+public:
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_Type__
diff --git a/libjava/java/lang/reflect/TypeVariable.h b/libjava/java/lang/reflect/TypeVariable.h
new file mode 100644
index 000000000..6029c0190
--- /dev/null
+++ b/libjava/java/lang/reflect/TypeVariable.h
@@ -0,0 +1,23 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_TypeVariable__
+#define __java_lang_reflect_TypeVariable__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::TypeVariable : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::Type * > * getBounds() = 0;
+ virtual ::java::lang::reflect::GenericDeclaration * getGenericDeclaration() = 0;
+ virtual ::java::lang::String * getName() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_TypeVariable__
diff --git a/libjava/java/lang/reflect/UndeclaredThrowableException.h b/libjava/java/lang/reflect/UndeclaredThrowableException.h
new file mode 100644
index 000000000..01b969b0e
--- /dev/null
+++ b/libjava/java/lang/reflect/UndeclaredThrowableException.h
@@ -0,0 +1,26 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_UndeclaredThrowableException__
+#define __java_lang_reflect_UndeclaredThrowableException__
+
+#pragma interface
+
+#include <java/lang/RuntimeException.h>
+
+class java::lang::reflect::UndeclaredThrowableException : public ::java::lang::RuntimeException
+{
+
+public:
+ UndeclaredThrowableException(::java::lang::Throwable *);
+ UndeclaredThrowableException(::java::lang::Throwable *, ::java::lang::String *);
+ virtual ::java::lang::Throwable * getUndeclaredThrowable();
+ virtual ::java::lang::Throwable * getCause();
+private:
+ static const jlong serialVersionUID = 330127114055056639LL;
+ ::java::lang::Throwable * __attribute__((aligned(__alignof__( ::java::lang::RuntimeException)))) undeclaredThrowable;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_UndeclaredThrowableException__
diff --git a/libjava/java/lang/reflect/VMProxy.h b/libjava/java/lang/reflect/VMProxy.h
new file mode 100644
index 000000000..e48e8e4e8
--- /dev/null
+++ b/libjava/java/lang/reflect/VMProxy.h
@@ -0,0 +1,28 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_VMProxy__
+#define __java_lang_reflect_VMProxy__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::VMProxy : public ::java::lang::Object
+{
+
+public: // actually package-private
+ VMProxy();
+ static ::java::lang::Class * getProxyClass(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+ static ::java::lang::reflect::Proxy$ProxyData * getProxyData(::java::lang::ClassLoader *, JArray< ::java::lang::Class * > *);
+ static ::java::lang::Class * generateProxyClass(::java::lang::ClassLoader *, ::java::lang::reflect::Proxy$ProxyData *);
+ static jboolean HAVE_NATIVE_GET_PROXY_CLASS;
+ static jboolean HAVE_NATIVE_GET_PROXY_DATA;
+ static jboolean HAVE_NATIVE_GENERATE_PROXY_CLASS;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __java_lang_reflect_VMProxy__
diff --git a/libjava/java/lang/reflect/VMProxy.java b/libjava/java/lang/reflect/VMProxy.java
new file mode 100644
index 000000000..ea1c88506
--- /dev/null
+++ b/libjava/java/lang/reflect/VMProxy.java
@@ -0,0 +1,140 @@
+/* VMProxy.java -- VM interface for proxy class
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+final class VMProxy
+{
+ /**
+ * Set to true if the VM provides a native method to implement
+ * Proxy.getProxyClass completely, including argument verification.
+ * If this is true, HAVE_NATIVE_GET_PROXY_DATA and
+ * HAVE_NATIVE_GENERATE_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_CLASS = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the first part of Proxy.getProxyClass: generation of the array
+ * of methods to convert, and verification of the arguments.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_DATA = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the second part of Proxy.getProxyClass: conversion of an array of
+ * methods into an actual proxy class.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GENERATE_PROXY_CLASS = true;
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyClass. Only needed if
+ * VMProxy.HAVE_NATIVE_GET_PROXY_CLASS is true, this does the
+ * work of both getProxyData and generateProxyClass with no
+ * intermediate form in Java. The native code may safely assume that
+ * this class must be created, and does not already exist.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return the generated proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see Configuration#HAVE_NATIVE_GET_PROXY_CLASS
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyData(ClassLoader, Class[])
+ * @see #generateProxyClass(ProxyData)
+ */
+ static Class getProxyClass(ClassLoader loader, Class[] interfaces)
+ {
+ return null;
+ }
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyData. Only needed if
+ * Configuration.HAVE_NATIVE_GET_PROXY_DATA is true. The native code
+ * may safely assume that a new ProxyData object must be created which
+ * does not duplicate any existing ones.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return all data that is required to make this proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see Configuration.HAVE_NATIVE_GET_PROXY_DATA
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see ProxyType#getProxyData()
+ */
+ static Proxy.ProxyData getProxyData(ClassLoader loader, Class[] interfaces)
+ {
+ return null;
+ }
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of generateProxyClass. Only needed if
+ * Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS is true. The native
+ * code may safely assume that a new Class must be created, and that
+ * the ProxyData object does not describe any existing class.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param data the struct of information to convert to a Class. This
+ * has already been verified for all problems except exceeding
+ * VM limitations
+ * @return the newly generated class
+ * @throws IllegalArgumentException if VM limitations are exceeded
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see ProxyData#generateProxyClass(ClassLoader)
+ */
+ static native Class generateProxyClass(ClassLoader loader, Proxy.ProxyData data);
+}
diff --git a/libjava/java/lang/reflect/WildcardType.h b/libjava/java/lang/reflect/WildcardType.h
new file mode 100644
index 000000000..2c5b93d65
--- /dev/null
+++ b/libjava/java/lang/reflect/WildcardType.h
@@ -0,0 +1,22 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __java_lang_reflect_WildcardType__
+#define __java_lang_reflect_WildcardType__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <gcj/array.h>
+
+
+class java::lang::reflect::WildcardType : public ::java::lang::Object
+{
+
+public:
+ virtual JArray< ::java::lang::reflect::Type * > * getLowerBounds() = 0;
+ virtual JArray< ::java::lang::reflect::Type * > * getUpperBounds() = 0;
+ static ::java::lang::Class class$;
+} __attribute__ ((java_interface));
+
+#endif // __java_lang_reflect_WildcardType__
diff --git a/libjava/java/lang/reflect/natArray.cc b/libjava/java/lang/reflect/natArray.cc
new file mode 100644
index 000000000..b7bc8beff
--- /dev/null
+++ b/libjava/java/lang/reflect/natArray.cc
@@ -0,0 +1,360 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Array.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jint length)
+{
+ if (componentType->isPrimitive())
+ {
+ // We could check for this in _Jv_NewPrimArray, but that seems
+ // like needless overhead when the only real route to this
+ // problem is here.
+ if (componentType == JvPrimClass (void))
+ throw new java::lang::IllegalArgumentException ();
+ return _Jv_NewPrimArray (componentType, length);
+ }
+ else
+ // FIXME: class loader?
+ return JvNewObjectArray (length, componentType, NULL);
+}
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType,
+ jintArray dimensions)
+{
+ jint ndims = dimensions->length;
+ if (ndims == 0)
+ throw new java::lang::IllegalArgumentException ();
+ jint* dims = elements (dimensions);
+ if (ndims == 1)
+ return newInstance (componentType, dims[0]);
+
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Array::class$);
+ ClassLoader *caller_loader = NULL;
+ if (caller)
+ caller_loader = caller->getClassLoaderInternal();
+
+ jclass arrayType = componentType;
+ for (int i = 0; i < ndims; i++)
+ arrayType = _Jv_GetArrayClass (arrayType, caller_loader);
+
+ return _Jv_NewMultiArray (arrayType, ndims, dims);
+}
+
+jint
+java::lang::reflect::Array::getLength (jobject array)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ throw new java::lang::IllegalArgumentException;
+ return ((__JArray*) array)->length;
+}
+
+jclass
+java::lang::reflect::Array::getElementType (jobject array, jint index)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ throw new java::lang::IllegalArgumentException;
+ jint length = ((__JArray*) array)->length;
+ if ((_Jv_uint) index >= (_Jv_uint) length)
+ _Jv_ThrowBadArrayIndex(index);
+ return arrayType->getComponentType ();
+}
+
+jboolean
+java::lang::reflect::Array::getBoolean (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ return elements ((jbooleanArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jchar
+java::lang::reflect::Array::getChar (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jbyte
+java::lang::reflect::Array::getByte (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jshort
+java::lang::reflect::Array::getShort (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jint
+java::lang::reflect::Array::getInt (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jlong
+java::lang::reflect::Array::getLong (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jfloat
+java::lang::reflect::Array::getFloat (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jdouble
+java::lang::reflect::Array::getDouble (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ return elements ((jdoubleArray) array) [index];
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jobject
+java::lang::reflect::Array::get (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (! elementType->isPrimitive ())
+ return elements ((jobjectArray) array) [index];
+ if (elementType == JvPrimClass (double))
+ return new java::lang::Double (elements ((jdoubleArray) array) [index]);
+ if (elementType == JvPrimClass (float))
+ return new java::lang::Float (elements ((jfloatArray) array) [index]);
+ if (elementType == JvPrimClass (long))
+ return new java::lang::Long (elements ((jlongArray) array) [index]);
+ if (elementType == JvPrimClass (int))
+ return new java::lang::Integer (elements ((jintArray) array) [index]);
+ if (elementType == JvPrimClass (short))
+ return new java::lang::Short (elements ((jshortArray) array) [index]);
+ if (elementType == JvPrimClass (byte))
+ return new java::lang::Byte (elements ((jbyteArray) array) [index]);
+ if (elementType == JvPrimClass (char))
+ return new java::lang::Character (elements ((jcharArray) array) [index]);
+ if (elementType == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (elements ((jbooleanArray) array) [index])
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ elements ((jcharArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ elements ((jbyteArray) array) [index] = value;
+ else if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setBoolean (jobject array,
+ jint index, jboolean value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ elements ((jbooleanArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::set (jobject array, jint index,
+ jobject value, jclass elType)
+{
+ // We don't have to call getElementType here, or check INDEX,
+ // because it was already done in the Java wrapper.
+ if (value != NULL && ! _Jv_IsInstanceOf (value, elType))
+ throw new java::lang::IllegalArgumentException;
+ elements ((jobjectArray) array) [index] = value;
+}
diff --git a/libjava/java/lang/reflect/natConstructor.cc b/libjava/java/lang/reflect/natConstructor.cc
new file mode 100644
index 000000000..953d86dd4
--- /dev/null
+++ b/libjava/java/lang/reflect/natConstructor.cc
@@ -0,0 +1,93 @@
+// natConstructor.cc - Native code for Constructor class.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/InstantiationException.h>
+#include <gcj/method.h>
+
+typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
+typedef JArray< JArray< ::java::lang::annotation::Annotation * > *> * anno_aa_t;
+
+jint
+java::lang::reflect::Constructor::getModifiersInternal ()
+{
+ return _Jv_FromReflectedConstructor (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Constructor::getSignature()
+{
+ return declaringClass->getReflectionSignature (this);
+}
+
+anno_a_t
+java::lang::reflect::Constructor::getDeclaredAnnotationsInternal()
+{
+ return (anno_a_t) declaringClass->getDeclaredAnnotations(this, false);
+}
+
+anno_aa_t
+java::lang::reflect::Constructor::getParameterAnnotationsInternal()
+{
+ return (anno_aa_t) declaringClass->getDeclaredAnnotations(this, true);
+}
+
+void
+java::lang::reflect::Constructor::getType ()
+{
+ _Jv_GetTypesFromSignature (_Jv_FromReflectedConstructor (this),
+ declaringClass,
+ &parameter_types,
+ NULL);
+
+ // FIXME: for now we have no way to get exception information.
+ exception_types =
+ (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$, NULL);
+}
+
+jobject
+java::lang::reflect::Constructor::newInstance (jobjectArray args)
+{
+ using namespace java::lang::reflect;
+
+ if (parameter_types == NULL)
+ getType ();
+
+ jmethodID meth = _Jv_FromReflectedConstructor (this);
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Constructor::class$);
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+ throw new IllegalAccessException;
+ }
+
+ if (Modifier::isAbstract (declaringClass->getModifiers()))
+ throw new InstantiationException;
+
+ _Jv_InitClass (declaringClass);
+
+ // In the constructor case the return type is the type of the
+ // constructor.
+ return _Jv_CallAnyMethodA (NULL, declaringClass, meth, true,
+ parameter_types, args);
+}
diff --git a/libjava/java/lang/reflect/natField.cc b/libjava/java/lang/reflect/natField.cc
new file mode 100644
index 000000000..734f65316
--- /dev/null
+++ b/libjava/java/lang/reflect/natField.cc
@@ -0,0 +1,449 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
+
+jint
+java::lang::reflect::Field::getModifiersInternal ()
+{
+ return _Jv_FromReflectedField (this)->flags;
+}
+
+jstring
+java::lang::reflect::Field::getSignature()
+{
+ return declaringClass->getReflectionSignature (this);
+}
+
+anno_a_t
+java::lang::reflect::Field::getDeclaredAnnotationsInternal()
+{
+ return (anno_a_t) declaringClass->getDeclaredAnnotations(this);
+}
+
+jstring
+java::lang::reflect::Field::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
+ return name;
+}
+
+jclass
+java::lang::reflect::Field::getType ()
+{
+ if (type == NULL)
+ {
+ jfieldID fld = _Jv_FromReflectedField (this);
+ JvSynchronize sync (declaringClass);
+ _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
+ type = fld->type;
+ }
+ return type;
+}
+
+static void*
+getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
+ jboolean checkFinal)
+{
+ using namespace java::lang::reflect;
+
+ jfieldID fld = _Jv_FromReflectedField (field);
+ _Jv_ushort flags = fld->getModifiers();
+
+ // Setting a final field is usually not allowed.
+ if (checkFinal
+ // As of 1.5, you can set a non-static final field if it is
+ // accessible.
+ && (! field->isAccessible()
+ || (field->getModifiers() & java::lang::reflect::Modifier::STATIC))
+ && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
+ throw new java::lang::IllegalAccessException(JvNewStringUTF
+ ("Field is final"));
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (flags) || field->isAccessible()))
+ {
+ if (! caller)
+ caller = _Jv_StackTrace::GetCallingClass (&Field::class$);
+ if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
+ throw new java::lang::IllegalAccessException;
+ }
+
+ if (flags & Modifier::STATIC)
+ {
+ jclass fldClass = field->getDeclaringClass ();
+ JvInitClass(fldClass);
+ return fld->u.addr;
+ }
+ else
+ {
+ if (obj == NULL)
+ throw new java::lang::NullPointerException;
+ if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
+ throw new java::lang::IllegalArgumentException;
+ return (void*) ((char*) obj + fld->getOffset ());
+ }
+}
+
+static jboolean
+getBoolean (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (boolean))
+ return * (jboolean *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jchar
+getChar (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jbyte
+getByte (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jshort
+getShort (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jint
+getInt (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (int))
+ return * (jint *) addr;
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jlong
+getLong (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jfloat
+getFloat (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jdouble
+getDouble (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (double))
+ return * (jdouble *) addr;
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+jboolean
+java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
+{
+ return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jchar
+java::lang::reflect::Field::getChar (jclass caller, jobject obj)
+{
+ return ::getChar (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jbyte
+java::lang::reflect::Field::getByte (jclass caller, jobject obj)
+{
+ return ::getByte (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jshort
+java::lang::reflect::Field::getShort (jclass caller, jobject obj)
+{
+ return ::getShort (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jint
+java::lang::reflect::Field::getInt (jclass caller, jobject obj)
+{
+ return ::getInt (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jlong
+java::lang::reflect::Field::getLong (jclass caller, jobject obj)
+{
+ return ::getLong (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jfloat
+java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
+{
+ return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jdouble
+java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
+{
+ return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jobject
+java::lang::reflect::Field::get (jclass caller, jobject obj)
+{
+ jclass type = this->getType();
+ void* addr = getAddr (this, caller, obj, false);
+ if (! type->isPrimitive ())
+ return * (jobject*) addr;
+ if (type == JvPrimClass (double))
+ return new java::lang::Double (* (jdouble*) addr);
+ if (type == JvPrimClass (float))
+ return new java::lang::Float (* (jfloat*) addr);
+ if (type == JvPrimClass (long))
+ return new java::lang::Long (* (jlong*) addr);
+ if (type == JvPrimClass (int))
+ return new java::lang::Integer (* (jint*) addr);
+ if (type == JvPrimClass (short))
+ return new java::lang::Short (* (jshort*) addr);
+ if (type == JvPrimClass (byte))
+ return new java::lang::Byte (* (jbyte*) addr);
+ if (type == JvPrimClass (char))
+ return new java::lang::Character (* (jchar*) addr);
+ if (type == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (* (jboolean*) addr)
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setBoolean (jclass type, void *addr, jboolean value)
+{
+ if (type == JvPrimClass (boolean))
+ * (jboolean *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setChar (jclass type, void *addr, jchar value)
+{
+ if (type == JvPrimClass (char))
+ * (jchar *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setByte (jclass type, void *addr, jbyte value)
+{
+ if (type == JvPrimClass (byte))
+ * (jbyte *) addr = value;
+ else if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setShort (jclass type, void *addr, jshort value)
+{
+ if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setInt (jclass type, void *addr, jint value)
+{
+ if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setLong (jclass type, void *addr, jlong value)
+{
+ if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setFloat (jclass type, void *addr, jfloat value)
+{
+ if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setDouble (jclass type, void *addr, jdouble value)
+{
+ if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
+ jboolean checkFinal)
+{
+ ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
+ jboolean checkFinal)
+{
+ ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
+}
+
+void
+java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
+ jboolean checkFinal)
+{
+ ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
+ jboolean checkFinal)
+{
+ ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
+}
+
+void
+java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
+ jboolean checkFinal)
+{
+ ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
+}
+
+void
+java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
+ jboolean checkFinal)
+{
+ ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
+}
+
+void
+java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
+ jboolean checkFinal)
+{
+ ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
+}
+
+void
+java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
+ jboolean checkFinal)
+{
+ ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
+}
+
+void
+java::lang::reflect::Field::set (jclass caller, jobject object, jobject value,
+ jclass type, jboolean checkFinal)
+{
+ void* addr = getAddr (this, caller, object, checkFinal);
+ if (value != NULL && ! _Jv_IsInstanceOf (value, type))
+ throw new java::lang::IllegalArgumentException;
+ * (jobject*) addr = value;
+}
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
new file mode 100644
index 000000000..d95c92f84
--- /dev/null
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -0,0 +1,701 @@
+// natMethod.cc - Native code for Method class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <jni.h>
+#include <java-stack.h>
+
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+
+#include <java/lang/Void.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/Class.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/NoClassDefFoundError.h>
+
+#include <stdlib.h>
+
+#if USE_LIBFFI
+#include <ffi.h>
+#else
+#include <java/lang/UnsupportedOperationException.h>
+#endif
+
+typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
+typedef JArray< JArray< ::java::lang::annotation::Annotation * > *> * anno_aa_t;
+
+
+
+struct cpair
+{
+ jclass prim;
+ jclass wrap;
+};
+
+// This is used to determine when a primitive widening conversion is
+// allowed.
+static cpair primitives[] =
+{
+#define BOOLEAN 0
+ { JvPrimClass (boolean), &java::lang::Boolean::class$ },
+ { JvPrimClass (byte), &java::lang::Byte::class$ },
+#define SHORT 2
+ { JvPrimClass (short), &java::lang::Short::class$ },
+#define CHAR 3
+ { JvPrimClass (char), &java::lang::Character::class$ },
+ { JvPrimClass (int), &java::lang::Integer::class$ },
+ { JvPrimClass (long), &java::lang::Long::class$ },
+ { JvPrimClass (float), &java::lang::Float::class$ },
+ { JvPrimClass (double), &java::lang::Double::class$ },
+ { NULL, NULL }
+};
+
+static inline jboolean
+can_widen (jclass from, jclass to)
+{
+ int fromx = -1, tox = -1;
+
+ for (int i = 0; primitives[i].prim; ++i)
+ {
+ if (primitives[i].wrap == from)
+ fromx = i;
+ if (primitives[i].prim == to)
+ tox = i;
+ }
+
+ // Can't handle a miss.
+ if (fromx == -1 || tox == -1)
+ return false;
+ // Boolean arguments may not be widened.
+ if (fromx == BOOLEAN && tox != BOOLEAN)
+ return false;
+ // Nothing promotes to char.
+ if (tox == CHAR && fromx != CHAR)
+ return false;
+
+ return fromx <= tox;
+}
+
+#ifdef USE_LIBFFI
+static inline ffi_type *
+get_ffi_type (jclass klass)
+{
+ // A special case.
+ if (klass == NULL)
+ return &ffi_type_pointer;
+
+ ffi_type *r;
+ if (klass == JvPrimClass (byte))
+ r = &ffi_type_sint8;
+ else if (klass == JvPrimClass (short))
+ r = &ffi_type_sint16;
+ else if (klass == JvPrimClass (int))
+ r = &ffi_type_sint32;
+ else if (klass == JvPrimClass (long))
+ r = &ffi_type_sint64;
+ else if (klass == JvPrimClass (float))
+ r = &ffi_type_float;
+ else if (klass == JvPrimClass (double))
+ r = &ffi_type_double;
+ else if (klass == JvPrimClass (boolean))
+ {
+ // On some platforms a bool is a byte, on others an int.
+ if (sizeof (jboolean) == sizeof (jbyte))
+ r = &ffi_type_sint8;
+ else
+ {
+ JvAssert (sizeof (jboolean) == sizeof (jint));
+ r = &ffi_type_sint32;
+ }
+ }
+ else if (klass == JvPrimClass (char))
+ r = &ffi_type_uint16;
+ else
+ {
+ JvAssert (! klass->isPrimitive());
+ r = &ffi_type_pointer;
+ }
+
+ return r;
+}
+#endif // USE_LIBFFI
+
+jobject
+java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
+{
+ using namespace java::lang::reflect;
+ jclass iface = NULL;
+
+ if (parameter_types == NULL)
+ getType ();
+
+ jmethodID meth = _Jv_FromReflectedMethod (this);
+
+ if (Modifier::isStatic(meth->accflags))
+ {
+ // We have to initialize a static class. It is safe to do this
+ // here and not in _Jv_CallAnyMethodA because JNI initializes a
+ // class whenever a method lookup is done.
+ _Jv_InitClass (declaringClass);
+ }
+ else
+ {
+ jclass objClass = JV_CLASS (obj);
+ if (! _Jv_IsAssignableFrom (objClass, declaringClass))
+ throw new java::lang::IllegalArgumentException;
+ }
+
+ // Check accessibility, if required.
+ if (! this->isAccessible())
+ {
+ if (! (Modifier::isPublic (meth->accflags)))
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+ throw new IllegalAccessException;
+ }
+ else
+ // Method is public, check to see if class is accessible.
+ {
+ jint flags = (declaringClass->accflags
+ & (Modifier::PUBLIC
+ | Modifier::PROTECTED
+ | Modifier::PRIVATE));
+ if (flags == 0) // i.e. class is package private
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+ if (! _Jv_ClassNameSamePackage (caller->name,
+ declaringClass->name))
+ throw new IllegalAccessException;
+ }
+ }
+ }
+
+ if (declaringClass->isInterface())
+ iface = declaringClass;
+
+ return _Jv_CallAnyMethodA (obj, return_type, meth, false,
+ parameter_types, args, iface);
+}
+
+jint
+java::lang::reflect::Method::getModifiersInternal ()
+{
+ return _Jv_FromReflectedMethod (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Method::getSignature()
+{
+ return declaringClass->getReflectionSignature (this);
+}
+
+jobject
+java::lang::reflect::Method::getDefaultValue()
+{
+ return declaringClass->getMethodDefaultValue(this);
+}
+
+anno_a_t
+java::lang::reflect::Method::getDeclaredAnnotationsInternal()
+{
+ return (anno_a_t) declaringClass->getDeclaredAnnotations(this, false);
+}
+
+anno_aa_t
+java::lang::reflect::Method::getParameterAnnotationsInternal()
+{
+ return (anno_aa_t) declaringClass->getDeclaredAnnotations(this, true);
+}
+
+jstring
+java::lang::reflect::Method::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
+ return name;
+}
+
+/* Internal method to set return_type and parameter_types fields. */
+
+void
+java::lang::reflect::Method::getType ()
+{
+ _Jv_Method *method = _Jv_FromReflectedMethod (this);
+ _Jv_GetTypesFromSignature (method,
+ declaringClass,
+ &parameter_types,
+ &return_type);
+
+ int count = 0;
+ if (method->throws != NULL)
+ {
+ while (method->throws[count] != NULL)
+ ++count;
+ }
+
+ exception_types
+ = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
+ NULL);
+ jclass *elts = elements (exception_types);
+ for (int i = 0; i < count; ++i)
+ elts[i] = _Jv_FindClass (method->throws[i],
+ declaringClass->getClassLoaderInternal ());
+}
+
+void
+_Jv_GetTypesFromSignature (jmethodID method,
+ jclass declaringClass,
+ JArray<jclass> **arg_types_out,
+ jclass *return_type_out)
+{
+
+ _Jv_Utf8Const* sig = method->signature;
+ java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();
+ char *ptr = sig->chars();
+ int numArgs = 0;
+ /* First just count the number of parameters. */
+ // FIXME: should do some validation here, e.g., that there is only
+ // one return type.
+ for (; ; ptr++)
+ {
+ switch (*ptr)
+ {
+ case 0:
+ case ')':
+ case 'V':
+ break;
+ case '[':
+ case '(':
+ continue;
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'Z':
+ numArgs++;
+ continue;
+ case 'L':
+ numArgs++;
+ do
+ ptr++;
+ while (*ptr != ';' && ptr[1] != '\0');
+ continue;
+ }
+ break;
+ }
+
+ JArray<jclass> *args = (JArray<jclass> *)
+ JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);
+ jclass* argPtr = elements (args);
+ for (ptr = sig->chars(); *ptr != '\0'; ptr++)
+ {
+ if (*ptr == '(')
+ continue;
+ if (*ptr == ')')
+ {
+ argPtr = return_type_out;
+ continue;
+ }
+
+ char *end_ptr;
+ jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
+ if (type == NULL)
+ // FIXME: This isn't ideal.
+ throw new java::lang::NoClassDefFoundError (sig->toString());
+
+ // ARGPTR can be NULL if we are processing the return value of a
+ // call from Constructor.
+ if (argPtr)
+ *argPtr++ = type;
+
+ ptr = end_ptr;
+ }
+ *arg_types_out = args;
+}
+
+// This is a very rough analog of the JNI CallNonvirtual<type>MethodA
+// functions. It handles both Methods and Constructors, and it can
+// handle any return type. In the Constructor case, the `obj'
+// argument is unused and should be NULL; also, the `return_type' is
+// the class that the constructor will construct. RESULT is a pointer
+// to a `jvalue' (see jni.h); for a void method this should be NULL.
+// This function returns an exception (if one was thrown), or NULL if
+// the call went ok.
+void
+_Jv_CallAnyMethodA (jobject obj,
+ jclass return_type,
+ jmethodID meth,
+ jboolean is_constructor,
+ jboolean is_virtual_call,
+ JArray<jclass> *parameter_types,
+ const jvalue *args,
+ jvalue *result,
+ jboolean is_jni_call,
+ jclass iface)
+{
+ using namespace java::lang::reflect;
+
+#ifdef USE_LIBFFI
+ JvAssert (! is_constructor || ! obj);
+ JvAssert (! is_constructor || return_type);
+
+ // See whether call needs an object as the first argument. A
+ // constructor does need a `this' argument, but it is one we create.
+ jboolean needs_this = false;
+ if (is_constructor
+ || ! Modifier::isStatic(meth->accflags))
+ needs_this = true;
+
+ int param_count = parameter_types->length;
+ if (needs_this)
+ ++param_count;
+
+ ffi_type *rtype;
+ // A constructor itself always returns void.
+ if (is_constructor || return_type == JvPrimClass (void))
+ rtype = &ffi_type_void;
+ else
+ rtype = get_ffi_type (return_type);
+ ffi_type **argtypes = (ffi_type **) __builtin_alloca (param_count
+ * sizeof (ffi_type *));
+
+ jclass *paramelts = elements (parameter_types);
+
+ // Special case for the `this' argument of a constructor. Note that
+ // the JDK 1.2 docs specify that the new object must be allocated
+ // before argument conversions are done.
+ if (is_constructor)
+ obj = _Jv_AllocObject (return_type);
+
+ const int size_per_arg = sizeof(jvalue);
+ ffi_cif cif;
+
+ char *p = (char *) __builtin_alloca (param_count * size_per_arg);
+ // Overallocate to get correct alignment.
+ void **values = (void **)
+ __builtin_alloca (param_count * sizeof (void *));
+
+ int i = 0;
+ if (needs_this)
+ {
+ // The `NULL' type is `Object'.
+ argtypes[i] = get_ffi_type (NULL);
+ values[i] = p;
+ memcpy (p, &obj, sizeof (jobject));
+ p += size_per_arg;
+ ++i;
+ }
+
+ for (int arg = 0; i < param_count; ++i, ++arg)
+ {
+ int tsize;
+
+ argtypes[i] = get_ffi_type (paramelts[arg]);
+ if (paramelts[arg]->isPrimitive())
+ tsize = paramelts[arg]->size();
+ else
+ tsize = sizeof (jobject);
+
+ // Copy appropriate bits from the jvalue into the ffi array.
+ // FIXME: we could do this copying all in one loop, above, by
+ // over-allocating a bit.
+ // How do we do this without breaking big-endian platforms?
+ values[i] = p;
+ memcpy (p, &args[arg], tsize);
+ p += size_per_arg;
+ }
+
+ if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count,
+ rtype, argtypes) != FFI_OK)
+ throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));
+
+ using namespace java::lang;
+ using namespace java::lang::reflect;
+
+ union
+ {
+ ffi_arg i;
+ jobject o;
+ jlong l;
+ jfloat f;
+ jdouble d;
+ } ffi_result;
+
+ switch (rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ break;
+ case FFI_TYPE_SINT8:
+ result->b = 0;
+ break;
+ case FFI_TYPE_SINT16:
+ result->s = 0;
+ break;
+ case FFI_TYPE_UINT16:
+ result->c = 0;
+ break;
+ case FFI_TYPE_SINT32:
+ result->i = 0;
+ break;
+ case FFI_TYPE_SINT64:
+ result->j = 0;
+ break;
+ case FFI_TYPE_FLOAT:
+ result->f = 0;
+ break;
+ case FFI_TYPE_DOUBLE:
+ result->d = 0;
+ break;
+ case FFI_TYPE_POINTER:
+ result->l = 0;
+ break;
+ default:
+ JvFail ("Unknown ffi_call return type");
+ break;
+ }
+
+ void *ncode;
+
+ // FIXME: If a vtable index is -1 at this point it is invalid, so we
+ // have to use the ncode.
+ //
+ // This can happen because methods in final classes don't have
+ // vtable entries, but _Jv_isVirtualMethod() doesn't know that. We
+ // could solve this problem by allocating a vtable index for methods
+ // in final classes.
+ if (is_virtual_call
+ && ! Modifier::isFinal (meth->accflags)
+ && (_Jv_ushort)-1 != meth->index)
+ {
+ _Jv_VTable *vtable = *(_Jv_VTable **) obj;
+ if (iface == NULL)
+ {
+ if (is_jni_call && Modifier::isAbstract (meth->accflags))
+ {
+ // With JNI we don't know if this is an interface call
+ // or a call to an abstract method. Look up the method
+ // by name, the slow way.
+ _Jv_Method *concrete_meth
+ = _Jv_LookupDeclaredMethod (vtable->clas,
+ meth->name,
+ meth->signature,
+ NULL);
+ if (concrete_meth == NULL
+ || concrete_meth->ncode == NULL
+ || Modifier::isAbstract(concrete_meth->accflags))
+ throw new java::lang::IncompatibleClassChangeError
+ (_Jv_GetMethodString (vtable->clas, meth));
+ ncode = concrete_meth->ncode;
+ }
+ else
+ ncode = vtable->get_method (meth->index);
+ }
+ else
+ ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface,
+ meth->index);
+ }
+ else
+ {
+ ncode = meth->ncode;
+ }
+
+ try
+ {
+ ffi_call (&cif, (void (*)()) ncode, &ffi_result, values);
+ }
+ catch (Throwable *ex)
+ {
+ // For JNI we just throw the real error. For reflection, we
+ // wrap the underlying method's exception in an
+ // InvocationTargetException.
+ if (! is_jni_call)
+ ex = new InvocationTargetException (ex);
+ throw ex;
+ }
+
+ // Since ffi_call returns integer values promoted to a word, use
+ // a narrowing conversion for jbyte, jchar, etc. results.
+ // Note that boolean is handled either by the FFI_TYPE_SINT8 or
+ // FFI_TYPE_SINT32 case.
+ if (is_constructor)
+ result->l = obj;
+ else
+ {
+ switch (rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ break;
+ case FFI_TYPE_SINT8:
+ result->b = (jbyte)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT16:
+ result->s = (jshort)ffi_result.i;
+ break;
+ case FFI_TYPE_UINT16:
+ result->c = (jchar)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT32:
+ result->i = (jint)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT64:
+ result->j = (jlong)ffi_result.l;
+ break;
+ case FFI_TYPE_FLOAT:
+ result->f = (jfloat)ffi_result.f;
+ break;
+ case FFI_TYPE_DOUBLE:
+ result->d = (jdouble)ffi_result.d;
+ break;
+ case FFI_TYPE_POINTER:
+ result->l = (jobject)ffi_result.o;
+ break;
+ default:
+ JvFail ("Unknown ffi_call return type");
+ break;
+ }
+ }
+#else
+ throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
+#endif // USE_LIBFFI
+}
+
+// This is another version of _Jv_CallAnyMethodA, but this one does
+// more checking and is used by the reflection (and not JNI) code.
+jobject
+_Jv_CallAnyMethodA (jobject obj,
+ jclass return_type,
+ jmethodID meth,
+ jboolean is_constructor,
+ JArray<jclass> *parameter_types,
+ jobjectArray args,
+ jclass iface)
+{
+ if (parameter_types->length == 0 && args == NULL)
+ {
+ // The JDK accepts this, so we do too.
+ }
+ else if (parameter_types->length != args->length)
+ throw new java::lang::IllegalArgumentException;
+
+ int param_count = parameter_types->length;
+
+ jclass *paramelts = elements (parameter_types);
+ jobject *argelts = args == NULL ? NULL : elements (args);
+ jvalue argvals[param_count];
+
+#define COPY(Where, What, Type) \
+ do { \
+ Type val = (What); \
+ memcpy ((Where), &val, sizeof (Type)); \
+ } while (0)
+
+ for (int i = 0; i < param_count; ++i)
+ {
+ jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+ if (paramelts[i]->isPrimitive())
+ {
+ if (! argelts[i]
+ || ! k
+ || ! can_widen (k, paramelts[i]))
+ throw new java::lang::IllegalArgumentException;
+
+ if (paramelts[i] == JvPrimClass (boolean))
+ COPY (&argvals[i],
+ ((java::lang::Boolean *) argelts[i])->booleanValue(),
+ jboolean);
+ else if (paramelts[i] == JvPrimClass (char))
+ COPY (&argvals[i],
+ ((java::lang::Character *) argelts[i])->charValue(),
+ jchar);
+ else
+ {
+ java::lang::Number *num = (java::lang::Number *) argelts[i];
+ if (paramelts[i] == JvPrimClass (byte))
+ COPY (&argvals[i], num->byteValue(), jbyte);
+ else if (paramelts[i] == JvPrimClass (short))
+ COPY (&argvals[i], num->shortValue(), jshort);
+ else if (paramelts[i] == JvPrimClass (int))
+ COPY (&argvals[i], num->intValue(), jint);
+ else if (paramelts[i] == JvPrimClass (long))
+ COPY (&argvals[i], num->longValue(), jlong);
+ else if (paramelts[i] == JvPrimClass (float))
+ COPY (&argvals[i], num->floatValue(), jfloat);
+ else if (paramelts[i] == JvPrimClass (double))
+ COPY (&argvals[i], num->doubleValue(), jdouble);
+ }
+ }
+ else
+ {
+ if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+ throw new java::lang::IllegalArgumentException;
+ COPY (&argvals[i], argelts[i], jobject);
+ }
+ }
+
+ jvalue ret_value;
+ _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
+ _Jv_isVirtualMethod (meth),
+ parameter_types, argvals, &ret_value,
+ false, iface);
+
+ jobject r;
+#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
+ if (is_constructor)
+ r = ret_value.l;
+ else if (return_type == JvPrimClass (byte))
+ r = VAL (java::lang::Byte, b);
+ else if (return_type == JvPrimClass (short))
+ r = VAL (java::lang::Short, s);
+ else if (return_type == JvPrimClass (int))
+ r = VAL (java::lang::Integer, i);
+ else if (return_type == JvPrimClass (long))
+ r = VAL (java::lang::Long, j);
+ else if (return_type == JvPrimClass (float))
+ r = VAL (java::lang::Float, f);
+ else if (return_type == JvPrimClass (double))
+ r = VAL (java::lang::Double, d);
+ else if (return_type == JvPrimClass (boolean))
+ r = VAL (java::lang::Boolean, z);
+ else if (return_type == JvPrimClass (char))
+ r = VAL (java::lang::Character, c);
+ else if (return_type == JvPrimClass (void))
+ r = NULL;
+ else
+ {
+ JvAssert (return_type == NULL || ! return_type->isPrimitive());
+ r = ret_value.l;
+ }
+
+ return r;
+}
diff --git a/libjava/java/lang/reflect/natVMProxy.cc b/libjava/java/lang/reflect/natVMProxy.cc
new file mode 100644
index 000000000..4c3fd74f9
--- /dev/null
+++ b/libjava/java/lang/reflect/natVMProxy.cc
@@ -0,0 +1,459 @@
+// natVMProxy.cc -- Implementation of VMProxy methods.
+
+/* Copyright (C) 2006, 2007
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// The idea of behind this code is to utilize libffi's ability to
+// create closures to provide a fast "cut-through" way to generate
+// proxy classes. Instead of generating bytecode and then
+// interpreting that, we copy the method definitions for each of the
+// methods we're supposed to be prxying and generate a libffi closure
+// for each one.
+
+#include <config.h>
+#include <platform.h>
+#include <sysdep/descriptor.h>
+
+#include <limits.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <gcj/cni.h>
+#include <gcj/javaprims.h>
+#include <jvm.h>
+#include <jni.h>
+#include <java-threads.h>
+#include <java-interp.h>
+#include <ffi.h>
+#include <execution.h>
+#include <gcj/method.h>
+
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <java/lang/Class.h>
+#include <java/lang/ClassCastException.h>
+#include <java/lang/Error.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Integer.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/UnsupportedOperationException.h>
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/VMCompiler.h>
+#include <java/lang/reflect/InvocationHandler.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Proxy$ClassFactory.h>
+#include <java/lang/reflect/Proxy$ProxyData.h>
+#include <java/lang/reflect/Proxy.h>
+#include <java/lang/reflect/UndeclaredThrowableException.h>
+#include <java/lang/reflect/VMProxy.h>
+
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+
+using namespace java::lang::reflect;
+using namespace java::lang;
+
+#ifndef INTERPRETER
+jclass
+java::lang::reflect::VMProxy::generateProxyClass
+ (ClassLoader *, Proxy$ProxyData *)
+{
+ throw new UnsupportedOperationException (
+ JvNewStringLatin1 ("Interpreter not available"));
+}
+#else
+typedef void (*closure_fun) (ffi_cif*, void*, void**, void*);
+static void *ncode (int method_index, jclass klass, _Jv_Method *self, closure_fun fun);
+static void run_proxy (ffi_cif*, void*, void**, void*);
+
+typedef jobject invoke_t (jobject, Proxy *, Method *, JArray< jobject > *);
+
+// True if pc points to a proxy frame.
+
+bool
+_Jv_is_proxy (void *pc)
+{
+ return pc == UNWRAP_FUNCTION_DESCRIPTOR ((void*)&run_proxy);
+}
+
+// Generate a proxy class by using libffi closures for each entry
+// point.
+
+jclass
+java::lang::reflect::VMProxy::generateProxyClass
+ (ClassLoader *loader, Proxy$ProxyData *d)
+{
+ // If we're precompiling, generate bytecode and allow VMCompiler to
+ // precompile it.
+ if (VMCompiler::precompiles ())
+ return (new Proxy$ClassFactory(d))->generate(loader);
+
+ jclass klass = new Class ();
+
+ // Synchronize on the class, so that it is not attempted initialized
+ // until we're done.
+ JvSynchronize sync (klass);
+
+ klass->superclass = &Proxy::class$;
+ klass->engine = &_Jv_soleIndirectCompiledEngine;
+ klass->size_in_bytes = -1;
+ klass->vtable_method_count = -1;
+
+ // Declare private static transient java.lang.reflect.Method[] $Proxy0.m
+ klass->field_count = klass->static_field_count = 1;
+ klass->fields = (_Jv_Field*)_Jv_AllocRawObj (sizeof (_Jv_Field));
+ klass->fields[0].name = _Jv_makeUtf8Const ("m");
+ klass->fields[0].type = d->methods->getClass();
+ klass->fields[0].flags = (Modifier::PRIVATE | Modifier::STATIC
+ | Modifier::TRANSIENT);
+
+ // Record the defining loader. For the bootstrap class loader,
+ // we record NULL.
+ if (loader != VMClassLoader::bootLoader)
+ klass->loader = loader;
+
+ {
+ StringBuffer *sb = new StringBuffer();
+ sb->append(JvNewStringLatin1 ("$Proxy"));
+ sb->append(Integer::toString (d->id));
+ klass->name = _Jv_makeUtf8Const (sb->toString());
+ }
+
+ // Allocate space for the interfaces.
+ klass->interface_count = d->interfaces->length;
+ klass->interfaces = (jclass*) _Jv_AllocRawObj (klass->interface_count
+ *sizeof (jclass));
+ for (int i = 0; i < klass->interface_count; i++)
+ klass->interfaces[i] = elements(d->interfaces)[i];
+
+ size_t count = d->methods->length;
+
+ {
+ size_t total_count = count + Proxy::class$.method_count + 1;
+ if (total_count >= 65536)
+ throw new IllegalArgumentException ();
+ // Allocate space for the methods. This is a worst case
+ // estimate.
+ klass->methods
+ = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method)
+ * total_count);
+ }
+
+ jshort &method_count = klass->method_count;
+
+ // Copy all reachable methods from Proxy.
+ for (int i = 0; i < Proxy::class$.method_count; i++)
+ {
+ if (_Jv_CheckAccess (klass, &Proxy::class$,
+ Proxy::class$.methods[i].accflags))
+ {
+ klass->methods[method_count] = Proxy::class$.methods[i];
+ method_count++;
+ }
+ }
+
+ _Jv_Method *init_method
+ = (_Jv_Linker::search_method_in_class
+ (klass, klass,
+ _Jv_makeUtf8Const ("<init>"),
+ _Jv_makeUtf8Const ("(Ljava.lang.reflect.InvocationHandler;)V"),
+ false));
+ init_method->accflags |= Modifier::PUBLIC;
+
+ // Create the methods for all of the interfaces.
+ for (size_t i = 0; i < count; i++)
+ {
+ _Jv_Method &method = klass->methods[method_count++];
+ const _Jv_Method &imethod
+ = *_Jv_FromReflectedMethod (elements(d->methods)[i]);
+ // We use a shallow copy of IMETHOD rather than a deep copy;
+ // this means that the pointer fields of METHOD point into the
+ // interface. As long as this subclass of Proxy is reachable,
+ // the interfaces of which it is a proxy will also be reachable,
+ // so this is safe.
+ method = imethod;
+ method.ncode = ncode (i, klass, &method, run_proxy);
+ method.accflags &= ~Modifier::ABSTRACT;
+ }
+
+ _Jv_Linker::layout_vtable_methods (klass);
+ _Jv_RegisterInitiatingLoader (klass, klass->loader);
+
+ // Set $Proxy0.m to point to the methods arrray
+ java::lang::reflect::Field *f
+ = klass->getDeclaredField (JvNewStringLatin1 ("m"));
+ f->flag = true;
+ f->set(NULL, d->methods);
+
+ return klass;
+}
+
+
+// Box things with primitive types.
+static inline jobject
+box (void *thing, jclass klass, FFI_TYPE type)
+{
+ jobject o;
+
+ switch (type)
+ {
+ case FFI_TYPE_VOID:
+ return NULL;
+
+ case FFI_TYPE_POINTER:
+ o = *(jobject*)thing;
+ return o;
+
+ default:
+ ;
+ }
+
+ if (klass == JvPrimClass (byte))
+ o = new Byte (*(jbyte*)thing);
+ else if (klass == JvPrimClass (short))
+ o = new Short (*(jshort*)thing);
+ else if (klass == JvPrimClass (int))
+ o = new Integer (*(jint*)thing);
+ else if (klass == JvPrimClass (long))
+ o = new Long (*(jlong*)thing);
+ else if (klass == JvPrimClass (float))
+ o = new Float (*(jfloat*)thing);
+ else if (klass == JvPrimClass (double))
+ o = new Double (*(jdouble*)thing);
+ else if (klass == JvPrimClass (boolean))
+ o = new Boolean (*(jboolean*)thing);
+ else if (klass == JvPrimClass (char))
+ o = new Character (*(jchar*)thing);
+ else
+ JvFail ("Bad ffi type in proxy");
+
+ return o;
+}
+
+
+// Unbox things with primitive types.
+static inline void
+unbox (jobject o, jclass klass, void *rvalue, FFI_TYPE type)
+{
+ switch (type)
+ {
+ case FFI_TYPE_VOID:
+ return;
+
+ case FFI_TYPE_POINTER:
+ _Jv_CheckCast (klass, o);
+ *(jobject*)rvalue = o;
+ return;
+
+ default:
+ ;
+ }
+
+ // If the value returned ... is null and the interface method's
+ // return type is primitive, then a NullPointerException will be
+ // thrown ...
+ if (klass == JvPrimClass (byte))
+ {
+ _Jv_CheckCast (&Byte::class$, o);
+ *(jbyte*)rvalue = ((Byte*)o)->byteValue();
+ }
+ else if (klass == JvPrimClass (short))
+ {
+ _Jv_CheckCast (&Short::class$, o);
+ *(jshort*)rvalue = ((Short*)o)->shortValue();
+ }
+ else if (klass == JvPrimClass (int))
+ {
+ _Jv_CheckCast (&Integer::class$, o);
+ *(jint*)rvalue = ((Integer*)o)->intValue();
+ }
+ else if (klass == JvPrimClass (long))
+ {
+ _Jv_CheckCast (&Long::class$, o);
+ *(jlong*)rvalue = ((Long*)o)->longValue();
+ }
+ else if (klass == JvPrimClass (float))
+ {
+ _Jv_CheckCast (&Float::class$, o);
+ *(jfloat*)rvalue = ((Float*)o)->floatValue();
+ }
+ else if (klass == JvPrimClass (double))
+ {
+ _Jv_CheckCast (&Double::class$, o);
+ *(jdouble*)rvalue = ((Double*)o)->doubleValue();
+ }
+ else if (klass == JvPrimClass (boolean))
+ {
+ _Jv_CheckCast (&Boolean::class$, o);
+ *(jboolean*)rvalue = ((Boolean*)o)->booleanValue();
+ }
+ else if (klass == JvPrimClass (char))
+ {
+ _Jv_CheckCast (&Character::class$, o);
+ *(jchar*)rvalue = ((Character*)o)->charValue();
+ }
+ else
+ JvFail ("Bad ffi type in proxy");
+}
+
+// _Jv_getFieldInternal is declared as a friend of reflect.Field in
+// libjava/headers.txt. This gives us a way to call the private
+// method Field.get (Class caller, Object obj).
+extern inline jobject
+_Jv_getFieldInternal (java::lang::reflect::Field *f, jclass c, jobject o)
+{
+ return f->get(c, o);
+}
+
+// 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.
+
+typedef struct {
+ ffi_closure closure;
+ _Jv_ClosureList list;
+ ffi_cif cif;
+ _Jv_Method *self;
+ int method_index;
+ ffi_type *arg_types[0];
+} ncode_closure;
+
+static void
+run_proxy (ffi_cif *cif,
+ void *rvalue,
+ void **args,
+ void*user_data)
+{
+ using namespace java::lang::reflect;
+
+ Proxy *proxy = *(Proxy**)args[0];
+ ncode_closure *self = (ncode_closure *) user_data;
+
+ jclass proxyClass = proxy->getClass();
+
+ // FRAME_DESC registers this particular invocation as the top-most
+ // interpreter frame. This lets the stack tracing code (for
+ // Throwable) print information about the Proxy being run rather
+ // than about Proxy.class itself. FRAME_DESC has a destructor so it
+ // cleans up automatically when this proxy invocation returns.
+ Thread *thread = Thread::currentThread();
+ _Jv_InterpFrame frame_desc (self->self, thread, proxyClass,
+ NULL, frame_proxy);
+
+ // The method to invoke is saved in $Proxy0.m[method_index].
+ // FIXME: We could somewhat improve efficiency by storing a pointer
+ // to the method (rather than its index) in ncode_closure. This
+ // would avoid the lookup, but it probably wouldn't make a huge
+ // difference. We'd still have to save the method array because
+ // ncode structs are not scanned by the gc.
+ Field *f = proxyClass->getDeclaredField (JvNewStringLatin1 ("m"));
+ JArray<Method*> *methods
+ = (JArray<Method*>*)_Jv_getFieldInternal (f, proxyClass, NULL);
+ Method *meth = elements(methods)[self->method_index];
+
+ JArray<jclass> *parameter_types = meth->internalGetParameterTypes ();
+ JArray<jclass> *exception_types = meth->internalGetExceptionTypes ();
+
+ InvocationHandler *handler = proxy->h;
+ 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.
+ invoke_t *invoke
+ = (invoke_t *)(_Jv_LookupInterfaceMethod
+ (handler->getClass (),
+ _Jv_makeUtf8Const ("invoke"),
+ (_Jv_makeUtf8Const
+ ("(Ljava.lang.Object;Ljava.lang.reflect.Method;[Ljava.lang.Object;)"
+ "Ljava.lang.Object;"))));
+
+ // Copy and box all the args.
+ int index = 1;
+ 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, meth, argsArray);
+ }
+ catch (Throwable *t)
+ {
+ if (_Jv_IsInstanceOf (t, &RuntimeException::class$)
+ || _Jv_IsInstanceOf (t, &Error::class$))
+ throw t;
+
+ 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, meth->return_type, rvalue, cif->rtype->type);
+}
+
+
+// Given a method and a closure function, create libffi CIF and return
+// the address of its closure.
+
+static void *
+ncode (int method_index, jclass klass, _Jv_Method *self, closure_fun fun)
+{
+ using namespace java::lang::reflect;
+
+ jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
+ int arg_count = _Jv_count_arguments (self->signature, staticp);
+
+ void *code;
+ ncode_closure *closure =
+ (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
+ + arg_count * sizeof (ffi_type*),
+ &code);
+ closure->method_index = method_index;
+ closure->list.registerClosure (klass, closure);
+
+ _Jv_init_cif (self->signature,
+ arg_count,
+ staticp,
+ &closure->cif,
+ &closure->arg_types[0],
+ NULL);
+ closure->self = self;
+
+ JvAssert ((self->accflags & Modifier::NATIVE) == 0);
+
+ ffi_prep_closure_loc (&closure->closure,
+ &closure->cif,
+ fun,
+ code,
+ code);
+
+ self->ncode = code;
+ return self->ncode;
+}
+
+#endif // INTERPRETER