summaryrefslogtreecommitdiffstats
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.java53
-rw-r--r--libjava/java/lang/reflect/Array.java78
-rw-r--r--libjava/java/lang/reflect/Constructor.java106
-rw-r--r--libjava/java/lang/reflect/Field.java264
-rw-r--r--libjava/java/lang/reflect/InvocationTargetException.java73
-rw-r--r--libjava/java/lang/reflect/Member.java26
-rw-r--r--libjava/java/lang/reflect/Method.java123
-rw-r--r--libjava/java/lang/reflect/Modifier.java130
-rw-r--r--libjava/java/lang/reflect/natArray.cc339
-rw-r--r--libjava/java/lang/reflect/natField.cc435
-rw-r--r--libjava/java/lang/reflect/natMethod.cc386
11 files changed, 2013 insertions, 0 deletions
diff --git a/libjava/java/lang/reflect/AccessibleObject.java b/libjava/java/lang/reflect/AccessibleObject.java
new file mode 100644
index 00000000000..8c869e167b0
--- /dev/null
+++ b/libjava/java/lang/reflect/AccessibleObject.java
@@ -0,0 +1,53 @@
+// AccessibleObject.java - Base for reflection objects.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using JDK 1.2 beta docs.
+ * Status: Believed complete and correct.
+ */
+
+public class AccessibleObject
+{
+ protected AccessibleObject ()
+ {
+ flag = false;
+ }
+
+ boolean isAccessible ()
+ {
+ return flag;
+ }
+
+ static void setAccessible (AccessibleObject[] array, boolean flag)
+ {
+ checkPermission ();
+ for (int i = 0; i < array.length; ++i)
+ array[i].flag = flag;
+ }
+
+ void setAccessible (boolean flag)
+ {
+ checkPermission ();
+ this.flag = flag;
+ }
+
+ private static final void checkPermission ()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ // FIXME: sm.checkPermission(ReflectPermission ("suppressAccessChecks"))
+ }
+
+ private boolean flag;
+}
diff --git a/libjava/java/lang/reflect/Array.java b/libjava/java/lang/reflect/Array.java
new file mode 100644
index 00000000000..398f80d5643
--- /dev/null
+++ b/libjava/java/lang/reflect/Array.java
@@ -0,0 +1,78 @@
+// FileDescriptor.java - Open file or device
+
+/* Copyright (C) 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date january 12, 1999
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3.
+ * Status: Believe complete and correct.
+ */
+
+public final class Array
+{
+ Array () { }
+
+ public static native Object newInstance(Class componentType, int length);
+ public static native Object newInstance(Class elementType, int[] dimensions);
+ public static native int getLength (Object array);
+
+ public static native Object get (Object array, int index);
+ public static native char getChar (Object array, int index);
+ public static native byte getByte (Object array, int index);
+ public static native short getShort (Object array, int index);
+ public static native int getInt (Object array, int index);
+ public static native long getLong (Object array, int index);
+ public static native float getFloat (Object array, int index);
+ public static native double getDouble (Object array, int index);
+ public static native boolean getBoolean (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);
+
+ 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();
+ }
+
+ public static native void setByte (Object array, int index, byte value);
+ public static native void setShort (Object array, int index, short value);
+ public static native void setInt (Object array, int index, int value);
+ public static native void setLong (Object array, int index, long value);
+ public static native void setFloat (Object array, int index, float value);
+ public static native void setDouble (Object array, int index, double value);
+ public static native void setChar (Object array, int index, char value);
+ public static native void setBoolean(Object array, int index, boolean value);
+}
diff --git a/libjava/java/lang/reflect/Constructor.java b/libjava/java/lang/reflect/Constructor.java
new file mode 100644
index 00000000000..466c1204bae
--- /dev/null
+++ b/libjava/java/lang/reflect/Constructor.java
@@ -0,0 +1,106 @@
+// Constructor.java - Represents a constructor for a class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Incomplete: needs a private constructor, and
+ * newInstance() needs to be written.
+ */
+
+public final class Constructor extends AccessibleObject implements Member
+{
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Constructor))
+ return false;
+ Constructor c = (Constructor) obj;
+ return decl_class == c.decl_class && index == c.index;
+ }
+
+ public Class getDeclaringClass ()
+ {
+ return decl_class;
+ }
+
+ public Class[] getExceptionTypes ()
+ {
+ return (Class[]) exception_types.clone();
+ }
+
+ public int getModifiers ()
+ {
+ return modifiers;
+ }
+
+ public String getName ()
+ {
+ return decl_class.getName();
+ }
+
+ public Class[] getParameterTypes ()
+ {
+ return (Class[]) parameter_types.clone();
+ }
+
+ public int hashCode ()
+ {
+ // FIXME.
+ return getName().hashCode();
+ }
+
+ // FIXME: this must be native. Should share implementation with
+ // Method.invoke.
+ public Object newInstance (Object[] args)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException
+ {
+ return null;
+ }
+
+ public String toString ()
+ {
+ StringBuffer b = new StringBuffer ();
+ b.append(Modifier.toString(modifiers));
+ b.append(" ");
+ b.append(getName());
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ b.append(parameter_types[i].toString());
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ return b.toString();
+ }
+
+ // Can't create these. FIXME.
+ private Constructor ()
+ {
+ }
+
+ // Declaring class.
+ private Class decl_class;
+ // Exception types.
+ private Class[] exception_types;
+ // Modifiers.
+ private int modifiers;
+ // Parameter types.
+ private Class[] parameter_types;
+ // Index of this method in declaring class' method table.
+ private int index;
+}
diff --git a/libjava/java/lang/reflect/Field.java b/libjava/java/lang/reflect/Field.java
new file mode 100644
index 00000000000..7c7e690926a
--- /dev/null
+++ b/libjava/java/lang/reflect/Field.java
@@ -0,0 +1,264 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date September 1998; February 1999.
+ */
+/* Status: Mostly implemented.
+ * However, access checks are not implemented. See natField.cc for
+ * _Jv_CheckFieldAccessibility as well as the missing getCaller.
+ * Note that the idea is to have to compiler convert calls to
+ * setXXX(...) and getXXX(...) to setXXX(CALLER, ...) and getXXX(CALLER, ...),
+ * where CALLER is reference to the class that contains the calls to
+ * setXXX or getXXX. This is easy for the compiler, and replaces
+ * expensive stack and table searching with a constant.
+ */
+
+public final class Field extends AccessibleObject implements Member
+{
+ private Class declaringClass;
+
+ // This is filled in by getName.
+ private String name;
+
+ // Offset in bytes from the start of declaringClass's fields array.
+ private int offset;
+
+ public boolean equals (Object fld)
+ {
+ if (! (fld instanceof Field))
+ return false;
+ Field f = (Field) fld;
+ return declaringClass == f.declaringClass && offset == f.offset;
+ }
+
+ public Class getDeclaringClass ()
+ {
+ return declaringClass;
+ }
+
+ public native String getName ();
+
+ public native Class getType ();
+
+ public native int getModifiers ();
+
+ public int hashCode()
+ {
+ return (declaringClass.hashCode() ^ offset);
+ }
+
+ // The idea is that the compiler will magically translate
+ // fld.getShort(obj) to fld.getShort(THISCLASS, obj).
+ // This makes checking assessiblity more efficient,
+ // since we don't have to do any stack-walking.
+
+ public boolean getBoolean (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getBoolean(null, obj);
+ }
+ public char getChar (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getChar(null, obj);
+ }
+
+ public byte getByte (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getByte(null, obj);
+ }
+
+ public short getShort (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getShort(null, obj);
+ }
+
+ public int getInt (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getInt(null, obj);
+ }
+
+ public long getLong (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getLong(null, obj);
+ }
+
+ public float getFloat (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getFloat(null, obj);
+ }
+
+ public double getDouble (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getDouble(null, obj);
+ }
+
+ public Object get (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return get(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;
+
+ public native Object get (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public void setByte (Object obj, byte b)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setByte(null, obj, b);
+ }
+
+ public void setShort (Object obj, short s)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setShort(null, obj, s);
+ }
+
+ public void setInt (Object obj, int i)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setInt(null, obj, i);
+ }
+
+ public void setLong (Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setLong(null, obj, l);
+ }
+
+ public void setFloat (Object obj, float f)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setFloat(null, obj, f);
+ }
+
+ public void setDouble (Object obj, double d)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setDouble(null, obj, d);
+ }
+
+ public void setChar (Object obj, char c)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setChar(null, obj, c);
+ }
+
+ public void setBoolean (Object obj, boolean b)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setBoolean(null, obj, b);
+ }
+
+ public native void setByte (Class caller, Object obj, byte b)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setShort (Class caller, Object obj, short s)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setInt (Class caller, Object obj, int i)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setLong (Class caller, Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setFloat (Class caller, Object obj, float f)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setDouble (Class caller, Object obj, double d)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setChar (Class caller, Object obj, char c)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setBoolean (Class caller, Object obj, boolean b)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native void set (Class caller, Object obj, Object val, Class type)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public void set (Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ set(null, object, value);
+ }
+
+ public void set (Class caller, Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ Class type = getType();
+ if (! type.isPrimitive())
+ set(caller, object, value, type);
+ else if (value instanceof Byte)
+ setByte(caller, object, ((Byte) value).byteValue());
+ else if (value instanceof Short)
+ setShort (caller, object, ((Short) value).shortValue());
+ else if (value instanceof Integer)
+ setInt(caller, object, ((Integer) value).intValue());
+ else if (value instanceof Long)
+ setLong(caller, object, ((Long) value).longValue());
+ else if (value instanceof Float)
+ setFloat(caller, object, ((Float) value).floatValue());
+ else if (value instanceof Double)
+ setDouble(caller, object, ((Double) value).doubleValue());
+ else if (value instanceof Character)
+ setChar(caller, object, ((Character) value).charValue());
+ else if (value instanceof Boolean)
+ setBoolean(caller, object, ((Boolean) value).booleanValue());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public String toString ()
+ {
+ StringBuffer sbuf = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ Modifier.toString(mods, sbuf);
+ sbuf.append(getType());
+ sbuf.append(' ');
+ sbuf.append(getDeclaringClass());
+ sbuf.append('.');
+ sbuf.append(getName());
+ return sbuf.toString();
+ }
+}
diff --git a/libjava/java/lang/reflect/InvocationTargetException.java b/libjava/java/lang/reflect/InvocationTargetException.java
new file mode 100644
index 00000000000..eccd5f7daed
--- /dev/null
+++ b/libjava/java/lang/reflect/InvocationTargetException.java
@@ -0,0 +1,73 @@
+// InvocationTargetException.java - Wrapper exception for reflection.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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 java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * Status: Believed complete and correct.
+ */
+
+public class InvocationTargetException extends Exception
+{
+ public Throwable getTargetException ()
+ {
+ return target;
+ }
+
+ protected InvocationTargetException ()
+ {
+ super ();
+ target = null;
+ }
+
+ public InvocationTargetException (Throwable exception)
+ {
+ super ();
+ target = exception;
+ }
+
+ public InvocationTargetException (Throwable exception, String msg)
+ {
+ super (msg);
+ target = exception;
+ }
+
+ // This is from JDK 1.2.
+ public void printStackTrace ()
+ {
+ if (target != null)
+ target.printStackTrace();
+ }
+
+ // This is from JDK 1.2.
+ public void printStackTrace (PrintStream s)
+ {
+ if (target != null)
+ target.printStackTrace(s);
+ }
+
+ // This is from JDK 1.2.
+ public void printStackTrace (PrintWriter wr)
+ {
+ if (target != null)
+ target.printStackTrace(wr);
+ }
+
+ // The wrapped exception. The name is specified by the
+ // serialization spec.
+ private Throwable target;
+}
diff --git a/libjava/java/lang/reflect/Member.java b/libjava/java/lang/reflect/Member.java
new file mode 100644
index 00000000000..a54f05f689e
--- /dev/null
+++ b/libjava/java/lang/reflect/Member.java
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date September 27, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition.
+ * Status: Believed complete and correct.
+ */
+
+public interface Member
+{
+ public static final int PUBLIC = 0;
+ public static final int DECLARED = 1;
+ public Class getDeclaringClass ();
+ public int getModifiers ();
+ public String getName();
+}
diff --git a/libjava/java/lang/reflect/Method.java b/libjava/java/lang/reflect/Method.java
new file mode 100644
index 00000000000..01e830876e5
--- /dev/null
+++ b/libjava/java/lang/reflect/Method.java
@@ -0,0 +1,123 @@
+// Method.java - Represent method of class or interface.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Incomplete: needs a private constructor, and
+ * invoke() needs to be finished.
+ */
+
+public final class Method extends AccessibleObject implements Member
+{
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Method))
+ return false;
+ Method m = (Method) obj;
+ return declaringClass == m.declaringClass && offset == m.offset;
+ }
+
+ public Class getDeclaringClass ()
+ {
+ return declaringClass;
+ }
+
+ public Class[] getExceptionTypes ()
+ {
+ return (Class[]) exception_types.clone();
+ }
+
+ public native int getModifiers ();
+
+ public native String getName ();
+
+ private native void getType ();
+
+ public Class[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType();
+ return (Class[]) parameter_types.clone();
+ }
+
+ public Class getReturnType ()
+ {
+ if (return_type == null)
+ getType();
+ return return_type;
+ }
+
+ public int hashCode ()
+ {
+ // FIXME.
+ return name.hashCode() + declaringClass.getName().hashCode();
+ }
+
+ public native Object invoke (Object obj, Object[] args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException;
+
+ public String toString ()
+ {
+ StringBuffer b = new StringBuffer ();
+ b.append(Modifier.toString(getModifiers()));
+ b.append(" ");
+ b.append(return_type.toString());
+ b.append(" ");
+ b.append(declaringClass.toString());
+ b.append(".");
+ b.append(name);
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ b.append(parameter_types[i].toString());
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ if (exception_types.length > 0)
+ {
+ b.append(" throws ");
+ for (int i = 0; i < exception_types.length; ++i)
+ {
+ b.append(exception_types[i].toString());
+ if (i < exception_types.length - 1)
+ b.append(",");
+ }
+ }
+ return b.toString();
+ }
+
+ private Method ()
+ {
+ }
+
+ // Declaring class.
+ private Class declaringClass;
+
+ // Exception types.
+ private Class[] exception_types;
+ // Name cache. (Initially null.)
+ private String name;
+ // Parameter types.
+ private Class[] parameter_types;
+ // Return type.
+ private 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.java b/libjava/java/lang/reflect/Modifier.java
new file mode 100644
index 00000000000..f9df49e80ee
--- /dev/null
+++ b/libjava/java/lang/reflect/Modifier.java
@@ -0,0 +1,130 @@
+// Modifier.java - Process modifier values.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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. */
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct to version 1.1
+ */
+
+package java.lang.reflect;
+
+public class Modifier
+{
+ public static final int PUBLIC = 0x001;
+ public static final int PRIVATE = 0x002;
+ public static final int PROTECTED = 0x004;
+ public static final int STATIC = 0x008;
+ public static final int FINAL = 0x010;
+ public static final int SYNCHRONIZED = 0x020;
+ public static final int VOLATILE = 0x040;
+ public static final int TRANSIENT = 0x080;
+ public static final int NATIVE = 0x100;
+ public static final int INTERFACE = 0x200;
+ public static final int ABSTRACT = 0x400;
+
+ public static boolean isAbstract (int mod)
+ {
+ return (mod & ABSTRACT) != 0;
+ }
+
+ public static boolean isFinal (int mod)
+ {
+ return (mod & FINAL) != 0;
+ }
+
+ public static boolean isInterface (int mod)
+ {
+ return (mod & INTERFACE) != 0;
+ }
+
+ public static boolean isNative (int mod)
+ {
+ return (mod & NATIVE) != 0;
+ }
+
+ public static boolean isPrivate (int mod)
+ {
+ return (mod & PRIVATE) != 0;
+ }
+
+ public static boolean isProtected (int mod)
+ {
+ return (mod & PROTECTED) != 0;
+ }
+
+ public static boolean isPublic (int mod)
+ {
+ return (mod & PUBLIC) != 0;
+ }
+
+ public static boolean isStatic (int mod)
+ {
+ return (mod & STATIC) != 0;
+ }
+
+ public static boolean isSynchronized (int mod)
+ {
+ return (mod & SYNCHRONIZED) != 0;
+ }
+
+ public static boolean isTransient (int mod)
+ {
+ return (mod & TRANSIENT) != 0;
+ }
+
+ public static boolean isVolatile (int mod)
+ {
+ return (mod & VOLATILE) != 0;
+ }
+
+ public static String toString (int mod)
+ {
+ StringBuffer r = new StringBuffer ();
+ toString(mod, r);
+ return r.toString();
+ }
+
+ static void 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 (isNative (mod))
+ r.append("native ");
+ if (isSynchronized (mod))
+ r.append("synchronized ");
+ if (isInterface (mod))
+ r.append("interface ");
+
+ // Trim trailing space.
+ int l = r.length();
+ if (l > 0)
+ r.setLength(l - 1);
+ }
+}
diff --git a/libjava/java/lang/reflect/natArray.cc b/libjava/java/lang/reflect/natArray.cc
new file mode 100644
index 00000000000..3da8b5c01ce
--- /dev/null
+++ b/libjava/java/lang/reflect/natArray.cc
@@ -0,0 +1,339 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1999 Cygnus Solutions
+
+ 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 <cni.h>
+#include <java/lang/reflect/Array.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())
+ return _Jv_NewPrimArray (componentType, length);
+ else
+ return JvNewObjectArray (length, componentType, NULL);
+
+}
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jintArray dimensions)
+{
+ jint ndims = dimensions->length;
+ if (ndims == 0)
+ return componentType->newInstance ();
+ jint* dims = elements (dimensions);
+ if (ndims == 1)
+ return newInstance (componentType, dims[0]);
+ jclass arrayType = componentType;
+ for (int i = 0; i < ndims; i++)
+ arrayType = _Jv_FindArrayClass (arrayType);
+ return _Jv_NewMultiArray (arrayType, ndims, dims);
+
+}
+
+jint
+java::lang::reflect::Array::getLength (jobject array)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ JvThrow (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 ())
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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];
+ JvThrow (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))
+ if (elements ((jbooleanArray) array) [index])
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::set (jobject array, jint index,
+ jobject value, jclass elType)
+{
+ if (! _Jv_IsInstanceOf (value, elType))
+ JvThrow (new java::lang::IllegalArgumentException ());
+ elements ((jobjectArray) array) [index] = value;
+}
diff --git a/libjava/java/lang/reflect/natField.cc b/libjava/java/lang/reflect/natField.cc
new file mode 100644
index 00000000000..2449b42545c
--- /dev/null
+++ b/libjava/java/lang/reflect/natField.cc
@@ -0,0 +1,435 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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 <cni.h>
+#include <jvm.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/IllegalArgumentException.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>
+#include <java-field.h>
+
+jint
+java::lang::reflect::Field::getModifiers ()
+{
+ return _Jv_FromReflectedField (this)->getModifiers ();
+}
+
+jstring
+java::lang::reflect::Field::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
+ return name;
+}
+
+jclass
+java::lang::reflect::Field::getType ()
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ if (! fld->isResolved())
+ {
+ JvSynchronize sync (declaringClass);
+ if (! fld->isResolved())
+ {
+ fld->type
+ = _Jv_FindClassFromSignature(((Utf8Const*) (fld->type))->data,
+ declaringClass->getClassLoader());
+ fld->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
+ }
+ }
+ return fld->type;
+}
+
+static void
+_Jv_CheckFieldAccessibility (jfieldID /*fld*/, jclass /*caller*/)
+{
+#if 0
+ if (caller == NULL)
+ caller = getCaller();
+#endif
+#if 0
+ _Jv_ushort flags = fld->getModifiers();
+ check accesss;
+#endif
+}
+
+static void*
+getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (field);
+ _Jv_ushort flags = fld->getModifiers();
+ if (! (flags & java::lang::reflect::Modifier::PUBLIC)
+ && ! field->isAccessible ())
+ _Jv_CheckFieldAccessibility (fld, caller);
+ if (flags & java::lang::reflect::Modifier::STATIC)
+ {
+ jclass fldClass = field->getDeclaringClass ();
+ JvInitClass(fldClass);
+ return fld->u.addr;
+ }
+ else
+ {
+ if (obj == NULL)
+ _Jv_Throw (new java::lang::NullPointerException ());
+ if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
+ JvThrow (new java::lang::IllegalArgumentException ());
+ return (void*) ((char*) obj + fld->getOffset ());
+ }
+}
+
+static jboolean
+getBoolean (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (boolean))
+ return * (jboolean *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jchar
+getChar (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jbyte
+getByte (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ _Jv_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;
+ _Jv_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;
+ _Jv_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)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getBoolean (fld->type, getAddr (this, caller, obj));
+}
+
+jchar
+java::lang::reflect::Field::getChar (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getChar (fld->type, getAddr (this, caller, obj));
+}
+
+jbyte
+java::lang::reflect::Field::getByte (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getByte (fld->type, getAddr (this, caller, obj));
+}
+
+jshort
+java::lang::reflect::Field::getShort (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getShort (fld->type, getAddr (this, caller, obj));
+}
+
+jint
+java::lang::reflect::Field::getInt (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getInt (fld->type, getAddr (this, caller, obj));
+}
+
+jlong
+java::lang::reflect::Field::getLong (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getLong (fld->type, getAddr (this, caller, obj));
+}
+
+jfloat
+java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getFloat (fld->type, getAddr (this, caller, obj));
+}
+
+jdouble
+java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getDouble (fld->type, getAddr (this, caller, obj));
+}
+
+jobject
+java::lang::reflect::Field::get (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ void* addr = getAddr (this, caller, obj);
+ if (! fld->type->isPrimitive ())
+ return * (jobject*) addr;
+ if (fld->type == JvPrimClass (double))
+ return new java::lang::Double (* (jdouble*) addr);
+ if (fld->type == JvPrimClass (float))
+ return new java::lang::Float (* (jfloat*) addr);
+ if (fld->type == JvPrimClass (long))
+ return new java::lang::Long (* (jlong*) addr);
+ if (fld->type == JvPrimClass (int))
+ return new java::lang::Integer (* (jint*) addr);
+ if (fld->type == JvPrimClass (short))
+ return new java::lang::Short (* (jshort*) addr);
+ if (fld->type == JvPrimClass (byte))
+ return new java::lang::Byte (* (jbyte*) addr);
+ if (fld->type == JvPrimClass (char))
+ return new java::lang::Character (* (jchar*) addr);
+ if (fld->type == JvPrimClass (boolean))
+ if (* (jboolean*) addr)
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setBoolean (jclass type, void *addr, jboolean value)
+{
+ if (type == JvPrimClass (boolean))
+ * (jboolean *) addr = value;
+ else
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (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
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setDouble (jclass type, void *addr, jdouble value)
+{
+ if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setBoolean (fld->type, getAddr (this, caller, obj), b);
+}
+
+void
+java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setChar (fld->type, getAddr (this, caller, obj), c);
+}
+
+void
+java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setByte (fld->type, getAddr (this, caller, obj), b);
+}
+
+void
+java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setShort (fld->type, getAddr (this, caller, obj), s);
+}
+
+void
+java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setInt (fld->type, getAddr (this, caller, obj), i);
+}
+
+void
+java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setLong (fld->type, getAddr (this, caller, obj), l);
+}
+void
+java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setFloat (fld->type, getAddr (this, caller, obj), f);
+}
+
+void
+java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setDouble (fld->type, getAddr (this, caller, obj), d);
+}
+
+void
+java::lang::reflect::Field::set (jclass caller, jobject object, jobject value, jclass type)
+{
+ if (! _Jv_IsInstanceOf (value, type))
+ JvThrow (new java::lang::IllegalArgumentException ());
+ void* addr = getAddr (this, caller, object);
+ * (jobject*) addr = value;
+}
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
new file mode 100644
index 00000000000..720bbc3d74e
--- /dev/null
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -0,0 +1,386 @@
+// natMethod.cc - Native code for Method class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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. */
+
+// This is about 90% done. Search for FIXME to see what remains.
+
+#include <config.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java-array.h>
+
+#include <java/lang/reflect/Method.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/IllegalArgumentException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java-method.h>
+
+#define ClassClass _CL_Q34java4lang5Class
+extern java::lang::Class ClassClass;
+
+#include <stdlib.h>
+
+#if 0
+
+#include <ffi.h>
+
+#define VoidClass _CL_Q34java4lang4Void
+extern java::lang::Class VoidClass;
+#define ByteClass _CL_Q34java4lang4Byte
+extern java::lang::Class ByteClass;
+#define ShortClass _CL_Q34java4lang5Short
+extern java::lang::Class ShortClass;
+#define CharacterClass _CL_Q34java4lang9Character
+extern java::lang::Class CharacterClass;
+#define IntegerClass _CL_Q34java4lang7Integer
+extern java::lang::Class IntegerClass;
+#define LongClass _CL_Q34java4lang4Long
+extern java::lang::Class LongClass;
+#define FloatClass _CL_Q34java4lang5Float
+extern java::lang::Class FloatClass;
+#define DoubleClass _CL_Q34java4lang6Double
+extern java::lang::Class DoubleClass;
+
+struct cpair
+{
+ jclass prim;
+ jclass wrap;
+};
+
+// This is used to determine when a primitive widening conversion is
+// allowed.
+static cpair primitives[] =
+{
+#define VOID 0
+ { JvPrimClass (void), &VoidClass },
+ { JvPrimClass (byte), &ByteClass },
+#define SHORT 2
+ { JvPrimClass (short), &ShortClass },
+#define CHAR 3
+ { JvPrimClass (char), &CharacterClass },
+ { JvPrimClass (int), &IntegerClass },
+ { JvPrimClass (long), &LongClass },
+ { JvPrimClass (float), &FloatClass },
+ { JvPrimClass (double), &DoubleClass },
+ { NULL, NULL }
+};
+
+static 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;
+ // Can't handle Void arguments.
+ if (fromx == VOID || tox == VOID)
+ return false;
+ // Special-case short/char conversions.
+ if ((fromx == SHORT && tox == CHAR) || (fromx == CHAR && tox == SHORT))
+ return false;
+
+ return fromx <= tox;
+}
+
+static 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))
+ {
+ // FIXME.
+ r = &ffi_type_sint8;
+ }
+ else if (klass == JvPrimClass (char))
+ r = &ffi_type_uint16;
+ else
+ {
+ JvAssert (! klass->isPrimitive());
+ r = &ffi_type_pointer;
+ }
+
+ return r;
+}
+
+// FIXME: the body of this method should be a separate function so
+// that Constructor can use it too.
+jobject
+java::lang::reflect::Method::invoke (jobject obj,
+ jobjectArray args)
+{
+ // FIXME: we need to be a friend of Class here.
+ _Jv_Method *meth = decl_class->methods[index];
+ if (! java::lang::reflect::Modifier::isStatic(modifiers))
+ {
+ jclass k = obj ? obj->getClass() : NULL;
+ if (! obj || ! decl_class->isAssignableFrom(k))
+ JvThrow (new java::lang::NullPointerException);
+ // FIXME: access checks.
+ meth = _Jv_LookupMethod (k, meth->name, meth->signature);
+ }
+
+ // FIXME: access checks.
+
+ if (parameter_types->length != args->length)
+ JvThrow (new java::lang::IllegalArgumentException);
+
+ ffi_type *rtype = get_ffi_type (return_type);
+ ffi_type **argtypes = (ffi_type **) alloca (parameter_types->length
+ * sizeof (ffi_type *));
+
+ jobject *paramelts = elements (parameter_types);
+ jobject *argelts = elements (args);
+
+ int size = 0;
+ for (int i = 0; i < parameter_types->length; ++i)
+ {
+ jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+ argtypes[i] = get_ffi_type (k);
+ if (paramelts[i]->isPrimitive())
+ {
+ if (! argelts[i]
+ || ! k->isPrimitive ()
+ || ! can_widen (k, paramelts[i]))
+ JvThrow (new java::lang::IllegalArgumentException);
+ size += paramelts[i]->size();
+ }
+ else
+ {
+ if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+ JvThrow (new java::lang::IllegalArgumentException);
+ size += sizeof (jobject);
+ }
+ }
+
+ ffi_cif cif;
+ if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, parameter_types->length,
+ rtype, argtypes) != FFI_OK)
+ {
+ // FIXME: throw some kind of VirtualMachineError here.
+ }
+
+ char *values = (char *) alloca (size);
+ char *p = values;
+
+#define COPY(Where, What, Type) \
+ do { \
+ Type val = (What); \
+ memcpy ((Where), &val, sizeof (Type)); \
+ Where += sizeof (Type); \
+ } while (0)
+
+ for (int i = 0; i < parameter_types->length; ++i)
+ {
+ java::lang::Number *num = (java::lang::Number *) paramelts[i];
+ if (paramelts[i] == JvPrimClass (byte))
+ COPY (p, num->byteValue(), jbyte);
+ else if (paramelts[i] == JvPrimClass (short))
+ COPY (p, num->shortValue(), jshort);
+ else if (paramelts[i] == JvPrimClass (int))
+ COPY (p, num->intValue(), jint);
+ else if (paramelts[i] == JvPrimClass (long))
+ COPY (p, num->longValue(), jlong);
+ else if (paramelts[i] == JvPrimClass (float))
+ COPY (p, num->floatValue(), jfloat);
+ else if (paramelts[i] == JvPrimClass (double))
+ COPY (p, num->doubleValue(), jdouble);
+ else if (paramelts[i] == JvPrimClass (boolean))
+ COPY (p, ((java::lang::Boolean *) argelts[i])->booleanValue(), jboolean);
+ else if (paramelts[i] == JvPrimClass (char))
+ COPY (p, ((java::lang::Character *) argelts[i])->charValue(), jchar);
+ else
+ {
+ JvAssert (! paramelts[i]->isPrimitive());
+ COPY (p, argelts[i], jobject);
+ }
+ }
+
+ // FIXME: exception handling.
+ java::lang::Throwable *ex;
+ jdouble ret_value; // Largest possible value. Hopefully
+ // it is aligned!
+ ex = TRAMP_CALL (ffi_call (&cif, meth->ncode, &ret_value, (void *) values));
+
+ if (ex)
+ JvThrow (new InvocationTargetException (ex));
+
+ jobject r;
+#define VAL(Wrapper, Type) (new Wrapper (* (Type *) &ret_value))
+ if (return_type == JvPrimClass (byte))
+ r = VAL (java::lang::Byte, jbyte);
+ else if (return_type == JvPrimClass (short))
+ r = VAL (java::lang::Short, jshort);
+ else if (return_type == JvPrimClass (int))
+ r = VAL (java::lang::Integer, jint);
+ else if (return_type == JvPrimClass (long))
+ r = VAL (java::lang::Long, jlong);
+ else if (return_type == JvPrimClass (float))
+ r = VAL (java::lang::Float, jfloat);
+ else if (return_type == JvPrimClass (double))
+ r = VAL (java::lang::Double, jdouble);
+ else if (return_type == JvPrimClass (boolean))
+ r = VAL (java::lang::Boolean, jboolean);
+ else if (return_type == JvPrimClass (char))
+ r = VAL (java::lang::Character, jchar);
+ else if (return_type == JvPrimClass (void))
+ r = NULL;
+ else
+ {
+ JvAssert (! return_type->isPrimitive());
+ r = VAL (java::lang::Object, jobject);
+ }
+
+ return r;
+}
+
+#else /* 0 */
+
+jobject
+java::lang::reflect::Method::invoke (jobject, jobjectArray)
+{
+ JvFail ("not enabled yet");
+}
+
+#endif /* 0 */
+
+jint
+java::lang::reflect::Method::getModifiers ()
+{
+ return _Jv_FromReflectedMethod (this)->accflags;
+}
+
+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_Utf8Const* sig = _Jv_FromReflectedMethod (this)->signature;
+ java::lang::ClassLoader *loader = declaringClass->getClassLoader();
+ char *ptr = sig->data;
+ int numArgs = 0;
+ /* First just count the number of parameters. */
+ 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, &ClassClass, NULL);
+ jclass* argPtr = elements (args);
+ for (ptr = sig->data; *ptr != '\0'; ptr++)
+ {
+ int num_arrays = 0;
+ jclass type;
+ for (; *ptr == '['; ptr++)
+ num_arrays++;
+ switch (*ptr)
+ {
+ default:
+ return;
+ case ')':
+ argPtr = &return_type;
+ continue;
+ case '(':
+ continue;
+ case 'V':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'Z':
+ type = _Jv_FindClassFromSignature(ptr, loader);
+ break;
+ case 'L':
+ type = _Jv_FindClassFromSignature(ptr, loader);
+ do
+ ptr++;
+ while (*ptr != ';' && ptr[1] != '\0');
+ break;
+ }
+ while (--num_arrays >= 0)
+ type = _Jv_FindArrayClass (type);
+ *argPtr++ = type;
+ }
+ parameter_types = args;
+}
OpenPOWER on IntegriCloud