Initial revision

From-SVN: r26263
This commit is contained in:
Tom Tromey
1999-04-07 14:42:40 +00:00
parent 140fa895c6
commit ee9dd3721b
370 changed files with 173494 additions and 0 deletions
@@ -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;
}
+78
View File
@@ -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);
}
+106
View File
@@ -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;
}
+264
View File
@@ -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();
}
}
@@ -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;
}
+26
View File
@@ -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();
}
+123
View File
@@ -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;
}
+130
View File
@@ -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);
}
}
+339
View File
@@ -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;
}
+435
View File
@@ -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;
}
+386
View File
@@ -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;
}