diff options
author | John Keiser <shalom@gnu.org> | 1998-06-21 06:26:31 +0000 |
---|---|---|
committer | John Keiser <shalom@gnu.org> | 1998-06-21 06:26:31 +0000 |
commit | 4870b0a600e3ad13c02fc8a047b8f10a9800e40f (patch) | |
tree | 34cbc164fcbc2ada2de81ebfe3c3bcd88db6819b | |
parent | 940dc05ba3e2e6a0b2991dfe611efe06718263ec (diff) | |
download | classpath-4870b0a600e3ad13c02fc8a047b8f10a9800e40f.tar.gz |
Initial Revision
-rw-r--r-- | native/java.lang.reflect/Array.c | 27 | ||||
-rw-r--r-- | native/java.lang.reflect/Array.h | 29 | ||||
-rwxr-xr-x | native/java.lang.reflect/Constructor.c | 180 | ||||
-rw-r--r-- | native/java.lang.reflect/Constructor.h | 37 | ||||
-rwxr-xr-x | native/java.lang.reflect/DEPENDENCIES | 29 | ||||
-rwxr-xr-x | native/java.lang.reflect/Method.c | 381 | ||||
-rw-r--r-- | native/java.lang.reflect/Method.h | 37 | ||||
-rwxr-xr-x | native/java.lang.reflect/README | 17 | ||||
-rwxr-xr-x | native/java.lang.reflect/STATUS | 8 | ||||
-rwxr-xr-x | native/java.lang.reflect/TODO | 9 | ||||
-rwxr-xr-x | native/java.lang.reflect/reflect.c | 218 | ||||
-rwxr-xr-x | native/java.lang.reflect/reflect.h | 13 |
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 |