diff options
-rw-r--r-- | libjava/ChangeLog | 38 | ||||
-rw-r--r-- | libjava/boehm.cc | 4 | ||||
-rw-r--r-- | libjava/gcj/field.h | 27 | ||||
-rw-r--r-- | libjava/gcj/method.h | 8 | ||||
-rw-r--r-- | libjava/include/jni.h | 654 | ||||
-rw-r--r-- | libjava/include/jvm.h | 19 | ||||
-rw-r--r-- | libjava/java/lang/Class.h | 22 | ||||
-rw-r--r-- | libjava/java/lang/reflect/natConstructor.cc | 4 | ||||
-rw-r--r-- | libjava/java/lang/reflect/natMethod.cc | 215 | ||||
-rw-r--r-- | libjava/jni.cc | 1210 |
10 files changed, 1669 insertions, 532 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 8a8e629..ffe657a 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,41 @@ +2000-01-21 Tom Tromey <tromey@cygnus.com> + + * java/lang/reflect/natConstructor.cc (newInstance): Use + _Jv_CallAnyMethodA. + * include/jvm.h: Declare _Jv_CallAnyMethodA. + * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Renamed + from _Jv_CallNonvirtualMethodA. Changed interface; overloaded. + Include <jni.h>. + (COPY): Removed. + (invoke): Use _Jv_CallAnyMethodA. + (VAL): Redefined. + * java/lang/Class.h (Class): Declare JvGetFirstStaticField, + JvNumStaticFields, JvNumMethods, and JvGetFirstMethod as friend + functions. + (struct _Jv_Method): Added getNextMethod method. + (JvNumMethods): New function. + (JvGetFirstMethod): Likewise. + * gcj/field.h (JvGetFirstStaticField): New function. + (JvNumStaticFields): Likewise. + (getNextField): Renamed from getNextInstanceField. + (struct _Jv_Field): New method getClass. + * jni.cc: Wrote many new functions. + * include/jni.h (JNI_TRUE): Define. + (JNI_FALSE): Likewise. + (jobject, jclass, jstring, jarray, jthrowable, jobjectArray, + jbyteArray, jshortArray, jintArray, jlongArray, jbooleanArray, + jcharArray, jfloatArray, jdoubleArray): New typedefs. + (jfieldID, jmethodID): Likewise. + (JNI_COMMIT, JNI_ABORT): New defines. + (JNINativeMethod): New struct. + (struct JNINativeInterface): Correctly declared more entries. + (class _Jv_JNIEnv): Added `ex' member. + (JNI_VERSION_1_1): New define. + (JNI_VERSION_1_2): Likewise. + + * boehm.cc (_Jv_MarkObj): Use getNextField, not + getNextInstanceField. + 2000-01-20 Tom Tromey <tromey@cygnus.com> * resolve.cc (StringClass): Removed. diff --git a/libjava/boehm.cc b/libjava/boehm.cc index c04e578..2c50c5c 100644 --- a/libjava/boehm.cc +++ b/libjava/boehm.cc @@ -1,6 +1,6 @@ // boehm.cc - interface between libjava and Boehm GC. -/* Copyright (C) 1998, 1999 Red Hat, Inc. +/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc. This file is part of libgcj. @@ -256,7 +256,7 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/) MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, elabel); } - field = field->getNextInstanceField (); + field = field->getNextField (); } klass = klass->getSuperclass(); } diff --git a/libjava/gcj/field.h b/libjava/gcj/field.h index 219da9e..28006fc 100644 --- a/libjava/gcj/field.h +++ b/libjava/gcj/field.h @@ -1,6 +1,6 @@ // field.h - Header file for fieldID instances. -*- c++ -*- -/* Copyright (C) 1998, 1999 Red Hat, Inc. +/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc. This file is part of libgcj. @@ -30,7 +30,7 @@ struct _Jv_Field _Jv_ushort flags; #ifdef COMPACT_FIELDS - short nameIndex; /* ofsfet in class's name table */ + short nameIndex; /* offset in class's name table */ #else _Jv_ushort bsize; /* not really needed ... */ #endif @@ -51,7 +51,7 @@ struct _Jv_Field jobject getObjectField (jobject obj) { return *(jobject *)((char *)obj + getOffset ()); } - jfieldID getNextInstanceField () { return this + 1; } + jfieldID getNextField () { return this + 1; } jboolean isRef () { @@ -66,6 +66,12 @@ struct _Jv_Field } } + jclass getClass () + { + JvAssert (isResolved ()); + return type; + } + // FIXME - may need to mask off internal flags. int getModifiers() { return flags; } @@ -79,6 +85,7 @@ struct _Jv_Field }; #ifdef __cplusplus + inline jbyte _Jv_GetStaticByteField (jclass, _Jv_Field* field) { @@ -151,6 +158,18 @@ JvNumInstanceFields (jclass klass) return klass->field_count - klass->static_field_count; } +extern inline jfieldID +JvGetFirstStaticField (jclass klass) +{ + return &(klass->fields[0]); +} + +extern inline jint +JvNumStaticFields (jclass klass) +{ + return klass->static_field_count; +} + extern inline jboolean JvFieldIsRef (jfieldID field) { @@ -164,6 +183,6 @@ JvGetObjectField (jobject obj, _Jv_Field* field) } #endif /* defined (__GCJ_CNI_H__) */ -#endif +#endif /* __cplusplus */ #endif /* __GCJ_FIELD_H */ diff --git a/libjava/gcj/method.h b/libjava/gcj/method.h index 13f30fe..fe8f03b 100644 --- a/libjava/gcj/method.h +++ b/libjava/gcj/method.h @@ -1,6 +1,6 @@ -// java-method.h - Header file for methodID instances. -*- c++ -*- +// method.h - Header file for methodID instances. -*- c++ -*- -/* Copyright (C) 1999 Red Hat, Inc. +/* Copyright (C) 1999, 2000 Red Hat, Inc. This file is part of libgcj. @@ -11,8 +11,10 @@ details. */ #ifndef __GCJ_METHOD_H__ #define __GCJ_METHOD_H__ +#include <java/lang/Class.h> + extern inline jmethodID -_Jv_FromReflectedMethod(java::lang::reflect::Method *method) +_Jv_FromReflectedMethod (java::lang::reflect::Method *method) { return (jmethodID) ((char *) method->declaringClass->methods + method->offset); diff --git a/libjava/include/jni.h b/libjava/include/jni.h index f5186e5..c2ba2f2 100644 --- a/libjava/include/jni.h +++ b/libjava/include/jni.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999 Red Hat, Inc. +/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc. This file is part of libgcj. @@ -6,6 +6,11 @@ This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ +/* Note: this file must be compilable by the C compiler (for now, + assuming GNU C is ok). This means you must never use `//' + comments, and all C++-specific code must be conditional on + __cplusplus. */ + #ifndef __GCJ_JNI_H__ #define __GCJ_JNI_H__ @@ -14,11 +19,15 @@ details. */ #ifdef __cplusplus -// This is wrong, because it pollutes the name-space too much! +/* This is wrong, because it pollutes the name-space too much! */ #include <gcj/javaprims.h> typedef struct _Jv_JNIEnv JNIEnv; -#else + +#define JNI_TRUE true +#define JNI_FALSE false + +#else /* __cplusplus */ typedef int jbyte __attribute__((__mode__(__QI__))); typedef int jshort __attribute__((__mode__(__HI__))); @@ -30,20 +39,51 @@ typedef float jfloat; typedef double jdouble; typedef jint jsize; +typedef void *jobject; +typedef jobject jclass; +typedef jobject jstring; +typedef jobject jarray; +typedef jobject jthrowable; +typedef jobject jobjectArray; +typedef jobject jbyteArray; +typedef jobject jshortArray; +typedef jobject jintArray; +typedef jobject jlongArray; +typedef jobject jbooleanArray; +typedef jobject jcharArray; +typedef jobject jfloatArray; +typedef jobject jdoubleArray; + +/* Dummy defines. */ +typedef void *jfieldID; +typedef void *jmethodID; + typedef const struct JNINativeInterface *JNIEnv; -#endif + +#define JNI_TRUE 1 +#define JNI_TRUE 0 + +#endif /* __cplusplus */ + +/* Version numbers. */ +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 + +/* Used when releasing array elements. */ +#define JNI_COMMIT 1 +#define JNI_ABORT 2 typedef union jvalue { jboolean z; jbyte b; jchar c; - jshort s; - jint i; + jshort s; + jint i; jlong j; - jfloat f; + jfloat f; jdouble d; - jobject l; + jobject l; } jvalue; typedef void * (*_Jv_func)(...); @@ -54,7 +94,7 @@ struct JNINativeInterface _Jv_func reserved1; _Jv_func reserved2; _Jv_func reserved3; - _Jv_func GetVersion; + jint (*GetVersion) (JNIEnv*); _Jv_func DefineClass; _Jv_func FindClass; _Jv_func reserved4; @@ -64,233 +104,415 @@ struct JNINativeInterface jboolean (*IsAssignableFrom) (JNIEnv*, jclass, jclass); _Jv_func reserved7; jint (*Throw) (JNIEnv*, jthrowable); - _Jv_func ThrowNew; - _Jv_func ExceptionOccurred; - _Jv_func ExceptionDescribe; - _Jv_func ExceptionClear; - _Jv_func FatalError; + jint (*ThrowNew) (JNIEnv*, jclass, const char *); + jthrowable (*ExceptionOccurred) (JNIEnv *); + void (*ExceptionDescribe) (JNIEnv *); + void (*ExceptionClear) (JNIEnv *); + void (*FatalError) (JNIEnv *, const char *); _Jv_func reserved8; _Jv_func reserved9; _Jv_func NewGlobalRef; _Jv_func DeleteGlobalRef; _Jv_func DeleteLocalRef; - _Jv_func IsSameObject; + jboolean (*IsSameObject) (JNIEnv *, jobject, jobject); _Jv_func reserved10; _Jv_func reserved11; - _Jv_func AllocObject; - _Jv_func NewObject; - _Jv_func NewObjectV; - _Jv_func NewObjectA; - _Jv_func GetObjectClass; - _Jv_func IsInstanceOf; - _Jv_func GetMethodID; - _Jv_func CallObjectMethod; - _Jv_func CallObjectMethodV; - _Jv_func CallObjectMethodA; - _Jv_func CallBooleanMethod; - _Jv_func CallBooleanMethodV; - _Jv_func CallBooleanMethodA; - _Jv_func CallByteMethod; - _Jv_func CallByteMethodV; - _Jv_func CallByteMethodA; - _Jv_func CallCharMethod; - _Jv_func CallCharMethodV; - _Jv_func CallCharMethodA; - _Jv_func CallShortMethod; - _Jv_func CallShortMethodV; - _Jv_func CallShortMethodA; - _Jv_func CallIntMethod; - _Jv_func CallIntMethodV; - _Jv_func CallIntMethodA; - _Jv_func CallLongMethod; - _Jv_func CallLongMethodV; - _Jv_func CallLongMethodA; - _Jv_func CallFloatMethod; - _Jv_func CallFloatMethodV; - _Jv_func CallFloatMethodA; - _Jv_func CallDoubleMethod; - _Jv_func CallDoubleMethodV; - _Jv_func CallDoubleMethodA; - _Jv_func CallVoidMethod; - _Jv_func CallVoidMethodV; - _Jv_func CallVoidMethodA; - _Jv_func CallNonvirtualObjectMethod; - _Jv_func CallNonvirtualObjectMethodV; - _Jv_func CallNonvirtualObjectMethodA; - jboolean (*CallNonvirtualBooleanMethod) (JNIEnv*, jobject, jclass, jmethodID, ...); - jboolean (*CallNonvirtualBooleanMethodV) (JNIEnv*, jobject, jclass, jmethodID, _Jv_va_list); - jboolean (*CallNonvirtualBooleanMethodA) (JNIEnv*, jobject, jclass, jmethodID, jvalue*); - _Jv_func CallNonvirtualByteMethod; - _Jv_func CallNonvirtualByteMethodV; - _Jv_func CallNonvirtualByteMethodA; - _Jv_func CallNonvirtualCharMethod; - _Jv_func CallNonvirtualCharMethodV; - _Jv_func CallNonvirtualCharMethodA; - _Jv_func CallNonvirtualShortMethod; - _Jv_func CallNonvirtualShortMethodV; - _Jv_func CallNonvirtualShortMethodA; - _Jv_func CallNonvirtualIntMethod; - _Jv_func CallNonvirtualIntMethodV; - _Jv_func CallNonvirtualIntMethodA; - _Jv_func CallNonvirtualLongMethod; - _Jv_func CallNonvirtualLongMethodV; - _Jv_func CallNonvirtualLongMethodA; - _Jv_func CallNonvirtualFloatMethod; - _Jv_func CallNonvirtualFloatMethodV; - _Jv_func CallNonvirtualFloatMethodA; - _Jv_func CallNonvirtualDoubleMethod; - jdouble (*CallNonvirtualDoubleMethodV) (JNIEnv*, jobject, jclass, jmethodID, _Jv_va_list); - _Jv_func CallNonvirtualDoubleMethodA; - _Jv_func CallNonvirtualVoidMethod; - _Jv_func CallNonvirtualVoidMethodV; - _Jv_func CallNonvirtualVoidMethodA; - _Jv_func GetFieldID; - jobject (*GetObjectField) (JNIEnv*, jobject, jfieldID); - jboolean (*GetBooleanField) (JNIEnv*, jobject, jfieldID); - jbyte (*GetByteField) (JNIEnv*, jobject, jfieldID); - jchar (*GetCharField) (JNIEnv*, jobject, jfieldID); - jshort (*GetShortField) (JNIEnv*, jobject, jfieldID); - jint (*GetIntField) (JNIEnv*, jobject, jfieldID); - jlong (*GetLongField) (JNIEnv*, jobject, jfieldID); - jfloat (*GetFloatField) (JNIEnv*, jobject, jfieldID); - jdouble (*GetDoubleField) (JNIEnv*, jobject, jfieldID); - _Jv_func SetObjectField; - _Jv_func SetBooleanField; - _Jv_func SetByteField; - _Jv_func SetCharField; - _Jv_func SetShortField; - _Jv_func SetIntField; - _Jv_func SetLongField; - _Jv_func SetFloatField; - _Jv_func SetDoubleField; - _Jv_func GetStaticMethodID; - _Jv_func CallStaticObjectMethod; - _Jv_func CallStaticObjectMethodV; - _Jv_func CallStaticObjectMethodA; - _Jv_func CallStaticBooleanMethod; - _Jv_func CallStaticBooleanMethodV; - _Jv_func CallStaticBooleanMethodA; - _Jv_func CallStaticByteMethod; - _Jv_func CallStaticByteMethodV; - _Jv_func CallStaticByteMethodA; - _Jv_func CallStaticCharMethod; - _Jv_func CallStaticCharMethodV; - _Jv_func CallStaticCharMethodA; - _Jv_func CallStaticShortMethod; - _Jv_func CallStaticShortMethodV; - _Jv_func CallStaticShortMethodA; - _Jv_func CallStaticIntMethod; - _Jv_func CallStaticIntMethodV; - _Jv_func CallStaticIntMethodA; - _Jv_func CallStaticLongMethod; - _Jv_func CallStaticLongMethodV; - _Jv_func CallStaticLongMethodA; - _Jv_func CallStaticFloatMethod; - _Jv_func CallStaticFloatMethodV; - _Jv_func CallStaticFloatMethodA; - _Jv_func CallStaticDoubleMethod; - _Jv_func CallStaticDoubleMethodV; - _Jv_func CallStaticDoubleMethodA; - _Jv_func CallStaticVoidMethod; - _Jv_func CallStaticVoidMethodV; - _Jv_func CallStaticVoidMethodA; - _Jv_func GetStaticFieldID; - _Jv_func GetStaticObjectField; - _Jv_func GetStaticBooleanField; - _Jv_func GetStaticByteField; - _Jv_func GetStaticCharField; - _Jv_func GetStaticShortField; - _Jv_func GetStaticIntField; - _Jv_func GetStaticLongField; - _Jv_func GetStaticFloatField; - _Jv_func GetStaticDoubleField; - _Jv_func SetStaticObjectField; - _Jv_func SetStaticBooleanField; - _Jv_func SetStaticByteField; - _Jv_func SetStaticCharField; - _Jv_func SetStaticShortField; - _Jv_func SetStaticIntField; - _Jv_func SetStaticLongField; - _Jv_func SetStaticFloatField; - _Jv_func SetStaticDoubleField; - _Jv_func NewString; - jint (*GetStringLength) (JNIEnv*, jstring); - _Jv_func GetStringChars; - _Jv_func ReleaseStringChars; - _Jv_func NewStringUTF; - _Jv_func GetStringUTFLength; - _Jv_func GetStringUTFChars; - _Jv_func ReleaseStringUTFChars; - _Jv_func GetArrayLength; - _Jv_func NewObjectArray; - _Jv_func GetObjectArrayElement; - _Jv_func SetObjectArrayElement; - _Jv_func NewBooleanArray; - _Jv_func NewByteArray; - _Jv_func NewCharArray; - _Jv_func NewShortArray; - _Jv_func NewIntArray; - _Jv_func NewLongArray; - _Jv_func NewFloatArray; - _Jv_func NewDoubleArray; - _Jv_func GetBooleanArrayElements; - _Jv_func GetByteArrayElements; - _Jv_func GetCharArrayElements; - _Jv_func GetShortArrayElements; - _Jv_func GetIntArrayElements; - _Jv_func GetLongArrayElements; - _Jv_func GetFloatArrayElements; - _Jv_func GetDoubleArrayElements; - _Jv_func ReleaseBooleanArrayElements; - _Jv_func ReleaseByteArrayElements; - _Jv_func ReleaseCharArrayElements; - _Jv_func ReleaseShortArrayElements; - _Jv_func ReleaseIntArrayElements; - _Jv_func ReleaseLongArrayElements; - _Jv_func ReleaseFloatArrayElements; - _Jv_func ReleaseDoubleArrayElements; - _Jv_func GetBooleanArrayRegion; - _Jv_func GetByteArrayRegion; - _Jv_func GetCharArrayRegion; - _Jv_func GetShortArrayRegion; - _Jv_func GetIntArrayRegion; - _Jv_func GetLongArrayRegion; - _Jv_func GetFloatArrayRegion; - _Jv_func GetDoubleArrayRegion; - _Jv_func SetBooleanArrayRegion; - _Jv_func SetByteArrayRegion; - _Jv_func SetCharArrayRegion; - _Jv_func SetShortArrayRegion; - _Jv_func SetIntArrayRegion; - _Jv_func SetLongArrayRegion; - _Jv_func SetFloatArrayRegion; - _Jv_func SetDoubleArrayRegion; + + jobject (*AllocObject) (JNIEnv *, jclass); + jobject (*NewObject) (JNIEnv *, jclass, jmethodID, ...); + jobject (*NewObjectV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jobject (*NewObjectA) (JNIEnv *, jclass, jmethodID, + jvalue *); + + jclass (*GetObjectClass) (JNIEnv *, jobject); + jboolean (*IsInstanceOf) (JNIEnv *, jobject, jclass); + jmethodID (*GetMethodID) (JNIEnv *, jclass, const char *, + const char *); + + jobject (*CallObjectMethod) (JNIEnv *, jobject, jmethodID, + ...); + jobject (*CallObjectMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jobject (*CallObjectMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jboolean (*CallBooleanMethod) (JNIEnv *, jobject, jmethodID, + ...); + jboolean (*CallBooleanMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jboolean (*CallBooleanMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jbyte (*CallByteMethod) (JNIEnv *, jobject, jmethodID, + ...); + jbyte (*CallByteMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jbyte (*CallByteMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jchar (*CallCharMethod) (JNIEnv *, jobject, jmethodID, + ...); + jchar (*CallCharMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jchar (*CallCharMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jshort (*CallShortMethod) (JNIEnv *, jobject, jmethodID, + ...); + jshort (*CallShortMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jshort (*CallShortMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jint (*CallIntMethod) (JNIEnv *, jobject, jmethodID, + ...); + jint (*CallIntMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jint (*CallIntMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jlong (*CallLongMethod) (JNIEnv *, jobject, jmethodID, + ...); + jlong (*CallLongMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jlong (*CallLongMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jfloat (*CallFloatMethod) (JNIEnv *, jobject, jmethodID, + ...); + jfloat (*CallFloatMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jfloat (*CallFloatMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + jdouble (*CallDoubleMethod) (JNIEnv *, jobject, jmethodID, + ...); + jdouble (*CallDoubleMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + jdouble (*CallDoubleMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + void (*CallVoidMethod) (JNIEnv *, jobject, jmethodID, + ...); + void (*CallVoidMethodV) (JNIEnv *, jobject, jmethodID, + _Jv_va_list); + void (*CallVoidMethodA) (JNIEnv *, jobject, jmethodID, + jvalue *); + + jobject (*CallNonvirtualObjectMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jobject (*CallNonvirtualObjectMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jobject (*CallNonvirtualObjectMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jboolean (*CallNonvirtualBooleanMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jboolean (*CallNonvirtualBooleanMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jboolean (*CallNonvirtualBooleanMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jbyte (*CallNonvirtualByteMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jbyte (*CallNonvirtualByteMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jbyte (*CallNonvirtualByteMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jchar (*CallNonvirtualCharMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jchar (*CallNonvirtualCharMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jchar (*CallNonvirtualCharMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jshort (*CallNonvirtualShortMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jshort (*CallNonvirtualShortMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jshort (*CallNonvirtualShortMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jint (*CallNonvirtualIntMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jint (*CallNonvirtualIntMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jint (*CallNonvirtualIntMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jlong (*CallNonvirtualLongMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jlong (*CallNonvirtualLongMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jlong (*CallNonvirtualLongMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jfloat (*CallNonvirtualFloatMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jfloat (*CallNonvirtualFloatMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jfloat (*CallNonvirtualFloatMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + jdouble (*CallNonvirtualDoubleMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + jdouble (*CallNonvirtualDoubleMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + jdouble (*CallNonvirtualDoubleMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + void (*CallNonvirtualVoidMethod) (JNIEnv *, jobject, jclass, + jmethodID, ...); + void (*CallNonvirtualVoidMethodV) (JNIEnv *, jobject, jclass, + jmethodID, _Jv_va_list); + void (*CallNonvirtualVoidMethodA) (JNIEnv *, jobject, jclass, + jmethodID, jvalue *); + + jfieldID (*GetFieldID) (JNIEnv *, jclass, const char *, + const char *); + + jobject (*GetObjectField) (JNIEnv *, jobject, jfieldID); + jboolean (*GetBooleanField) (JNIEnv *, jobject, jfieldID); + jbyte (*GetByteField) (JNIEnv *, jobject, jfieldID); + jchar (*GetCharField) (JNIEnv *, jobject, jfieldID); + jshort (*GetShortField) (JNIEnv *, jobject, jfieldID); + jint (*GetIntField) (JNIEnv *, jobject, jfieldID); + jlong (*GetLongField) (JNIEnv *, jobject, jfieldID); + jfloat (*GetFloatField) (JNIEnv *, jobject, jfieldID); + jdouble (*GetDoubleField) (JNIEnv *, jobject, jfieldID); + + void (*SetObjectField) (JNIEnv *, jobject, + jfieldID, jobject); + void (*SetBooleanField) (JNIEnv *, jobject, + jfieldID, jboolean); + void (*SetByteField) (JNIEnv *, jobject, + jfieldID, jbyte); + void (*SetCharField) (JNIEnv *, jobject, + jfieldID, jchar); + void (*SetShortField) (JNIEnv *, jobject, + jfieldID, jshort); + void (*SetIntField) (JNIEnv *, jobject, + jfieldID, jint); + void (*SetLongField) (JNIEnv *, jobject, + jfieldID, jlong); + void (*SetFloatField) (JNIEnv *, jobject, + jfieldID, jfloat); + void (*SetDoubleField) (JNIEnv *, jobject, + jfieldID, jdouble); + + jmethodID (*GetStaticMethodID) (JNIEnv *, jclass, const char *, + const char *); + + jobject (*CallStaticObjectMethod) (JNIEnv *, jclass, jmethodID, + ...); + jobject (*CallStaticObjectMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jobject (*CallStaticObjectMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jboolean (*CallStaticBooleanMethod) (JNIEnv *, jclass, jmethodID, + ...); + jboolean (*CallStaticBooleanMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jboolean (*CallStaticBooleanMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jbyte (*CallStaticByteMethod) (JNIEnv *, jclass, jmethodID, + ...); + jbyte (*CallStaticByteMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jbyte (*CallStaticByteMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jchar (*CallStaticCharMethod) (JNIEnv *, jclass, jmethodID, + ...); + jchar (*CallStaticCharMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jchar (*CallStaticCharMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jshort (*CallStaticShortMethod) (JNIEnv *, jclass, jmethodID, + ...); + jshort (*CallStaticShortMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jshort (*CallStaticShortMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jint (*CallStaticIntMethod) (JNIEnv *, jclass, jmethodID, + ...); + jint (*CallStaticIntMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jint (*CallStaticIntMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jlong (*CallStaticLongMethod) (JNIEnv *, jclass, jmethodID, + ...); + jlong (*CallStaticLongMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jlong (*CallStaticLongMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jfloat (*CallStaticFloatMethod) (JNIEnv *, jclass, jmethodID, + ...); + jfloat (*CallStaticFloatMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jfloat (*CallStaticFloatMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + jdouble (*CallStaticDoubleMethod) (JNIEnv *, jclass, jmethodID, + ...); + jdouble (*CallStaticDoubleMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + jdouble (*CallStaticDoubleMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + void (*CallStaticVoidMethod) (JNIEnv *, jclass, jmethodID, + ...); + void (*CallStaticVoidMethodV) (JNIEnv *, jclass, jmethodID, + _Jv_va_list); + void (*CallStaticVoidMethodA) (JNIEnv *, jclass, jmethodID, + jvalue *); + + jfieldID (*GetStaticFieldID) (JNIEnv *, jclass, const char *, + const char *); + + jobject (*GetStaticObjectField) (JNIEnv *, jclass, jfieldID); + jboolean (*GetStaticBooleanField) (JNIEnv *, jclass, jfieldID); + jbyte (*GetStaticByteField) (JNIEnv *, jclass, jfieldID); + jchar (*GetStaticCharField) (JNIEnv *, jclass, jfieldID); + jshort (*GetStaticShortField) (JNIEnv *, jclass, jfieldID); + jint (*GetStaticIntField) (JNIEnv *, jclass, jfieldID); + jlong (*GetStaticLongField) (JNIEnv *, jclass, jfieldID); + jfloat (*GetStaticFloatField) (JNIEnv *, jclass, jfieldID); + jdouble (*GetStaticDoubleField) (JNIEnv *, jclass, jfieldID); + + void (*SetStaticObjectField) (JNIEnv *, jclass, + jfieldID, jobject); + void (*SetStaticBooleanField) (JNIEnv *, jclass, + jfieldID, jboolean); + void (*SetStaticByteField) (JNIEnv *, jclass, + jfieldID, jbyte); + void (*SetStaticCharField) (JNIEnv *, jclass, + jfieldID, jchar); + void (*SetStaticShortField) (JNIEnv *, jclass, + jfieldID, jshort); + void (*SetStaticIntField) (JNIEnv *, jclass, + jfieldID, jint); + void (*SetStaticLongField) (JNIEnv *, jclass, + jfieldID, jlong); + void (*SetStaticFloatField) (JNIEnv *, jclass, + jfieldID, jfloat); + void (*SetStaticDoubleField) (JNIEnv *, jclass, + jfieldID, jdouble); + + jstring (*NewString) (JNIEnv *, const jchar *, jsize); + jint (*GetStringLength) (JNIEnv *, jstring); + const jchar * (*GetStringChars) (JNIEnv *, jstring, jboolean *); + void (*ReleaseStringChars) (JNIEnv *, jstring, const jchar *); + jstring (*NewStringUTF) (JNIEnv *, const char *); + jsize (*GetStringUTFLength) (JNIEnv *, jstring); + const char * (*GetStringUTFChars) (JNIEnv *, jstring, jboolean *); + void (*ReleaseStringUTFChars) (JNIEnv *, jstring, const char *); + jsize (*GetArrayLength) (JNIEnv *, jarray); + jarray (*NewObjectArray) (JNIEnv *, jsize, jclass, jobject); + jobject (*GetObjectArrayElement) (JNIEnv *, jobjectArray, jsize); + void (*SetObjectArrayElement) (JNIEnv *, jobjectArray, jsize, + jobject); + + jbooleanArray (*NewBooleanArray) (JNIEnv *, jsize); + jbyteArray (*NewByteArray) (JNIEnv *, jsize); + jcharArray (*NewCharArray) (JNIEnv *, jsize); + jshortArray (*NewShortArray) (JNIEnv *, jsize); + jintArray (*NewIntArray) (JNIEnv *, jsize); + jlongArray (*NewLongArray) (JNIEnv *, jsize); + jfloatArray (*NewFloatArray) (JNIEnv *, jsize); + jdoubleArray (*NewDoubleArray) (JNIEnv *, jsize); + + jboolean * (*GetBooleanArrayElements) (JNIEnv *, jbooleanArray, + jboolean *); + jbyte * (*GetByteArrayElements) (JNIEnv *, jbyteArray, + jboolean *); + jchar * (*GetCharArrayElements) (JNIEnv *, jcharArray, + jboolean *); + jshort * (*GetShortArrayElements) (JNIEnv *, jshortArray, + jboolean *); + jint * (*GetIntArrayElements) (JNIEnv *, jintArray, + jboolean *); + jlong * (*GetLongArrayElements) (JNIEnv *, jlongArray, + jboolean *); + jfloat * (*GetFloatArrayElements) (JNIEnv *, jfloatArray, + jboolean *); + jdouble * (*GetDoubleArrayElements) (JNIEnv *, jdoubleArray, + jboolean *); + + void (*ReleaseBooleanArrayElements) (JNIEnv *, jbooleanArray, + jboolean *, jint); + void (*ReleaseByteArrayElements) (JNIEnv *, jbyteArray, + jbyte *, jint); + void (*ReleaseCharArrayElements) (JNIEnv *, jcharArray, + jchar *, jint); + void (*ReleaseShortArrayElements) (JNIEnv *, jshortArray, + jshort *, jint); + void (*ReleaseIntArrayElements) (JNIEnv *, jintArray, + jint *, jint); + void (*ReleaseLongArrayElements) (JNIEnv *, jlongArray, + jlong *, jint); + void (*ReleaseFloatArrayElements) (JNIEnv *, jfloatArray, + jfloat *, jint); + void (*ReleaseDoubleArrayElements) (JNIEnv *, jdoubleArray, + jdouble *, jint); + + void (*GetBooleanArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetByteArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetCharArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetShortArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetIntArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetLongArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetFloatArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*GetDoubleArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + + void (*SetBooleanArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetByteArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetCharArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetShortArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetIntArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetLongArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetFloatArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + void (*SetDoubleArrayRegion) (JNIEnv *, jbooleanArray, + jsize, jsize, jboolean *); + _Jv_func RegisterNatives; _Jv_func UnregisterNatives; - _Jv_func MonitorEnter; - _Jv_func MonitorExit; + jint (*MonitorEnter) (JNIEnv *, jobject); + jint (*MonitorExit) (JNIEnv *, jobject); _Jv_func GetJavaVM; }; +/* This structure is used when registering native methods. */ +typedef struct +{ + char *name; + char *signature; + void *fnPtr; /* Sigh. */ +} JNINativeMethod; + #ifdef __cplusplus -struct _Jv_JNIEnv +class _Jv_JNIEnv { +public: + /* The method table. */ struct JNINativeInterface *p; - jclass GetSuperclass (jclass cl); - jsize GetStringLength (jstring str); +private: + /* The current exception. */ + jthrowable ex; -}; + /* This doesn't really protect the private contents, because anybody + can set this macro. However, if they do set it then they at + least know they are doing something unportable. */ +#ifdef GCJ_JV_JNIENV_FRIEND + GCJ_JV_JNIENV_FRIEND; +#endif -extern inline jclass -_Jv_JNIEnv::GetSuperclass (jclass cl) -{ return p->GetSuperclass (this, cl); } +public: + jclass GetSuperclass (jclass cl) + { return p->GetSuperclass (this, cl); } -extern inline jsize -_Jv_JNIEnv::GetStringLength (jstring str) -{ return p->GetStringLength (this, str); } + jsize GetStringLength (jstring str) + { return p->GetStringLength (this, str); } +}; -#endif +#endif /* __cplusplus */ #endif /* __GCJ_JNI_H__ */ diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h index ab22cd8..a8d1fac 100644 --- a/libjava/include/jvm.h +++ b/libjava/include/jvm.h @@ -1,6 +1,6 @@ // jvm.h - Header file for private implementation information. -*- c++ -*- -/* Copyright (C) 1998, 1999 Red Hat, Inc. +/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc. This file is part of libgcj. @@ -166,9 +166,20 @@ extern void _Jv_GetTypesFromSignature (jmethodID method, jclass declaringClass, JArray<jclass> **arg_types_out, jclass *return_type_out); -extern jobject _Jv_CallNonvirtualMethodA (jobject, jclass, - jmethodID, jboolean, - JArray<jclass> *, jobjectArray); + +extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type, + jmethodID meth, jboolean is_constructor, + JArray<jclass> *parameter_types, + jobjectArray args); + +union jvalue; +extern jthrowable _Jv_CallAnyMethodA (jobject obj, + jclass return_type, + jmethodID meth, + jboolean is_constructor, + JArray<jclass> *parameter_types, + jvalue *args, + jvalue *result); extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims) __attribute__((__malloc__)); diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index 2863adb..84834f3 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -60,6 +60,9 @@ struct _Jv_Method _Jv_Utf8Const *signature; unsigned short accflags; void *ncode; + + _Jv_Method *getNextMethod () + { return this + 1; } }; #define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1) @@ -168,13 +171,19 @@ private: friend jfieldID JvGetFirstInstanceField (jclass); friend jint JvNumInstanceFields (jclass); + friend jfieldID JvGetFirstStaticField (jclass); + friend jint JvNumStaticFields (jclass); + friend jobject _Jv_AllocObject (jclass, jint); friend jobjectArray _Jv_NewObjectArray (jsize, jclass, jobject); friend jobject _Jv_NewPrimArray (jclass, jint); friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID); friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *); + friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *); friend jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *); + friend jint JvNumMethods (jclass); + friend jmethodID JvGetFirstMethod (jclass); friend class _Jv_PrimClass; @@ -257,4 +266,17 @@ private: java::lang::Thread *thread; }; + +extern inline jint +JvNumMethods (jclass klass) +{ + return klass->method_count; +} + +extern inline jmethodID +JvGetFirstMethod (jclass klass) +{ + return &klass->methods[0]; +} + #endif /* __JAVA_LANG_CLASS_H__ */ diff --git a/libjava/java/lang/reflect/natConstructor.cc b/libjava/java/lang/reflect/natConstructor.cc index 6b59c95..82eb3e9 100644 --- a/libjava/java/lang/reflect/natConstructor.cc +++ b/libjava/java/lang/reflect/natConstructor.cc @@ -48,6 +48,6 @@ java::lang::reflect::Constructor::newInstance (jobjectArray args) jmethodID meth = _Jv_FromReflectedConstructor (this); // In the constructor case the return type is the type of the // constructor. - return _Jv_CallNonvirtualMethodA (NULL, declaringClass, meth, true, - parameter_types, args); + return _Jv_CallAnyMethodA (NULL, declaringClass, meth, true, + parameter_types, args); } diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc index e88c0f3..988fa1e 100644 --- a/libjava/java/lang/reflect/natMethod.cc +++ b/libjava/java/lang/reflect/natMethod.cc @@ -12,6 +12,7 @@ details. */ #include <gcj/cni.h> #include <jvm.h> +#include <jni.h> #include <java/lang/reflect/Method.h> #include <java/lang/reflect/Constructor.h> @@ -187,8 +188,8 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args) meth = _Jv_LookupDeclaredMethod (k, meth->name, meth->signature); } - return _Jv_CallNonvirtualMethodA (obj, return_type, meth, false, - parameter_types, args); + return _Jv_CallAnyMethodA (obj, return_type, meth, false, + parameter_types, args); } jint @@ -311,23 +312,22 @@ _Jv_GetTypesFromSignature (jmethodID method, // functions. It handles both Methods and Constructors, and it can // handle any return type. In the Constructor case, the `obj' // argument is unused and should be NULL; also, the `return_type' is -// the class that the constructor will construct. -jobject -_Jv_CallNonvirtualMethodA (jobject obj, - jclass return_type, - jmethodID meth, - jboolean is_constructor, - JArray<jclass> *parameter_types, - jobjectArray args) +// the class that the constructor will construct. RESULT is a pointer +// to a `jvalue' (see jni.h); for a void method this should be NULL. +// This function returns an exception (if one was thrown), or NULL if +// the call went ok. +jthrowable +_Jv_CallAnyMethodA (jobject obj, + jclass return_type, + jmethodID meth, + jboolean is_constructor, + JArray<jclass> *parameter_types, + jvalue *args, + jvalue *result) { JvAssert (! is_constructor || ! obj); JvAssert (! is_constructor || ! return_type); - // FIXME: access checks. - - if (parameter_types->length != args->length) - JvThrow (new java::lang::IllegalArgumentException); - // See whether call needs an object as the first argument. A // constructor does need a `this' argument, but it is one we create. jboolean needs_this = false; @@ -349,7 +349,6 @@ _Jv_CallNonvirtualMethodA (jobject obj, * sizeof (ffi_type *)); jclass *paramelts = elements (parameter_types); - jobject *argelts = elements (args); // FIXME: at some point the compiler is going to add extra arguments // to some functions. In particular we are going to do this for @@ -376,22 +375,11 @@ _Jv_CallNonvirtualMethodA (jobject obj, for (int arg = 0; i < param_count; ++i, ++arg) { - jclass k = argelts[arg] ? argelts[arg]->getClass() : NULL; - argtypes[i] = get_ffi_type (k); + argtypes[i] = get_ffi_type (paramelts[arg]); if (paramelts[arg]->isPrimitive()) - { - if (! argelts[arg] - || ! k - || ! can_widen (k, paramelts[arg])) - JvThrow (new java::lang::IllegalArgumentException); - size += paramelts[arg]->size(); - } + size += paramelts[arg]->size(); else - { - if (argelts[arg] && ! paramelts[arg]->isAssignableFrom (k)) - JvThrow (new java::lang::IllegalArgumentException); - size += sizeof (jobject); - } + size += sizeof (jobject); } ffi_cif cif; @@ -404,89 +392,162 @@ _Jv_CallNonvirtualMethodA (jobject obj, char *p = (char *) alloca (size); void **values = (void **) alloca (param_count * sizeof (void *)); -#define COPY(Where, What, Type) \ - do { \ - Type val = (What); \ - memcpy ((Where), &val, sizeof (Type)); \ - values[i] = (Where); \ - Where += sizeof (Type); \ - } while (0) - i = 0; if (needs_this) { - COPY (p, obj, jobject); + values[i] = p; + memcpy (p, &obj, sizeof (jobject)); + p += sizeof (jobject); ++i; } for (int arg = 0; i < param_count; ++i, ++arg) { - java::lang::Number *num = (java::lang::Number *) argelts[arg]; - if (paramelts[arg] == JvPrimClass (byte)) - COPY (p, num->byteValue(), jbyte); - else if (paramelts[arg] == JvPrimClass (short)) - COPY (p, num->shortValue(), jshort); - else if (paramelts[arg] == JvPrimClass (int)) - COPY (p, num->intValue(), jint); - else if (paramelts[arg] == JvPrimClass (long)) - COPY (p, num->longValue(), jlong); - else if (paramelts[arg] == JvPrimClass (float)) - COPY (p, num->floatValue(), jfloat); - else if (paramelts[arg] == JvPrimClass (double)) - COPY (p, num->doubleValue(), jdouble); - else if (paramelts[arg] == JvPrimClass (boolean)) - COPY (p, ((java::lang::Boolean *) argelts[arg])->booleanValue(), - jboolean); - else if (paramelts[arg] == JvPrimClass (char)) - COPY (p, ((java::lang::Character *) argelts[arg])->charValue(), jchar); + int tsize; + if (paramelts[arg]->isPrimitive()) + tsize = paramelts[arg]->size(); else - { - JvAssert (! paramelts[arg]->isPrimitive()); - COPY (p, argelts[arg], jobject); - } + tsize = sizeof (jobject); + + // Copy appropriate bits from the jvalue into the ffi array. + // FIXME: we could do this copying all in one loop, above, by + // over-allocating a bit. + values[i] = p; + memcpy (p, &args[arg], tsize); + p += tsize; } // FIXME: initialize class here. - // Largest possible value. Hopefully it is aligned! - jdouble ret_value; java::lang::Throwable *ex; using namespace java::lang; using namespace java::lang::reflect; ex = Method::hack_trampoline ((gnu::gcj::RawData *) &cif, (gnu::gcj::RawData *) meth->ncode, - (gnu::gcj::RawData *) &ret_value, + (gnu::gcj::RawData *) result, (gnu::gcj::RawData *) values); if (ex) - JvThrow (new InvocationTargetException (ex)); + // FIXME: this is wrong for JNI. But if we just return the + // exception, then the non-JNI cases won't be able to distinguish + // it from exceptions we might generate ourselves. Sigh. + ex = new InvocationTargetException (ex); + + if (is_constructor) + result->l = obj; + + return ex; +} + +// This is another version of _Jv_CallAnyMethodA, but this one does +// more checking and is used by the reflection (and not JNI) code. +jobject +_Jv_CallAnyMethodA (jobject obj, + jclass return_type, + jmethodID meth, + jboolean is_constructor, + JArray<jclass> *parameter_types, + jobjectArray args) +{ + // FIXME: access checks. + + if (parameter_types->length != args->length) + JvThrow (new java::lang::IllegalArgumentException); + + int param_count = parameter_types->length; + + jclass *paramelts = elements (parameter_types); + jobject *argelts = elements (args); + jvalue argvals[param_count]; + +#define COPY(Where, What, Type) \ + do { \ + Type val = (What); \ + memcpy ((Where), &val, sizeof (Type)); \ + } while (0) + + for (int i = 0; i < param_count; ++i) + { + jclass k = argelts[i] ? argelts[i]->getClass() : NULL; + if (paramelts[i]->isPrimitive()) + { + if (! argelts[i] + || ! k + || ! can_widen (k, paramelts[i])) + JvThrow (new java::lang::IllegalArgumentException); + } + else + { + if (argelts[i] && ! paramelts[i]->isAssignableFrom (k)) + JvThrow (new java::lang::IllegalArgumentException); + } + + java::lang::Number *num = (java::lang::Number *) argelts[i]; + if (paramelts[i] == JvPrimClass (byte)) + COPY (&argvals[i], num->byteValue(), jbyte); + else if (paramelts[i] == JvPrimClass (short)) + COPY (&argvals[i], num->shortValue(), jshort); + else if (paramelts[i] == JvPrimClass (int)) + COPY (&argvals[i], num->intValue(), jint); + else if (paramelts[i] == JvPrimClass (long)) + COPY (&argvals[i], num->longValue(), jlong); + else if (paramelts[i] == JvPrimClass (float)) + COPY (&argvals[i], num->floatValue(), jfloat); + else if (paramelts[i] == JvPrimClass (double)) + COPY (&argvals[i], num->doubleValue(), jdouble); + else if (paramelts[i] == JvPrimClass (boolean)) + COPY (&argvals[i], + ((java::lang::Boolean *) argelts[i])->booleanValue(), + jboolean); + else if (paramelts[i] == JvPrimClass (char)) + COPY (&argvals[i], + ((java::lang::Character *) argelts[i])->charValue(), + jchar); + else + { + JvAssert (! paramelts[i]->isPrimitive()); + COPY (&argvals[i], argelts[i], jobject); + } + } + + jvalue ret_value; + java::lang::Throwable *ex = _Jv_CallAnyMethodA (obj, + return_type, + meth, + is_constructor, + parameter_types, + argvals, + &ret_value); + + if (ex) + JvThrow (ex); jobject r; -#define VAL(Wrapper, Type) (new Wrapper (* (Type *) &ret_value)) +#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field)) if (is_constructor) - r = obj; - else if (return_type == JvPrimClass (byte)) - r = VAL (java::lang::Byte, jbyte); + r = ret_value.l; + else if (return_type == JvPrimClass (byte)) + r = VAL (java::lang::Byte, b); else if (return_type == JvPrimClass (short)) - r = VAL (java::lang::Short, jshort); + r = VAL (java::lang::Short, s); else if (return_type == JvPrimClass (int)) - r = VAL (java::lang::Integer, jint); + r = VAL (java::lang::Integer, i); else if (return_type == JvPrimClass (long)) - r = VAL (java::lang::Long, jlong); + r = VAL (java::lang::Long, j); else if (return_type == JvPrimClass (float)) - r = VAL (java::lang::Float, jfloat); + r = VAL (java::lang::Float, f); else if (return_type == JvPrimClass (double)) - r = VAL (java::lang::Double, jdouble); + r = VAL (java::lang::Double, d); else if (return_type == JvPrimClass (boolean)) - r = VAL (java::lang::Boolean, jboolean); + r = VAL (java::lang::Boolean, z); else if (return_type == JvPrimClass (char)) - r = VAL (java::lang::Character, jchar); + r = VAL (java::lang::Character, c); else if (return_type == JvPrimClass (void)) r = NULL; else { JvAssert (return_type == NULL || ! return_type->isPrimitive()); - r = * (Object **) &ret_value; + r = ret_value.l; } return r; diff --git a/libjava/jni.cc b/libjava/jni.cc index 9a8df1e..cc0ba6b 100644 --- a/libjava/jni.cc +++ b/libjava/jni.cc @@ -1,6 +1,6 @@ // jni.cc - JNI implementation, including the jump table. -/* Copyright (C) 1998, 1999 Red Hat, Inc. +/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc. This file is part of libgcj. @@ -8,12 +8,78 @@ This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ +// Note: currently we take the approach of not checking most +// arguments. Instead we could do more checking conditionally (e.g., +// if DEBUG is defined). That might be beneficial in some cases, +// though to me it seems that one could just as easily use the +// debugger. + #include <config.h> #include <stddef.h> +// Must define this before jni.h. +#define GCJ_JV_JNIENV_FRIEND \ + friend jthrowable &get_throwable (JNIEnv *) + +#include <gcj/cni.h> +#include <jvm.h> +#include <java-assert.h> #include <jni.h> #include <gcj/field.h> +#include <java/lang/Throwable.h> +#include <java/lang/ArrayIndexOutOfBoundsException.h> +#include <java/lang/InstantiationException.h> +#include <java/lang/NoSuchFieldError.h> +#include <java/lang/NoSuchMethodError.h> +#include <java/lang/reflect/Constructor.h> +#include <java/lang/reflect/Modifier.h> + +#define ClassClass _CL_Q34java4lang5Class +extern java::lang::Class ClassClass; +#define ObjectClass _CL_Q34java4lang6Object +extern java::lang::Class ObjectClass; + +// This enum is used to select different template instantiations in +// the invocation code. +enum invocation_type +{ + normal, + nonvirtual, + static_type, + constructor +}; + + + +// Tell the GC that a certain pointer is live. +static void +mark_for_gc (void *) +{ + // FIXME. +} + +// Unmark a pointer. +static void +unmark_for_gc (void *) +{ + // FIXME. +} + +// Return throwable in env. +jthrowable & +get_throwable (JNIEnv *env) +{ + return env->ex; +} + + + +static jint +_Jv_JNI_GetVersion (JNIEnv *) +{ + return JNI_VERSION_1_2; +} static jclass _Jv_JNI_GetSuperclass (JNIEnv *, jclass clazz) @@ -27,34 +93,556 @@ IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2) return clazz1->isAssignableFrom (clazz2); } +static jint +_Jv_JNI_Throw (JNIEnv *env, jthrowable obj) +{ + get_throwable (env) = obj; + return 0; +} + +static jint +_Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message) +{ + using namespace java::lang::reflect; + + JArray<jclass> *argtypes + = (JArray<jclass> *) JvNewObjectArray (1, &ClassClass, NULL); + + jclass *elts = elements (argtypes); + elts[0] = &StringClass; + + // FIXME: exception processing. + Constructor *cons = clazz->getConstructor (argtypes); + + jobjectArray values = JvNewObjectArray (1, &StringClass, NULL); + jobject *velts = elements (values); + velts[0] = JvNewStringUTF (message); + + // FIXME: exception processing. + jobject obj = cons->newInstance (values); + + get_throwable (env) = reinterpret_cast<jthrowable> (obj); + return 0; +} + +static jthrowable +_Jv_JNI_ExceptionOccurred (JNIEnv *env) +{ + return get_throwable (env); +} + +static void +_Jv_JNI_ExceptionDescribe (JNIEnv *env) +{ + if (get_throwable (env) != NULL) + get_throwable (env)->printStackTrace(); +} + +static void +_Jv_JNI_ExceptionClear (JNIEnv *env) +{ + get_throwable (env) = NULL; +} + +static void +_Jv_JNI_FatalError (JNIEnv *, const char *message) +{ + JvFail (message); +} + +static jboolean +_Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2) +{ + return obj1 == obj2; +} + static jobject -_Jv_JNI_GetObjectField (JNIEnv *, jobject obj, jfieldID field) +_Jv_JNI_AllocObject (JNIEnv *env, jclass clazz) { - return _Jv_GetObjectField (obj, field); + jobject obj = NULL; + using namespace java::lang::reflect; + if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers())) + get_throwable (env) = new java::lang::InstantiationException (); + else + { + // FIXME: exception processing. + // FIXME: will this work for String? + obj = JvAllocObject (clazz); + } + + return obj; } -static jbyte -_Jv_JNI_GetByteField (JNIEnv *, jobject obj, jfieldID field) +static jclass +_Jv_JNI_GetObjectClass (JNIEnv *, jobject obj) { - return _Jv_GetByteField (obj, field); + return obj->getClass(); } -static jshort -_Jv_JNI_GetShortField (JNIEnv *, jobject obj, jfieldID field) +static jboolean +_Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz) { - return _Jv_GetShortField (obj, field); + return clazz->isInstance(obj); } -static jint -_Jv_JNI_GetIntField (JNIEnv *, jobject obj, jfieldID field) + + +// +// This section concerns method invocation. +// + +template<jboolean is_static> +static jmethodID +_Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz, + const char *name, const char *sig) { - return _Jv_GetIntField (obj, field); + // FIXME: exception processing. + _Jv_InitClass (clazz); + + _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1); + _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1); + + JvAssert (! clazz->isPrimitive()); + + using namespace java::lang::reflect; + + while (clazz != NULL) + { + jint count = JvNumMethods (clazz); + jmethodID meth = JvGetFirstMethod (clazz); + + for (jint i = 0; i < count; ++i) + { + if (((is_static && Modifier::isStatic (meth->accflags)) + || (! is_static && ! Modifier::isStatic (meth->accflags))) + && _Jv_equalUtf8Consts (meth->name, name_u) + && _Jv_equalUtf8Consts (meth->signature, sig_u)) + return meth; + + meth = meth->getNextMethod(); + } + + clazz = clazz->getSuperclass (); + } + + get_throwable (env) = new java::lang::NoSuchMethodError (); + return NULL; +} + +// This is a helper function which turns a va_list into an array of +// `jvalue's. It needs signature information in order to do its work. +// The array of values must already be allocated. +static void +array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs) +{ + jclass *arg_elts = elements (arg_types); + for (int i = 0; i < arg_types->length; ++i) + { + if (arg_elts[i] == JvPrimClass (byte)) + values[i].b = va_arg (vargs, jbyte); + else if (arg_elts[i] == JvPrimClass (short)) + values[i].s = va_arg (vargs, jshort); + else if (arg_elts[i] == JvPrimClass (int)) + values[i].i = va_arg (vargs, jint); + else if (arg_elts[i] == JvPrimClass (long)) + values[i].j = va_arg (vargs, jlong); + else if (arg_elts[i] == JvPrimClass (float)) + values[i].f = va_arg (vargs, jfloat); + else if (arg_elts[i] == JvPrimClass (double)) + values[i].d = va_arg (vargs, jdouble); + else if (arg_elts[i] == JvPrimClass (boolean)) + values[i].z = va_arg (vargs, jboolean); + else if (arg_elts[i] == JvPrimClass (char)) + values[i].c = va_arg (vargs, jchar); + else + { + // An object. + values[i].l = va_arg (vargs, jobject); + } + } +} + +// This can call any sort of method: virtual, "nonvirtual", static, or +// constructor. +template<typename T, invocation_type style> +static T +_Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass, + jmethodID id, va_list vargs) +{ + if (style == normal) + id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature); + + jclass decl_class = klass ? klass : obj->getClass (); + JvAssert (decl_class != NULL); + + jclass return_type; + JArray<jclass> *arg_types; + // FIXME: exception processing. + _Jv_GetTypesFromSignature (id, decl_class, + &arg_types, &return_type); + + jvalue args[arg_types->length]; + array_from_valist (args, arg_types, vargs); + + jvalue result; + jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, + style == constructor, + arg_types, args, &result); + + if (ex != NULL) + get_throwable (env) = ex; + + // We cheat a little here. FIXME. + return * (T *) &result; +} + +template<typename T, invocation_type style> +static T +_Jv_JNI_CallAnyMethod (JNIEnv *env, jobject obj, jclass klass, + jmethodID method, ...) +{ + va_list args; + T result; + + va_start (args, method); + result = _Jv_JNI_CallAnyMethodV<T, style> (env, obj, klass, method, args); + va_end (args); + + return result; +} + +template<typename T, invocation_type style> +static T +_Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass, + jmethodID id, jvalue *args) +{ + if (style == normal) + id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature); + + jclass decl_class = klass ? klass : obj->getClass (); + JvAssert (decl_class != NULL); + + jclass return_type; + JArray<jclass> *arg_types; + // FIXME: exception processing. + _Jv_GetTypesFromSignature (id, decl_class, + &arg_types, &return_type); + + jvalue result; + jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, + style == constructor, + arg_types, args, &result); + + if (ex != NULL) + get_throwable (env) = ex; + + // We cheat a little here. FIXME. + return * (T *) &result; +} + +template<invocation_type style> +static void +_Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass, + jmethodID id, va_list vargs) +{ + if (style == normal) + id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature); + + jclass decl_class = klass ? klass : obj->getClass (); + JvAssert (decl_class != NULL); + + jclass return_type; + JArray<jclass> *arg_types; + // FIXME: exception processing. + _Jv_GetTypesFromSignature (id, decl_class, + &arg_types, &return_type); + + jvalue args[arg_types->length]; + array_from_valist (args, arg_types, vargs); + + jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, + style == constructor, + arg_types, args, NULL); + + if (ex != NULL) + get_throwable (env) = ex; +} + +template<invocation_type style> +static void +_Jv_JNI_CallAnyVoidMethod (JNIEnv *env, jobject obj, jclass klass, + jmethodID method, ...) +{ + va_list args; + + va_start (args, method); + _Jv_JNI_CallAnyVoidMethodV<style> (env, obj, klass, method, args); + va_end (args); +} + +template<invocation_type style> +static void +_Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass, + jmethodID id, jvalue *args) +{ + if (style == normal) + id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature); + + jclass decl_class = klass ? klass : obj->getClass (); + JvAssert (decl_class != NULL); + + jclass return_type; + JArray<jclass> *arg_types; + // FIXME: exception processing. + _Jv_GetTypesFromSignature (id, decl_class, + &arg_types, &return_type); + + jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, + style == constructor, + arg_types, args, NULL); + + if (ex != NULL) + get_throwable (env) = ex; +} + +// Functions with this signature are used to implement functions in +// the CallMethod family. +template<typename T> +static T +_Jv_JNI_CallMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args) +{ + return _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args); +} + +// Functions with this signature are used to implement functions in +// the CallMethod family. +template<typename T> +static T +_Jv_JNI_CallMethod (JNIEnv *env, jobject obj, jmethodID id, ...) +{ + va_list args; + T result; + + va_start (args, id); + result = _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args); + va_end (args); + + return result; +} + +// Functions with this signature are used to implement functions in +// the CallMethod family. +template<typename T> +static T +_Jv_JNI_CallMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args) +{ + return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args); +} + +static void +_Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args) +{ + _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args); +} + +static void +_Jv_JNI_CallVoidMethod (JNIEnv *env, jobject obj, jmethodID id, ...) +{ + va_list args; + + va_start (args, id); + _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args); + va_end (args); } -static jlong -_Jv_JNI_GetLongField (JNIEnv *, jobject obj, jfieldID field) +static void +_Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args) { - return _Jv_GetLongField (obj, field); + _Jv_JNI_CallAnyVoidMethodA<normal> (env, obj, NULL, id, args); +} + +// Functions with this signature are used to implement functions in +// the CallStaticMethod family. +template<typename T> +static T +_Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass, + jmethodID id, va_list args) +{ + return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args); +} + +// Functions with this signature are used to implement functions in +// the CallStaticMethod family. +template<typename T> +static T +_Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, jmethodID id, ...) +{ + va_list args; + T result; + + va_start (args, id); + result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, + id, args); + va_end (args); + + return result; +} + +// Functions with this signature are used to implement functions in +// the CallStaticMethod family. +template<typename T> +static T +_Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id, + jvalue *args) +{ + return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args); +} + +static void +_Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass, jmethodID id, + va_list args) +{ + _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args); +} + +static void +_Jv_JNI_CallStaticVoidMethod (JNIEnv *env, jclass klass, jmethodID id, ...) +{ + va_list args; + + va_start (args, id); + _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args); + va_end (args); +} + +static void +_Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass, jmethodID id, + jvalue *args) +{ + _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args); +} + +static jobject +_Jv_JNI_NewObjectV (JNIEnv *env, jclass klass, + jmethodID id, va_list args) +{ + return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass, + id, args); +} + +static jobject +_Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...) +{ + va_list args; + jobject result; + + va_start (args, id); + result = _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass, + id, args); + va_end (args); + + return result; +} + +static jobject +_Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id, + jvalue *args) +{ + return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass, + id, args); +} + + + +template<typename T> +static T +_Jv_JNI_GetField (JNIEnv *, jobject obj, jfieldID field) +{ + T *ptr = (T *) ((char *) obj + field->getOffset ()); + return *ptr; +} + +template<typename T> +static void +_Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value) +{ + T *ptr = (T *) ((char *) obj + field->getOffset ()); + *ptr = value; +} + +template<jboolean is_static> +static jfieldID +_Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz, + const char *name, const char *sig) +{ + // FIXME: exception processing. + _Jv_InitClass (clazz); + + _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1); + + jclass field_class = NULL; + if (sig[0] == '[') + field_class = _Jv_FindClassFromSignature ((char *) sig, NULL); + else + { + _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1); + field_class = _Jv_FindClass (sig_u, NULL); + } + + // FIXME: what if field_class == NULL? + + while (clazz != NULL) + { + jint count = (is_static + ? JvNumStaticFields (clazz) + : JvNumInstanceFields (clazz)); + jfieldID field = (is_static + ? JvGetFirstStaticField (clazz) + : JvGetFirstInstanceField (clazz)); + for (jint i = 0; i < count; ++i) + { + // The field is resolved as a side effect of class + // initialization. + JvAssert (field->isResolved ()); + + _Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz); + + if (_Jv_equalUtf8Consts (f_name, a_name) + && field->getClass() == field_class) + return field; + + field = field->getNextField (); + } + + clazz = clazz->getSuperclass (); + } + + get_throwable (env) = new java::lang::NoSuchFieldError (); + return NULL; +} + +template<typename T> +static T +_Jv_JNI_GetStaticField (JNIEnv *, jclass, jfieldID field) +{ + T *ptr = (T *) field->u.addr; + return *ptr; +} + +template<typename T> +static void +_Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value) +{ + T *ptr = (T *) field->u.addr; + *ptr = value; +} + +static jstring +_Jv_JNI_NewString (JNIEnv *, const jchar *unichars, jsize len) +{ + // FIXME: exception processing. + jstring r = _Jv_NewString (unichars, len); + return r; } static jsize @@ -63,6 +651,173 @@ _Jv_JNI_GetStringLength (JNIEnv *, jstring string) return string->length(); } +static const jchar * +_Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy) +{ + jchar *result = _Jv_GetStringChars (string); + mark_for_gc (result); + if (isCopy) + *isCopy = false; + return (const jchar *) result; +} + +static void +_Jv_JNI_ReleaseStringChars (JNIEnv *, jstring, const jchar *chars) +{ + unmark_for_gc ((void *) chars); +} + +static jstring +_Jv_JNI_NewStringUTF (JNIEnv *, const char *bytes) +{ + // FIXME: exception processing. + jstring r = JvNewStringUTF (bytes); + return r; +} + +static jsize +_Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string) +{ + return JvGetStringUTFLength (string); +} + +static const char * +_Jv_JNI_GetStringUTFChars (JNIEnv *, jstring string, jboolean *isCopy) +{ + jsize len = JvGetStringUTFLength (string); + // FIXME: exception processing. + char *r = (char *) _Jv_Malloc (len + 1); + JvGetStringUTFRegion (string, 0, len, r); + r[len] = '\0'; + + if (isCopy) + *isCopy = true; + + return (const char *) r; +} + +static void +_Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf) +{ + _Jv_Free ((void *) utf); +} + +static jsize +_Jv_JNI_GetArrayLength (JNIEnv *, jarray array) +{ + return array->length; +} + +static jarray +_Jv_JNI_NewObjectArray (JNIEnv *, jsize length, jclass elementClass, + jobject init) +{ + // FIXME: exception processing. + jarray result = JvNewObjectArray (length, elementClass, init); + return result; +} + +static jobject +_Jv_JNI_GetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index) +{ + jobject *elts = elements (array); + return elts[index]; +} + +static void +_Jv_JNI_SetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index, + jobject value) +{ + // FIXME: exception processing. + _Jv_CheckArrayStore (array, value); + jobject *elts = elements (array); + elts[index] = value; +} + +template<typename T, jclass K> +static JArray<T> * +_Jv_JNI_NewPrimitiveArray (JNIEnv *, jsize length) +{ + return (JArray<T> *) _Jv_NewPrimArray (K, length); +} + +template<typename T> +static T * +_Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array, + jboolean *isCopy) +{ + T *elts = elements (array); + if (isCopy) + { + // We elect never to copy. + *isCopy = false; + } + mark_for_gc (elts); + return elts; +} + +template<typename T> +static void +_Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *, + T *elems, jint /* mode */) +{ + // Note that we ignore MODE. We can do this because we never copy + // the array elements. My reading of the JNI documentation is that + // this is an option for the implementor. + unmark_for_gc (elems); +} + +template<typename T> +static void +_Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array, + jsize start, jsize len, + T *buf) +{ + if (start < 0 || len >= array->length || start + len >= array->length) + { + // FIXME: index. + get_throwable (env) = new java::lang::ArrayIndexOutOfBoundsException (); + } + else + { + T *elts = elements (array) + start; + memcpy (buf, elts, len * sizeof (T)); + } +} + +template<typename T> +static void +_Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array, + jsize start, jsize len, T *buf) +{ + if (start < 0 || len >= array->length || start + len >= array->length) + { + // FIXME: index. + get_throwable (env) = new java::lang::ArrayIndexOutOfBoundsException (); + } + else + { + T *elts = elements (array) + start; + memcpy (elts, buf, len * sizeof (T)); + } +} + +static jint +_Jv_JNI_MonitorEnter (JNIEnv *, jobject obj) +{ + // FIXME: exception processing. + jint r = _Jv_MonitorEnter (obj); + return r; +} + +static jint +_Jv_JNI_MonitorExit (JNIEnv *, jobject obj) +{ + // FIXME: exception processing. + jint r = _Jv_MonitorExit (obj); + return r; +} + // JDK 1.2 jobject _Jv_JNI_ToReflectedField (JNIEnv *, jclass cls, jfieldID fieldID) @@ -82,227 +837,234 @@ _Jv_JNI_FromReflectedField (JNIEnv *, java::lang::reflect::Field *field) } #define NOT_IMPL NULL +#define RESERVED NULL struct JNINativeInterface _Jv_JNIFunctions = { - NULL, - NULL, - NULL, - NULL, - NOT_IMPL /* GetVersion */, + RESERVED, + RESERVED, + RESERVED, + RESERVED, + _Jv_JNI_GetVersion, NOT_IMPL /* DefineClass */, NOT_IMPL /* FindClass */, - NULL, - NULL, - NULL, + RESERVED, + RESERVED, + RESERVED, _Jv_JNI_GetSuperclass, IsAssignableFrom, - NULL, - NOT_IMPL /* Throw */, - NOT_IMPL /* ThrowNew */, - NOT_IMPL /* ExceptionOccurred */, - NOT_IMPL /* ExceptionDescribe */, - NOT_IMPL /* ExceptionClear */, - NOT_IMPL /* FatalError */, - NOT_IMPL /* NULL */, - NOT_IMPL /* NULL */, + RESERVED, + _Jv_JNI_Throw, + _Jv_JNI_ThrowNew, + _Jv_JNI_ExceptionOccurred, + _Jv_JNI_ExceptionDescribe, + _Jv_JNI_ExceptionClear, + _Jv_JNI_FatalError, + RESERVED, + RESERVED, NOT_IMPL /* NewGlobalRef */, NOT_IMPL /* DeleteGlobalRef */, NOT_IMPL /* DeleteLocalRef */, - NOT_IMPL /* IsSameObject */, - NOT_IMPL /* NULL */, - NOT_IMPL /* NULL */, - NOT_IMPL /* AllocObject */, - NOT_IMPL /* NewObject */, - NOT_IMPL /* NewObjectV */, - NOT_IMPL /* NewObjectA */, - NOT_IMPL /* GetObjectClass */, - NOT_IMPL /* IsInstanceOf */, - NOT_IMPL /* GetMethodID */, - NOT_IMPL /* CallObjectMethod */, - NOT_IMPL /* CallObjectMethodV */, - NOT_IMPL /* CallObjectMethodA */, - NOT_IMPL /* CallBooleanMethod */, - NOT_IMPL /* CallBooleanMethodV */, - NOT_IMPL /* CallBooleanMethodA */, - NOT_IMPL /* CallByteMethod */, - NOT_IMPL /* CallByteMethodV */, - NOT_IMPL /* CallByteMethodA */, - NOT_IMPL /* CallCharMethod */, - NOT_IMPL /* CallCharMethodV */, - NOT_IMPL /* CallCharMethodA */, - NOT_IMPL /* CallShortMethod */, - NOT_IMPL /* CallShortMethodV */, - NOT_IMPL /* CallShortMethodA */, - NOT_IMPL /* CallIntMethod */, - NOT_IMPL /* CallIntMethodV */, - NOT_IMPL /* CallIntMethodA */, - NOT_IMPL /* CallLongMethod */, - NOT_IMPL /* CallLongMethodV */, - NOT_IMPL /* CallLongMethodA */, - NOT_IMPL /* CallFloatMethod */, - NOT_IMPL /* CallFloatMethodV */, - NOT_IMPL /* CallFloatMethodA */, - NOT_IMPL /* CallDoubleMethod */, - NOT_IMPL /* CallDoubleMethodV */, - NOT_IMPL /* CallDoubleMethodA */, - NOT_IMPL /* CallVoidMethod */, - NOT_IMPL /* CallVoidMethodV */, - NOT_IMPL /* CallVoidMethodA */, - NOT_IMPL /* CallNonvirtualObjectMethod */, - NOT_IMPL /* CallNonvirtualObjectMethodV */, - NOT_IMPL /* CallNonvirtualObjectMethodA */, - NOT_IMPL /* CallNonvirtualBooleanMethod */, - NOT_IMPL /* CallNonvirtualBooleanMethodV */, - NOT_IMPL /* CallNonvirtualBooleanMethodA */, - NOT_IMPL /* CallNonvirtualByteMethod */, - NOT_IMPL /* CallNonvirtualByteMethodV */, - NOT_IMPL /* CallNonvirtualByteMethodA */, - NOT_IMPL /* CallNonvirtualCharMethod */, - NOT_IMPL /* CallNonvirtualCharMethodV */, - NOT_IMPL /* CallNonvirtualCharMethodA */, - NOT_IMPL /* CallNonvirtualShortMethod */, - NOT_IMPL /* CallNonvirtualShortMethodV */, - NOT_IMPL /* CallNonvirtualShortMethodA */, - NOT_IMPL /* CallNonvirtualIntMethod */, - NOT_IMPL /* CallNonvirtualIntMethodV */, - NOT_IMPL /* CallNonvirtualIntMethodA */, - NOT_IMPL /* CallNonvirtualLongMethod */, - NOT_IMPL /* CallNonvirtualLongMethodV */, - NOT_IMPL /* CallNonvirtualLongMethodA */, - NOT_IMPL /* CallNonvirtualFloatMethod */, - NOT_IMPL /* CallNonvirtualFloatMethodV */, - NOT_IMPL /* CallNonvirtualFloatMethodA */, - NOT_IMPL /* CallNonvirtualDoubleMethod */, - NOT_IMPL /* CallNonvirtualDoubleMethodV */, - NOT_IMPL /* CallNonvirtualDoubleMethodA */, - NOT_IMPL /* CallNonvirtualVoidMethod */, - NOT_IMPL /* CallNonvirtualVoidMethodV */, - NOT_IMPL /* CallNonvirtualVoidMethodA */, - NOT_IMPL /* GetFieldID */, - _Jv_JNI_GetObjectField, - NOT_IMPL /* GetBooleanField */, - _Jv_JNI_GetByteField, - NOT_IMPL /* GetCharField */, - _Jv_JNI_GetShortField, - _Jv_JNI_GetIntField, - _Jv_JNI_GetLongField, - NOT_IMPL /* GetFloatField */, - NOT_IMPL /* GetDoubleField */, - NOT_IMPL /* SetObjectField */, - NOT_IMPL /* SetBooleanField */, - NOT_IMPL /* SetByteField */, - NOT_IMPL /* SetCharField */, - NOT_IMPL /* SetShortField */, - NOT_IMPL /* SetIntField */, - NOT_IMPL /* SetLongField */, - NOT_IMPL /* SetFloatField */, - NOT_IMPL /* SetDoubleField */, - NOT_IMPL /* GetStaticMethodID */, - NOT_IMPL /* CallStaticObjectMethod */, - NOT_IMPL /* CallStaticObjectMethodV */, - NOT_IMPL /* CallStaticObjectMethodA */, - NOT_IMPL /* CallStaticBooleanMethod */, - NOT_IMPL /* CallStaticBooleanMethodV */, - NOT_IMPL /* CallStaticBooleanMethodA */, - NOT_IMPL /* CallStaticByteMethod */, - NOT_IMPL /* CallStaticByteMethodV */, - NOT_IMPL /* CallStaticByteMethodA */, - NOT_IMPL /* CallStaticCharMethod */, - NOT_IMPL /* CallStaticCharMethodV */, - NOT_IMPL /* CallStaticCharMethodA */, - NOT_IMPL /* CallStaticShortMethod */, - NOT_IMPL /* CallStaticShortMethodV */, - NOT_IMPL /* CallStaticShortMethodA */, - NOT_IMPL /* CallStaticIntMethod */, - NOT_IMPL /* CallStaticIntMethodV */, - NOT_IMPL /* CallStaticIntMethodA */, - NOT_IMPL /* CallStaticLongMethod */, - NOT_IMPL /* CallStaticLongMethodV */, - NOT_IMPL /* CallStaticLongMethodA */, - NOT_IMPL /* CallStaticFloatMethod */, - NOT_IMPL /* CallStaticFloatMethodV */, - NOT_IMPL /* CallStaticFloatMethodA */, - NOT_IMPL /* CallStaticDoubleMethod */, - NOT_IMPL /* CallStaticDoubleMethodV */, - NOT_IMPL /* CallStaticDoubleMethodA */, - NOT_IMPL /* CallStaticVoidMethod */, - NOT_IMPL /* CallStaticVoidMethodV */, - NOT_IMPL /* CallStaticVoidMethodA */, - NOT_IMPL /* GetStaticFieldID */, - NOT_IMPL /* GetStaticObjectField */, - NOT_IMPL /* GetStaticBooleanField */, - NOT_IMPL /* GetStaticByteField */, - NOT_IMPL /* GetStaticCharField */, - NOT_IMPL /* GetStaticShortField */, - NOT_IMPL /* GetStaticIntField */, - NOT_IMPL /* GetStaticLongField */, - NOT_IMPL /* GetStaticFloatField */, - NOT_IMPL /* GetStaticDoubleField */, - NOT_IMPL /* SetStaticObjectField */, - NOT_IMPL /* SetStaticBooleanField */, - NOT_IMPL /* SetStaticByteField */, - NOT_IMPL /* SetStaticCharField */, - NOT_IMPL /* SetStaticShortField */, - NOT_IMPL /* SetStaticIntField */, - NOT_IMPL /* SetStaticLongField */, - NOT_IMPL /* SetStaticFloatField */, - NOT_IMPL /* SetStaticDoubleField */, - NOT_IMPL /* NewString */, + _Jv_JNI_IsSameObject, + RESERVED, + RESERVED, + _Jv_JNI_AllocObject, + _Jv_JNI_NewObject, + _Jv_JNI_NewObjectV, + _Jv_JNI_NewObjectA, + _Jv_JNI_GetObjectClass, + _Jv_JNI_IsInstanceOf, + _Jv_JNI_GetAnyMethodID<false>, + + _Jv_JNI_CallMethod<jobject>, + _Jv_JNI_CallMethodV<jobject>, + _Jv_JNI_CallMethodA<jobject>, + _Jv_JNI_CallMethod<jboolean>, + _Jv_JNI_CallMethodV<jboolean>, + _Jv_JNI_CallMethodA<jboolean>, + _Jv_JNI_CallMethod<jbyte>, + _Jv_JNI_CallMethodV<jbyte>, + _Jv_JNI_CallMethodA<jbyte>, + _Jv_JNI_CallMethod<jchar>, + _Jv_JNI_CallMethodV<jchar>, + _Jv_JNI_CallMethodA<jchar>, + _Jv_JNI_CallMethod<jshort>, + _Jv_JNI_CallMethodV<jshort>, + _Jv_JNI_CallMethodA<jshort>, + _Jv_JNI_CallMethod<jint>, + _Jv_JNI_CallMethodV<jint>, + _Jv_JNI_CallMethodA<jint>, + _Jv_JNI_CallMethod<jlong>, + _Jv_JNI_CallMethodV<jlong>, + _Jv_JNI_CallMethodA<jlong>, + _Jv_JNI_CallMethod<jfloat>, + _Jv_JNI_CallMethodV<jfloat>, + _Jv_JNI_CallMethodA<jfloat>, + _Jv_JNI_CallMethod<jdouble>, + _Jv_JNI_CallMethodV<jdouble>, + _Jv_JNI_CallMethodA<jdouble>, + _Jv_JNI_CallVoidMethod, + _Jv_JNI_CallVoidMethodV, + _Jv_JNI_CallVoidMethodA, + + // Nonvirtual method invocation functions follow. + _Jv_JNI_CallAnyMethod<jobject, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>, + _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>, + _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>, + _Jv_JNI_CallAnyMethod<jchar, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>, + _Jv_JNI_CallAnyMethod<jshort, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>, + _Jv_JNI_CallAnyMethod<jint, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jint, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jint, nonvirtual>, + _Jv_JNI_CallAnyMethod<jlong, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>, + _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>, + _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>, + _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>, + _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>, + _Jv_JNI_CallAnyVoidMethod<nonvirtual>, + _Jv_JNI_CallAnyVoidMethodV<nonvirtual>, + _Jv_JNI_CallAnyVoidMethodA<nonvirtual>, + + _Jv_JNI_GetAnyFieldID<false>, + _Jv_JNI_GetField<jobject>, + _Jv_JNI_GetField<jboolean>, + _Jv_JNI_GetField<jbyte>, + _Jv_JNI_GetField<jchar>, + _Jv_JNI_GetField<jshort>, + _Jv_JNI_GetField<jint>, + _Jv_JNI_GetField<jlong>, + _Jv_JNI_GetField<jfloat>, + _Jv_JNI_GetField<jdouble>, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_SetField, + _Jv_JNI_GetAnyMethodID<true>, + + _Jv_JNI_CallStaticMethod<jobject>, + _Jv_JNI_CallStaticMethodV<jobject>, + _Jv_JNI_CallStaticMethodA<jobject>, + _Jv_JNI_CallStaticMethod<jboolean>, + _Jv_JNI_CallStaticMethodV<jboolean>, + _Jv_JNI_CallStaticMethodA<jboolean>, + _Jv_JNI_CallStaticMethod<jbyte>, + _Jv_JNI_CallStaticMethodV<jbyte>, + _Jv_JNI_CallStaticMethodA<jbyte>, + _Jv_JNI_CallStaticMethod<jchar>, + _Jv_JNI_CallStaticMethodV<jchar>, + _Jv_JNI_CallStaticMethodA<jchar>, + _Jv_JNI_CallStaticMethod<jshort>, + _Jv_JNI_CallStaticMethodV<jshort>, + _Jv_JNI_CallStaticMethodA<jshort>, + _Jv_JNI_CallStaticMethod<jint>, + _Jv_JNI_CallStaticMethodV<jint>, + _Jv_JNI_CallStaticMethodA<jint>, + _Jv_JNI_CallStaticMethod<jlong>, + _Jv_JNI_CallStaticMethodV<jlong>, + _Jv_JNI_CallStaticMethodA<jlong>, + _Jv_JNI_CallStaticMethod<jfloat>, + _Jv_JNI_CallStaticMethodV<jfloat>, + _Jv_JNI_CallStaticMethodA<jfloat>, + _Jv_JNI_CallStaticMethod<jdouble>, + _Jv_JNI_CallStaticMethodV<jdouble>, + _Jv_JNI_CallStaticMethodA<jdouble>, + _Jv_JNI_CallStaticVoidMethod, + _Jv_JNI_CallStaticVoidMethodV, + _Jv_JNI_CallStaticVoidMethodA, + + _Jv_JNI_GetAnyFieldID<true>, + _Jv_JNI_GetStaticField<jobject>, + _Jv_JNI_GetStaticField<jboolean>, + _Jv_JNI_GetStaticField<jbyte>, + _Jv_JNI_GetStaticField<jchar>, + _Jv_JNI_GetStaticField<jshort>, + _Jv_JNI_GetStaticField<jint>, + _Jv_JNI_GetStaticField<jlong>, + _Jv_JNI_GetStaticField<jfloat>, + _Jv_JNI_GetStaticField<jdouble>, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_SetStaticField, + _Jv_JNI_NewString, _Jv_JNI_GetStringLength, - NOT_IMPL /* GetStringChars */, - NOT_IMPL /* ReleaseStringChars */, - NOT_IMPL /* NewStringUTF */, - NOT_IMPL /* GetStringUTFLength */, - NOT_IMPL /* GetStringUTFChars */, - NOT_IMPL /* ReleaseStringUTFChars */, - NOT_IMPL /* GetArrayLength */, - NOT_IMPL /* NewObjectArray */, - NOT_IMPL /* GetObjectArrayElement */, - NOT_IMPL /* SetObjectArrayElement */, - NOT_IMPL /* NewBooleanArray */, - NOT_IMPL /* NewByteArray */, - NOT_IMPL /* NewCharArray */, - NOT_IMPL /* NewShortArray */, - NOT_IMPL /* NewIntArray */, - NOT_IMPL /* NewLongArray */, - NOT_IMPL /* NewFloatArray */, - NOT_IMPL /* NewDoubleArray */, - NOT_IMPL /* GetBooleanArrayElements */, - NOT_IMPL /* GetByteArrayElements */, - NOT_IMPL /* GetCharArrayElements */, - NOT_IMPL /* GetShortArrayElements */, - NOT_IMPL /* GetIntArrayElements */, - NOT_IMPL /* GetLongArrayElements */, - NOT_IMPL /* GetFloatArrayElements */, - NOT_IMPL /* GetDoubleArrayElements */, - NOT_IMPL /* ReleaseBooleanArrayElements */, - NOT_IMPL /* ReleaseByteArrayElements */, - NOT_IMPL /* ReleaseCharArrayElements */, - NOT_IMPL /* ReleaseShortArrayElements */, - NOT_IMPL /* ReleaseIntArrayElements */, - NOT_IMPL /* ReleaseLongArrayElements */, - NOT_IMPL /* ReleaseFloatArrayElements */, - NOT_IMPL /* ReleaseDoubleArrayElements */, - NOT_IMPL /* GetBooleanArrayRegion */, - NOT_IMPL /* GetByteArrayRegion */, - NOT_IMPL /* GetCharArrayRegion */, - NOT_IMPL /* GetShortArrayRegion */, - NOT_IMPL /* GetIntArrayRegion */, - NOT_IMPL /* GetLongArrayRegion */, - NOT_IMPL /* GetFloatArrayRegion */, - NOT_IMPL /* GetDoubleArrayRegion */, - NOT_IMPL /* SetBooleanArrayRegion */, - NOT_IMPL /* SetByteArrayRegion */, - NOT_IMPL /* SetCharArrayRegion */, - NOT_IMPL /* SetShortArrayRegion */, - NOT_IMPL /* SetIntArrayRegion */, - NOT_IMPL /* SetLongArrayRegion */, - NOT_IMPL /* SetFloatArrayRegion */, - NOT_IMPL /* SetDoubleArrayRegion */, + _Jv_JNI_GetStringChars, + _Jv_JNI_ReleaseStringChars, + _Jv_JNI_NewStringUTF, + _Jv_JNI_GetStringUTFLength, + _Jv_JNI_GetStringUTFChars, + _Jv_JNI_ReleaseStringUTFChars, + _Jv_JNI_GetArrayLength, + _Jv_JNI_NewObjectArray, + _Jv_JNI_GetObjectArrayElement, + _Jv_JNI_SetObjectArrayElement, + _Jv_JNI_NewPrimitiveArray<jboolean, JvPrimClass (boolean)>, + _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>, + _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>, + _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>, + _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>, + _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>, + _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>, + _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_ReleasePrimitiveArrayElements, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_GetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, + _Jv_JNI_SetPrimitiveArrayRegion, NOT_IMPL /* RegisterNatives */, NOT_IMPL /* UnregisterNatives */, - NOT_IMPL /* MonitorEnter */, - NOT_IMPL /* MonitorExit */, + _Jv_JNI_MonitorEnter, + _Jv_JNI_MonitorExit, NOT_IMPL /* GetJavaVM */, }; |