summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <shalom@gnu.org>1998-06-21 06:26:31 +0000
committerJohn Keiser <shalom@gnu.org>1998-06-21 06:26:31 +0000
commit4870b0a600e3ad13c02fc8a047b8f10a9800e40f (patch)
tree34cbc164fcbc2ada2de81ebfe3c3bcd88db6819b
parent940dc05ba3e2e6a0b2991dfe611efe06718263ec (diff)
downloadclasspath-4870b0a600e3ad13c02fc8a047b8f10a9800e40f.tar.gz
Initial Revision
-rw-r--r--native/java.lang.reflect/Array.c27
-rw-r--r--native/java.lang.reflect/Array.h29
-rwxr-xr-xnative/java.lang.reflect/Constructor.c180
-rw-r--r--native/java.lang.reflect/Constructor.h37
-rwxr-xr-xnative/java.lang.reflect/DEPENDENCIES29
-rwxr-xr-xnative/java.lang.reflect/Method.c381
-rw-r--r--native/java.lang.reflect/Method.h37
-rwxr-xr-xnative/java.lang.reflect/README17
-rwxr-xr-xnative/java.lang.reflect/STATUS8
-rwxr-xr-xnative/java.lang.reflect/TODO9
-rwxr-xr-xnative/java.lang.reflect/reflect.c218
-rwxr-xr-xnative/java.lang.reflect/reflect.h13
12 files changed, 985 insertions, 0 deletions
diff --git a/native/java.lang.reflect/Array.c b/native/java.lang.reflect/Array.c
new file mode 100644
index 000000000..a73743e42
--- /dev/null
+++ b/native/java.lang.reflect/Array.c
@@ -0,0 +1,27 @@
+/*
+ * java.lang.reflect.Array native functions.
+ * Author: John Keiser
+ * Version: 1.1.0
+ * Date: 2 Jun 1998
+ */
+#include "Array.h"
+
+/*
+ * Class: java_lang_reflect_Array
+ * Method: getLength
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_reflect_Array_getLength
+ (JNIEnv * env, jclass thisClass, jobject arr) {
+ return (*env)->GetArrayLength(env, arr);
+}
+
+/*
+ * Class: java_lang_reflect_Array
+ * Method: createObjectArray
+ * Signature: (Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_Array_createObjectArray
+ (JNIEnv * env, jclass thisClass, jclass arrayType, jint arrayLength) {
+ return (jobject)(*env)->NewObjectArray(env,arrayLength,arrayType,NULL);
+}
diff --git a/native/java.lang.reflect/Array.h b/native/java.lang.reflect/Array.h
new file mode 100644
index 000000000..9231b2b3a
--- /dev/null
+++ b/native/java.lang.reflect/Array.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_reflect_Array */
+
+#ifndef _Included_java_lang_reflect_Array
+#define _Included_java_lang_reflect_Array
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: java_lang_reflect_Array
+ * Method: getLength
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_reflect_Array_getLength
+ (JNIEnv *, jclass, jobject);
+
+/*
+ * Class: java_lang_reflect_Array
+ * Method: createObjectArray
+ * Signature: (Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_Array_createObjectArray
+ (JNIEnv *, jclass, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/native/java.lang.reflect/Constructor.c b/native/java.lang.reflect/Constructor.c
new file mode 100755
index 000000000..9dfd3a1fd
--- /dev/null
+++ b/native/java.lang.reflect/Constructor.c
@@ -0,0 +1,180 @@
+/*
+ * java.lang.reflect.Constructor native functions.
+ * Author: John Keiser
+ * Version: 1.1.0
+ * Date: 2 Jun 1998
+ */
+
+#include "Constructor.h"
+#include "reflect.h"
+#include <jcl.h>
+#include <native_state.h>
+#include <jnilink.h>
+#include <vmi.h>
+#include <primlib.h>
+
+#include <malloc.h>
+
+static struct state_table * table;
+
+static jmethodID
+GetTheMethodID(JNIEnv * env, jobject thisObj, jclass declarer,
+ jstring name, jobjectArray targetArgTypes);
+
+static jmethodID
+GetTheMethodID(JNIEnv * env, jobject thisObj, jclass declarer,
+ jstring name, jobjectArray targetArgTypes) {
+ linkPtr l;
+ char * nameUTF;
+ char * signature;
+ jmethodID m;
+
+ if(JCL_MonitorEnter(env, thisObj) != 0) {
+ return NULL;
+ }
+
+ l = (linkPtr)get_state(env, thisObj, table);
+
+ if(l == NULL) {
+ nameUTF = JCL_jstring_to_cstring(env, name);
+ if(nameUTF == NULL) {
+ return NULL;
+ }
+
+ signature = JCL_malloc(env, sizeof(char) * MAX_SIGNATURE_SIZE);
+ if(signature == NULL) {
+ return NULL;
+ }
+
+ if(REFLECT_GetConstructorSignature(env, signature, targetArgTypes) == -1) {
+ return NULL;
+ }
+ l = LINK_LinkMethod(env, declarer, nameUTF, signature);
+
+ JCL_free_cstring(env, name, nameUTF);
+ free(signature);
+
+ set_state(env, thisObj, table, l);
+ }
+
+ if(JCL_MonitorExit(env, thisObj) != 0) {
+ return NULL;
+ }
+
+ m = LINK_GetMethod(env, l, NULL);
+ return m;
+}
+
+static jvalue * DoInitialCheckingAndConverting(JNIEnv * env, jobjectArray args,
+ jclass declaringClass, jobjectArray targetArgTypes, jint modifiers, jint argLength) {
+
+ jframeID thisFrame;
+ jframeID methodObjFrame;
+ jframeID callerFrame;
+
+ jobject callerObject;
+ jclass callerClass;
+
+ jvalue * retval;
+
+ jobject obj;
+ jclass c;
+
+ jsize argNum;
+
+ vmiError vmiErr;
+
+ vmiErr = VMI_GetThisFrame(env, &thisFrame);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ vmiErr = VMI_GetCallerFrame(env, thisFrame, &methodObjFrame);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ vmiErr = VMI_GetCallerFrame(env, methodObjFrame, &callerFrame);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ vmiErr = VMI_GetFrameObject(env, callerFrame, &callerObject);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ callerClass = (*env)->GetObjectClass(env, callerObject);
+
+ if(!REFLECT_HasLinkLevelAccessToMember(env, callerClass, declaringClass, modifiers)) {
+ JCL_ThrowException(env, "java/lang/IllegalAccessException", "Cannot access reflected Method");
+ return NULL;
+ }
+
+ if(argLength == -1) {
+ JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Incorrect number of arguments");
+ return NULL;
+ }
+
+ if(argLength == 0) {
+ return NULL;
+ }
+
+ retval = JCL_malloc(env, sizeof(jvalue) * argLength);
+ if(retval == NULL) {
+ return NULL;
+ }
+
+ for(argNum = 0; argNum < argLength; argNum++) {
+ obj = (*env)->GetObjectArrayElement(env, args, argNum);
+ c = (jclass)(*env)->GetObjectArrayElement(env, targetArgTypes, argNum);
+ retval[argNum] = PRIMLIB_UnwrapJValue(env, obj, c);
+ if((*env)->ExceptionOccurred(env)) {
+ return NULL;
+ }
+ }
+}
+
+
+/*
+ * Class: java_lang_reflect_Constructor
+ * Method: constructNative
+ * Signature: ([Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;I[Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_java_lang_reflect_Constructor_constructNative
+(JNIEnv * env, jobject thisObj, jobjectArray args, jclass declarer, jstring name, jint modifiers, jobjectArray parameterTypes, jint length) {
+ jvalue * argVals;
+ jmethodID m;
+
+ argVals = DoInitialCheckingAndConverting(env, args, declarer, parameterTypes, modifiers, length);
+
+ if((*env)->ExceptionOccurred(env)) {
+ return NULL;
+ }
+
+ m = GetTheMethodID(env, thisObj, declarer, name, parameterTypes);
+ if(m == NULL)
+ return NULL;
+
+ return (*env)->NewObject(env, declarer, m, argVals);
+}
+
+
+/** Native State functions **/
+
+JNIEXPORT void JNICALL Java_java_lang_reflect_Constructor_initNativeState (JNIEnv * env, jclass clazz) {
+ /* create the table to hold C state, for each instance of this class */
+ table = init_state_table (env, clazz);
+}
+
+JNIEXPORT void JNICALL Java_java_lang_reflect_Constructor_finalizeNative(JNIEnv *env, jobject obj) {
+ jmethodID* m;
+ m = (jmethodID*) remove_state_slot (env, obj, table);
+ free(m);
+}
+
diff --git a/native/java.lang.reflect/Constructor.h b/native/java.lang.reflect/Constructor.h
new file mode 100644
index 000000000..23c0ebbdf
--- /dev/null
+++ b/native/java.lang.reflect/Constructor.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_reflect_Constructor */
+
+#ifndef _Included_java_lang_reflect_Constructor
+#define _Included_java_lang_reflect_Constructor
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: java_lang_reflect_Constructor
+ * Method: initNativeState
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_Constructor_initNativeState
+ (JNIEnv *, jclass);
+
+/*
+ * Class: java_lang_reflect_Constructor
+ * Method: finalizeNative
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_Constructor_finalizeNative
+ (JNIEnv *, jobject);
+
+/*
+ * Class: java_lang_reflect_Constructor
+ * Method: constructNative
+ * Signature: ([Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;I[Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_Constructor_constructNative
+ (JNIEnv *, jobject, jobjectArray, jclass, jstring, jint, jobjectArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/native/java.lang.reflect/DEPENDENCIES b/native/java.lang.reflect/DEPENDENCIES
new file mode 100755
index 000000000..38e669bce
--- /dev/null
+++ b/native/java.lang.reflect/DEPENDENCIES
@@ -0,0 +1,29 @@
+DEPENDENCIES for java.lang.reflect Native side.
+
+1.1:
+Array.c:
+ 1.1: JNI
+Method.c:
+ 1.1: JNI,JCL,PRIMLIB,JNILINK,NSA
+ 1.2: JVMDI: JVMDI_GetCallerFrame
+ 1.2: VMI: VMI_GetThisFrame
+ 1.2: VMI: VMI_GetFrameObject
+ 1.2: VMI: VMI_MOD_STATIC
+ 1.2: VMI: VMI_ThrowAppropriateException
+ 1.2: VMI: VMI_ThrowAppropriateJVMDIException
+Constructor.c:
+ 1.1: JNI,JCL,PRIMLIB,JNILINK,NSA
+ 1.2: JVMDI: GetCallerFrame
+ 1.2: VMI: VMI_GetThisFrame
+ 1.2: VMI: VMI_GetFrameObject
+ 1.2: VMI: VMI_ThrowAppropriateException
+ 1.2: VMI: VMI_ThrowAppropriateJVMDIException
+Field.c:
+ untested
+reflect.c:
+ 1.1: JNI,JCL,PRIMLIB
+ 1.2: JVMDI: GetClassModifiers
+ 1.2: JVMDI: GetClassName
+ 1.2: VMI: VMI_MOD_STATIC
+ 1.2: VMI: VMI_MOD_FINAL
+ 1.2: VMI_MOD_PRIVATE
diff --git a/native/java.lang.reflect/Method.c b/native/java.lang.reflect/Method.c
new file mode 100755
index 000000000..b10b643f1
--- /dev/null
+++ b/native/java.lang.reflect/Method.c
@@ -0,0 +1,381 @@
+/*
+ * java.lang.reflect.Method native functions.
+ * Author: John Keiser
+ * Version: 1.1.0
+ * Date: 2 Jun 1998
+ */
+
+#include "Method.h"
+#include "reflect.h"
+#include <jcl.h>
+#include <vmi.h>
+#include <primlib.h>
+#include <native_state.h>
+#include <jnilink.h>
+
+#include <malloc.h>
+
+/** Native State functions **/
+
+static struct state_table *table;
+
+static jvalue * DoInitialCheckingAndConverting(JNIEnv * env, jobject invokeObj, jobjectArray args,
+ jclass declaringClass, jobjectArray targetArgTypes,
+ jint modifiers, jint argLength);
+static jmethodID GetTheStaticMethodID(JNIEnv * env, jobject thisObj, jclass declarer, jstring name,
+ jobjectArray targetArgTypes, jclass retType);
+static jmethodID GetTheInstanceMethodID(JNIEnv * env, jobject thisObj, jobject theObj,
+ jclass declarer, jstring name, jobjectArray targetArgTypes,
+ jclass retType);
+
+/*
+Invoking the method:
+N If the calling class does not have link-level access to the method:
+ Throw IllegalAccessException.
+ If the method is not static:
+ If the object is null:
+ Throw NullPointerException.
+N If the object is not assignment-compatible (instanceof) with the Method's declaringClass:
+ Throw IllegalArgumentException.
+J If the argument lists are different lengths:
+ Throw IllegalArgumentException.
+ For each argument in actualArgs:
+J If class of correspondng targetArgTypes is primitive:
+N Convert the wrapped argument to the primitive type using widening or identity conversion.
+ If a widening or identity conversion could not occur, or if the object is null:
+ Throw IllegalArgumentException.
+J Else:
+N If the class of the argument is not assignment-compatible (instanceof) with the corresponding targetArgType:
+ Throw IllegalArgumentException.
+
+ If the method is static,
+N Determine the methodID for the declaringClass, name and signature.
+N Invoke the appropriate static method based on the return type of the Method and and Method's declaringClass.
+ Else
+N Determine the methodID for the object's class, and the Method's name and signature.
+N Invoke the appropriate static method, if the return type is primitive, wrap it.
+ If an exception was thrown, return from invoke().
+J If the return value is a primitive type, wrap it in the appropriate wrapper type.
+
+
+Java values to pass:
+ object -- the object to invoke on
+ actualArgs -- the arguments
+
+ class -- the declaringClass
+ methodName -- the name of the method
+ argLengthsDifferent -- whether the argument lengths are different
+ actualArgReflectiveTypes -- ints representing the types of the actualArgTypes
+ actualArgTypes -- the actual classes representing the types of the method arguments
+
+Native values to store:
+ if(static) methodID -- the methodID
+ else char*[2] argInfo -- the name and signature of the method as char*'s
+
+*/
+
+/* Initial checking portion:
+N If the calling class does not have link-level access to the method:
+ Throw IllegalAccessException.
+ If the method is not static:
+ If the object is null:
+ Throw NullPointerException.
+N If the object is not assignment-compatible (instanceof) with the Method's declaringClass:
+ Throw IllegalArgumentException.
+J If the argument lists are different lengths:
+ Throw IllegalArgumentException.
+ For each argument in actualArgs:
+J If class of correspondng targetArgTypes is primitive:
+N Convert the wrapped argument to the primitive type using widening or identity conversion.
+ If a widening or identity conversion could not occur, or if the object is null:
+ Throw IllegalArgumentException.
+J Else:
+N If the class of the argument is not assignment-compatible (instanceof) with the corresponding targetArgType:
+ Throw IllegalArgumentException.
+*/
+static jvalue * DoInitialCheckingAndConverting(JNIEnv * env, jobject invokeObj, jobjectArray args,
+ jclass declaringClass, jobjectArray targetArgTypes, jint modifiers, jint argLength) {
+
+ jframeID thisFrame;
+ jframeID methodObjFrame;
+ jframeID callerFrame;
+
+ jobject callerObject;
+ jclass callerClass;
+
+ jvalue * retval;
+
+ jobject obj;
+ jclass c;
+
+ jsize argNum;
+
+ vmiError vmiErr;
+
+ vmiErr = VMI_GetThisFrame(env, &thisFrame);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ vmiErr = VMI_GetCallerFrame(env, thisFrame, &methodObjFrame);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ vmiErr = VMI_GetCallerFrame(env, methodObjFrame, &callerFrame);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ vmiErr = VMI_GetFrameObject(env, callerFrame, &callerObject);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return NULL;
+ }
+
+ callerClass = (*env)->GetObjectClass(env, callerObject);
+
+ if(!REFLECT_HasLinkLevelAccessToMember(env, callerClass, declaringClass, modifiers)) {
+ JCL_ThrowException(env, "java/lang/IllegalAccessException", "Cannot access reflected Method");
+ return NULL;
+ }
+
+ if(!(modifiers & VMI_MOD_STATIC)) {
+ if(invokeObj == NULL) {
+ JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Object to invoke on is null");
+ return NULL;
+ }
+ if(!(*env)->IsInstanceOf(env, invokeObj, declaringClass)) {
+ JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Object to invoke on is not of appropriate type");
+ return NULL;
+ }
+ }
+
+ if(argLength == -1) {
+ JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Incorrect number of arguments");
+ return NULL;
+ }
+
+ if(argLength == 0) {
+ return NULL;
+ }
+
+ retval = JCL_malloc(env, sizeof(jvalue) * argLength);
+ if(retval == NULL) {
+ return NULL;
+ }
+
+ for(argNum = 0; argNum < argLength; argNum++) {
+ obj = (*env)->GetObjectArrayElement(env, args, argNum);
+ c = (jclass)(*env)->GetObjectArrayElement(env, targetArgTypes, argNum);
+ retval[argNum] = PRIMLIB_UnwrapJValue(env, obj, c);
+ if((*env)->ExceptionOccurred(env)) {
+ return NULL;
+ }
+ }
+}
+
+static jmethodID GetTheMethodID(JNIEnv * env, jobject thisObj, jobject theObj, jclass declarer, jstring name, jobjectArray targetArgTypes, jclass retType) {
+ linkPtr l;
+ char * nameUTF;
+ char * signature;
+ jmethodID m;
+
+ if(JCL_MonitorEnter(env, thisObj) != 0) {
+ return NULL;
+ }
+
+ l = (linkPtr)get_state(env, thisObj, table);
+
+ if(l == NULL) {
+ nameUTF = JCL_jstring_to_cstring(env, name);
+ if(nameUTF == NULL) {
+ return NULL;
+ }
+
+ signature = JCL_malloc(env, sizeof(char) * MAX_SIGNATURE_SIZE);
+ if(signature == NULL) {
+ return NULL;
+ }
+
+ if(REFLECT_GetMethodSignature(env, signature, targetArgTypes, retType) == -1) {
+ JCL_ThrowException(env, "java/lang/NullPointerException", "Null class in argTypes[]");
+ return NULL;
+ }
+ l = LINK_LinkMethod(env, declarer, nameUTF, signature);
+
+ JCL_free_cstring(env, name, nameUTF);
+ free(signature);
+
+ set_state(env, thisObj, table, l);
+ }
+
+ if(JCL_MonitorExit(env, thisObj) != 0) {
+ return NULL;
+ }
+
+ m = LINK_GetMethod(env, l, theObj);
+ return m;
+}
+
+/*
+Checking for link-level access:
+ If the method is public, link-level access is always granted.
+ If the method is protected, the calling class must be assignment-compatible with the method's class, or it must
+ have the same package.
+ If the method is package-protected, the calling class must have the same package as the method's class.
+ If the method is private, the calling class must be the same as the method's class.
+*/
+
+
+/*
+ * Class: java_lang_reflect_Method
+ * Method: initNativeState
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_Method_initNativeState (JNIEnv * env, jclass clazz) {
+ /* create the table to hold C state, for each instance of this class */
+ table = init_state_table (env, clazz);
+}
+
+/*
+ * Class: java_lang_reflect_Method
+ * Method: finalizeNative
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_Method_finalizeNative(JNIEnv *env, jobject obj) {
+ linkPtr l;
+ l = (linkPtr) remove_state_slot (env, obj, table);
+ LINK_UnlinkMethod(env, l);
+}
+
+
+
+/*
+ * Class: java_lang_reflect_Method
+ * Method: invokeNative
+ * Signature: (Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;ILjava/lang/Class;[Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_Method_invokeNative
+ (JNIEnv * env, jobject thisObj, jobject invokeObj, jobjectArray args,
+ jclass declarer, jstring name, jint modifiers,
+ jclass returnType, jobjectArray parameterTypes,
+ jint length) {
+
+ jvalue * argVals;
+ jint type;
+ jmethodID m;
+
+ jboolean z;
+ jbyte b;
+ jshort s;
+ jchar c;
+ jint i;
+ jlong j;
+ jfloat f;
+ jdouble d;
+
+ argVals = DoInitialCheckingAndConverting(env, invokeObj, args, declarer, parameterTypes, modifiers, length);
+
+ if((*env)->ExceptionOccurred(env)) {
+ return NULL;
+ }
+
+ type = PRIMLIB_GetReflectiveType(env, returnType);
+
+ m = GetTheMethodID(env, thisObj, invokeObj, declarer, name, parameterTypes, returnType);
+
+ JCL_RETHROW_EXCEPTION(env);
+
+ if(modifiers & VMI_MOD_STATIC) {
+ switch(type) {
+ case PRIMLIB_BOOLEAN:
+ z = (*env)->CallStaticBooleanMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapBoolean(env, z);
+ case PRIMLIB_BYTE:
+ b = (*env)->CallStaticByteMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapByte(env, b);
+ case PRIMLIB_CHAR:
+ c = (*env)->CallStaticCharMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapChar(env, c);
+ case PRIMLIB_SHORT:
+ s = (*env)->CallStaticShortMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapShort(env, s);
+ case PRIMLIB_INT:
+ i = (*env)->CallStaticIntMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapInt(env, i);
+ case PRIMLIB_LONG:
+ j = (*env)->CallStaticLongMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapLong(env, j);
+ case PRIMLIB_FLOAT:
+ f = (*env)->CallStaticFloatMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapFloat(env, f);
+ case PRIMLIB_DOUBLE:
+ d = (*env)->CallStaticDoubleMethod(env, declarer, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapDouble(env, d);
+ case PRIMLIB_VOID:
+ (*env)->CallStaticVoidMethod(env, declarer, m, argVals);
+ return NULL;
+ case PRIMLIB_OBJECT:
+ return (*env)->CallStaticObjectMethod(env, declarer, m, argVals);
+ default:
+ JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Unknown primitive type! Internal error.");
+ return NULL;
+ }
+ } else {
+ switch(type) {
+ case PRIMLIB_BOOLEAN:
+ z = (*env)->CallBooleanMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapBoolean(env, z);
+ case PRIMLIB_BYTE:
+ b = (*env)->CallByteMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapByte(env, b);
+ case PRIMLIB_CHAR:
+ c = (*env)->CallCharMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapChar(env, c);
+ case PRIMLIB_SHORT:
+ s = (*env)->CallShortMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapShort(env, s);
+ case PRIMLIB_INT:
+ i = (*env)->CallIntMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapInt(env, i);
+ case PRIMLIB_LONG:
+ j = (*env)->CallLongMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapLong(env, j);
+ case PRIMLIB_FLOAT:
+ f = (*env)->CallFloatMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapFloat(env, f);
+ case PRIMLIB_DOUBLE:
+ (*env)->CallDoubleMethod(env, invokeObj, m, argVals);
+ JCL_RETHROW_EXCEPTION(env);
+ return PRIMLIB_WrapDouble(env, d);
+ case PRIMLIB_VOID:
+ (*env)->CallVoidMethod(env, invokeObj, m, argVals);
+ return NULL;
+ case PRIMLIB_OBJECT:
+ return (*env)->CallObjectMethod(env, invokeObj, m, argVals);
+ default:
+ JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Unknown primitive type! Internal error.");
+ return NULL;
+ }
+ }
+}
+
diff --git a/native/java.lang.reflect/Method.h b/native/java.lang.reflect/Method.h
new file mode 100644
index 000000000..e5bb9c5d6
--- /dev/null
+++ b/native/java.lang.reflect/Method.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_lang_reflect_Method */
+
+#ifndef _Included_java_lang_reflect_Method
+#define _Included_java_lang_reflect_Method
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: java_lang_reflect_Method
+ * Method: initNativeState
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_Method_initNativeState
+ (JNIEnv *, jclass);
+
+/*
+ * Class: java_lang_reflect_Method
+ * Method: finalizeNative
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_Method_finalizeNative
+ (JNIEnv *, jobject);
+
+/*
+ * Class: java_lang_reflect_Method
+ * Method: invokeNative
+ * Signature: (Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;ILjava/lang/Class;[Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_Method_invokeNative
+ (JNIEnv *, jobject, jobject, jobjectArray, jclass, jstring, jint, jclass, jobjectArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/native/java.lang.reflect/README b/native/java.lang.reflect/README
new file mode 100755
index 000000000..6e4ce7fd0
--- /dev/null
+++ b/native/java.lang.reflect/README
@@ -0,0 +1,17 @@
+README for java.lang.reflect Native side
+
+
+Jun 20 1998: John Keiser
+Initial Version
+
+Currently Reflection depends heavily on the VMI and JVMDI. The only way I can
+think of to deal with this is to make a VMI 1.1 API that handles what JVMDI
+does not. When one compiles the 1.1 version of Reflection, it can just use
+that.
+
+Field is not done yet. Don't bother compiling it.
+
+This whole thing is quite untested. I am checking in now because I want
+Geoffrey, the Serialization dude, to have some reference code to work with.
+His stuff is not altogether different from mine, and in order to make his
+code efficient he may need to borrow from mine.
diff --git a/native/java.lang.reflect/STATUS b/native/java.lang.reflect/STATUS
new file mode 100755
index 000000000..6c483a294
--- /dev/null
+++ b/native/java.lang.reflect/STATUS
@@ -0,0 +1,8 @@
+STATUS for java.lang.reflect Native side
+
+1.1:
+Method.c : compiled, untested.
+Field.c : unknown. Needs changes before I'm happy with it.
+Constructor.c: all methods compile.
+Array.c : compiled, untested.
+reflect.c : compiled, untested. \ No newline at end of file
diff --git a/native/java.lang.reflect/TODO b/native/java.lang.reflect/TODO
new file mode 100755
index 000000000..dc446ab3b
--- /dev/null
+++ b/native/java.lang.reflect/TODO
@@ -0,0 +1,9 @@
+TODO for java.lang.reflect Native side:
+
+- Field.c: reimplement almost everything. Don't even know if this compiles.
+
+- Note: I am planning on moving all JDK 1.2 dependencies to VMI so that 1.1 VMs
+ like Kaffe that do not implement JVMDI can still interface to
+ java.lang.reflect.
+
+- Makefile needs to be created, as well. \ No newline at end of file
diff --git a/native/java.lang.reflect/reflect.c b/native/java.lang.reflect/reflect.c
new file mode 100755
index 000000000..b6853467c
--- /dev/null
+++ b/native/java.lang.reflect/reflect.c
@@ -0,0 +1,218 @@
+#include "reflect.h"
+#include <primlib.h>
+#include <string.h>
+#include <vmi.h>
+#include <jcl.h>
+
+#define SAME_CLASS 1
+#define SAME_PACKAGE 2
+#define SUBCLASS 3
+#define UNRELATED 4
+
+static jint StartMethodSignature(JNIEnv * env, char * signatureBuf, jobjectArray argTypes);
+
+JNIEXPORT jboolean JNICALL REFLECT_HasLinkLevelAccessToMember(JNIEnv * env, jclass accessor, jclass accessee, jint memberMods) {
+ jstring accessorNameUTF;
+ jstring accesseeNameUTF;
+ char * accessorName;
+ char * accesseeName;
+ jint classMods;
+ int lastAccessorDot;
+ int lastAccesseeDot;
+ int comparison = UNRELATED;
+ int accessorLen;
+ int accesseeLen;
+ vmiError vmiErr;
+
+ vmiErr = VMI_GetClassModifiers(env, accessee, &classMods);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return JNI_FALSE;
+ }
+ vmiErr = VMI_GetClassName(env, accessor, &accessorNameUTF);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return JNI_FALSE;
+ }
+ vmiErr = VMI_GetClassName(env, accessee, &accesseeNameUTF);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return JNI_FALSE;
+ }
+
+ accessorName = JCL_jstring_to_cstring(env, accessorNameUTF);
+ if(accessorName == NULL) {
+ return JNI_FALSE;
+ }
+
+ accesseeName = JCL_jstring_to_cstring(env, accesseeNameUTF);
+ if(accesseeName == NULL) {
+ return JNI_FALSE;
+ }
+
+ accessorLen = strlen(accessorName);
+ accesseeLen = strlen(accesseeName);
+
+ if(accessorLen == accesseeLen) {
+ if(!strcmp(accessorName,accesseeName)) {
+ comparison = SAME_CLASS;
+ }
+ }
+
+ if(comparison == UNRELATED) {
+ lastAccessorDot = strlen(accessorName) - 1;
+ while(lastAccessorDot > 0) {
+ if(accessorName[lastAccessorDot] == '.') {
+ break;
+ }
+ lastAccessorDot--;
+ }
+ lastAccesseeDot = strlen(accesseeName) - 1;
+ while(lastAccesseeDot > 0) {
+ if(accesseeName[lastAccesseeDot] == '.') {
+ break;
+ }
+ lastAccesseeDot--;
+ }
+ if(lastAccessorDot == lastAccesseeDot) {
+ if(strncmp(accessorName,accesseeName,lastAccessorDot) == 0) {
+ comparison = SAME_PACKAGE;
+ }
+ }
+ }
+ if(comparison == UNRELATED) {
+ if((*env)->IsAssignableFrom(env, accessor, accessee)) {
+ comparison = SUBCLASS;
+ }
+ }
+
+ JCL_free_cstring(env, accessorNameUTF, accessorName);
+ JCL_free_cstring(env, accesseeNameUTF, accesseeName);
+
+ switch(comparison) {
+ case SAME_CLASS:
+ return JNI_TRUE;
+ case SAME_PACKAGE:
+ return !((classMods & VMI_MOD_PRIVATE) || (memberMods & VMI_MOD_PRIVATE));
+ case SUBCLASS:
+ return ((classMods & VMI_MOD_PROTECTED) || (classMods & VMI_MOD_PUBLIC))
+ && ((memberMods & VMI_MOD_PROTECTED) || (memberMods & VMI_MOD_PUBLIC));
+ case UNRELATED:
+ default:
+ return (classMods & VMI_MOD_PUBLIC) && (memberMods & VMI_MOD_PUBLIC);
+ }
+}
+
+static jint StartMethodSignature(JNIEnv * env, char * signatureBuf, jobjectArray argTypes) {
+ jint pos = 0;
+ jint lengthOfFieldSig;
+ jsize numArgs;
+ jsize argIndex;
+ jclass argType;
+
+ signatureBuf[pos] = '(';
+ pos++;
+
+ numArgs = (*env)->GetArrayLength(env, argTypes);
+
+ for(argIndex = 0; argIndex < numArgs; argIndex++) {
+ argType = (*env)->GetObjectArrayElement(env, argTypes, argIndex);
+ lengthOfFieldSig = REFLECT_GetFieldSignature(env, signatureBuf+pos, argType);
+ if(lengthOfFieldSig == -1) {
+ return -1;
+ }
+ pos += lengthOfFieldSig;
+ }
+
+ signatureBuf[pos] = ')';
+ pos++;
+}
+
+JNIEXPORT jint JNICALL REFLECT_GetMethodSignature(JNIEnv * env, char * signatureBuf,
+ jobjectArray argTypes, jclass retType) {
+ jint pos;
+ jint lengthOfFieldSig;
+ pos = StartMethodSignature(env, signatureBuf, argTypes);
+ if(pos == -1) {
+ return -1;
+ }
+
+ lengthOfFieldSig = REFLECT_GetFieldSignature(env, signatureBuf+pos, retType);
+ if(lengthOfFieldSig == -1) {
+ return -1;
+ }
+ pos += lengthOfFieldSig;
+ return pos;
+}
+
+JNIEXPORT jint JNICALL REFLECT_GetConstructorSignature(JNIEnv * env, char * signatureBuf,
+ jobjectArray argTypes) {
+ jint pos;
+ pos = StartMethodSignature(env, signatureBuf, argTypes);
+ if(pos == -1) {
+ return -1;
+ }
+ signatureBuf[pos] = 'V';
+ pos++;
+ return pos;
+}
+
+JNIEXPORT jint JNICALL REFLECT_GetFieldSignature(JNIEnv * env, char * signatureBuf,
+ jclass fieldType) {
+ jstring classNameUTF;
+ char * className;
+ jint reflectType;
+ vmiError vmiErr;
+
+ reflectType = PRIMLIB_GetReflectiveType(env, fieldType);
+
+ switch(reflectType) {
+ case PRIMLIB_BOOLEAN:
+ signatureBuf[0] = 'Z';
+ return 1;
+ case PRIMLIB_BYTE:
+ signatureBuf[0] = 'B';
+ return 1;
+ case PRIMLIB_CHAR:
+ signatureBuf[0] = 'C';
+ return 1;
+ case PRIMLIB_SHORT:
+ signatureBuf[0] = 'S';
+ return 1;
+ case PRIMLIB_INT:
+ signatureBuf[0] = 'I';
+ return 1;
+ case PRIMLIB_LONG:
+ signatureBuf[0] = 'J';
+ return 1;
+ case PRIMLIB_FLOAT:
+ signatureBuf[0] = 'F';
+ return 1;
+ case PRIMLIB_DOUBLE:
+ signatureBuf[0] = 'D';
+ return 1;
+ case PRIMLIB_VOID:
+ signatureBuf[0] = 'V';
+ return 1;
+ case PRIMLIB_OBJECT:
+ signatureBuf[0] = 'L';
+ vmiErr = VMI_GetClassName(env, fieldType, &classNameUTF);
+ if(vmiErr != VMI_ERROR_NONE) {
+ VMI_ThrowAppropriateException(env, vmiErr);
+ return -1;
+ }
+
+ className = JCL_jstring_to_cstring(env, classNameUTF);
+ if(className == NULL) {
+ return -1;
+ }
+ strcpy(signatureBuf+1,className);
+ strcat(signatureBuf,";");
+ return strlen(signatureBuf);
+ case PRIMLIB_NULL:
+ default:
+ JCL_ThrowException(env, "java/lang/NullPointerException", "Null class in REFLECT_GetFieldSignature()");
+ return -1;
+ }
+}
+
diff --git a/native/java.lang.reflect/reflect.h b/native/java.lang.reflect/reflect.h
new file mode 100755
index 000000000..7f33d396d
--- /dev/null
+++ b/native/java.lang.reflect/reflect.h
@@ -0,0 +1,13 @@
+#ifndef __REFLECT_H__
+#define __REFLECT_H__
+
+#include <jni.h>
+
+#define MAX_SIGNATURE_SIZE 4096
+
+JNIEXPORT jboolean JNICALL REFLECT_HasLinkLevelAccessToMember(JNIEnv * env, jclass accessor, jclass accessee, jint memberMods);
+JNIEXPORT jint JNICALL REFLECT_GetMethodSignature(JNIEnv * env, char * signatureBuf, jobjectArray argTypes, jclass retType);
+JNIEXPORT jint JNICALL REFLECT_GetConstructorSignature(JNIEnv * env, char * signatureBuf, jobjectArray argTypes);
+JNIEXPORT jint JNICALL REFLECT_GetFieldSignature (JNIEnv * env, char * signatureBuf, jclass fieldType);
+
+#endif \ No newline at end of file