1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/gc-common.h"
37 #include "mm/memory.h"
39 #include "native/jni.h"
40 #include "native/llni.h"
41 #include "native/localref.h"
42 #include "native/native.h"
44 #if defined(ENABLE_JAVASE)
45 # if defined(WITH_CLASSPATH_GNU)
46 # include "native/include/gnu_classpath_Pointer.h"
48 # if SIZEOF_VOID_P == 8
49 # include "native/include/gnu_classpath_Pointer64.h"
51 # include "native/include/gnu_classpath_Pointer32.h"
56 #include "native/include/java_lang_Object.h"
57 #include "native/include/java_lang_String.h"
58 #include "native/include/java_lang_Throwable.h"
60 #if defined(ENABLE_JAVASE)
61 # if defined(WITH_CLASSPATH_SUN)
62 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
65 # include "native/include/java_lang_ClassLoader.h"
67 # include "native/include/java_lang_reflect_Constructor.h"
68 # include "native/include/java_lang_reflect_Field.h"
69 # include "native/include/java_lang_reflect_Method.h"
71 # include "native/include/java_nio_Buffer.h"
73 # if defined(WITH_CLASSPATH_GNU)
74 # include "native/include/java_nio_DirectByteBufferImpl.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
82 #include "native/vm/java_lang_Class.h"
84 #if defined(ENABLE_JAVASE)
85 # include "native/vm/java_lang_ClassLoader.h"
86 # include "native/vm/reflect.h"
89 #include "threads/lock-common.h"
90 #include "threads/threads-common.h"
92 #include "toolbox/logging.h"
94 #include "vm/builtin.h"
95 #include "vm/exceptions.h"
96 #include "vm/global.h"
97 #include "vm/initialize.h"
98 #include "vm/primitive.h"
99 #include "vm/resolve.h"
100 #include "vm/stringlocal.h"
103 #include "vm/jit/asmpart.h"
104 #include "vm/jit/jit.h"
105 #include "vm/jit/stacktrace.h"
107 #include "vmcore/loader.h"
108 #include "vmcore/options.h"
109 #include "vmcore/statistics.h"
112 /* debug **********************************************************************/
115 # define TRACEJNICALLS(format, ...) \
117 if (opt_TraceJNICalls) { \
118 log_println((format), __VA_ARGS__); \
122 # define TRACEJNICALLS(format, ...)
126 /* global variables ***********************************************************/
128 /* global reference table *****************************************************/
130 /* hashsize must be power of 2 */
132 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
134 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
137 /* direct buffer stuff ********************************************************/
139 #if defined(ENABLE_JAVASE)
140 static classinfo *class_java_nio_Buffer;
142 # if defined(WITH_CLASSPATH_GNU)
144 static classinfo *class_java_nio_DirectByteBufferImpl;
145 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
147 # if SIZEOF_VOID_P == 8
148 static classinfo *class_gnu_classpath_Pointer64;
150 static classinfo *class_gnu_classpath_Pointer32;
153 static methodinfo *dbbirw_init;
155 # elif defined(WITH_CLASSPATH_SUN)
157 static classinfo *class_sun_nio_ch_DirectBuffer;
158 static classinfo *class_java_nio_DirectByteBuffer;
160 static methodinfo *dbb_init;
166 /* accessing instance fields macros *******************************************/
168 #define SET_FIELD(o,type,f,value) \
169 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
171 #define GET_FIELD(o,type,f) \
172 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
175 /* some forward declarations **************************************************/
177 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
180 /* jni_init ********************************************************************
182 Initialize the JNI subsystem.
184 *******************************************************************************/
188 /* create global ref hashtable */
190 hashtable_global_ref = NEW(hashtable);
192 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
195 #if defined(ENABLE_JAVASE)
196 /* Direct buffer stuff. */
198 if (!(class_java_nio_Buffer =
199 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
200 !link_class(class_java_nio_Buffer))
203 # if defined(WITH_CLASSPATH_GNU)
205 if (!(class_java_nio_DirectByteBufferImpl =
206 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
207 !link_class(class_java_nio_DirectByteBufferImpl))
210 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
212 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
216 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
218 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
221 # if SIZEOF_VOID_P == 8
222 if (!(class_gnu_classpath_Pointer64 =
223 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
224 !link_class(class_gnu_classpath_Pointer64))
227 if (!(class_gnu_classpath_Pointer32 =
228 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
229 !link_class(class_gnu_classpath_Pointer32))
233 # elif defined(WITH_CLASSPATH_SUN)
235 if (!(class_sun_nio_ch_DirectBuffer =
236 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
237 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
239 if (!link_class(class_sun_nio_ch_DirectBuffer))
240 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
242 if (!(class_java_nio_DirectByteBuffer =
243 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
244 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
246 if (!link_class(class_java_nio_DirectByteBuffer))
247 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
250 class_resolvemethod(class_java_nio_DirectByteBuffer,
252 utf_new_char("(JI)V"))))
253 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
257 #endif /* defined(ENABLE_JAVASE) */
263 /* _Jv_jni_CallObjectMethod ****************************************************
265 Internal function to call Java Object methods.
267 *******************************************************************************/
269 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
271 methodinfo *m, va_list ap)
276 STATISTICS(jniinvokation());
279 exceptions_throw_nullpointerexception();
283 /* Class initialization is done by the JIT compiler. This is ok
284 since a static method always belongs to the declaring class. */
286 if (m->flags & ACC_STATIC) {
287 /* For static methods we reset the object. */
292 /* for convenience */
297 /* For instance methods we make a virtual function table lookup. */
299 resm = method_vftbl_lookup(vftbl, m);
302 STATISTICS(jnicallXmethodnvokation());
304 ro = vm_call_method_valist(resm, o, ap);
310 /* _Jv_jni_CallObjectMethodA ***************************************************
312 Internal function to call Java Object methods.
314 *******************************************************************************/
316 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
324 STATISTICS(jniinvokation());
327 exceptions_throw_nullpointerexception();
331 /* Class initialization is done by the JIT compiler. This is ok
332 since a static method always belongs to the declaring class. */
334 if (m->flags & ACC_STATIC) {
335 /* For static methods we reset the object. */
340 /* for convenience */
345 /* For instance methods we make a virtual function table lookup. */
347 resm = method_vftbl_lookup(vftbl, m);
350 STATISTICS(jnicallXmethodnvokation());
352 ro = vm_call_method_jvalue(resm, o, args);
358 /* _Jv_jni_CallIntMethod *******************************************************
360 Internal function to call Java integer class methods (boolean,
361 byte, char, short, int).
363 *******************************************************************************/
365 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
366 methodinfo *m, va_list ap)
371 STATISTICS(jniinvokation());
374 exceptions_throw_nullpointerexception();
378 /* Class initialization is done by the JIT compiler. This is ok
379 since a static method always belongs to the declaring class. */
381 if (m->flags & ACC_STATIC) {
382 /* For static methods we reset the object. */
387 /* for convenience */
392 /* For instance methods we make a virtual function table lookup. */
394 resm = method_vftbl_lookup(vftbl, m);
397 STATISTICS(jnicallXmethodnvokation());
399 i = vm_call_method_int_valist(resm, o, ap);
405 /* _Jv_jni_CallIntMethodA ******************************************************
407 Internal function to call Java integer class methods (boolean,
408 byte, char, short, int).
410 *******************************************************************************/
412 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
413 methodinfo *m, const jvalue *args)
418 STATISTICS(jniinvokation());
421 exceptions_throw_nullpointerexception();
425 /* Class initialization is done by the JIT compiler. This is ok
426 since a static method always belongs to the declaring class. */
428 if (m->flags & ACC_STATIC) {
429 /* For static methods we reset the object. */
434 /* for convenience */
439 /* For instance methods we make a virtual function table lookup. */
441 resm = method_vftbl_lookup(vftbl, m);
444 STATISTICS(jnicallXmethodnvokation());
446 i = vm_call_method_int_jvalue(resm, o, args);
452 /* _Jv_jni_CallLongMethod ******************************************************
454 Internal function to call Java long methods.
456 *******************************************************************************/
458 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
459 methodinfo *m, va_list ap)
464 STATISTICS(jniinvokation());
467 exceptions_throw_nullpointerexception();
471 /* Class initialization is done by the JIT compiler. This is ok
472 since a static method always belongs to the declaring class. */
474 if (m->flags & ACC_STATIC) {
475 /* For static methods we reset the object. */
480 /* for convenience */
485 /* For instance methods we make a virtual function table lookup. */
487 resm = method_vftbl_lookup(vftbl, m);
490 STATISTICS(jnicallXmethodnvokation());
492 l = vm_call_method_long_valist(resm, o, ap);
498 /* _Jv_jni_CallLongMethodA *****************************************************
500 Internal function to call Java long methods.
502 *******************************************************************************/
504 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
505 methodinfo *m, const jvalue *args)
510 STATISTICS(jniinvokation());
513 exceptions_throw_nullpointerexception();
517 /* Class initialization is done by the JIT compiler. This is ok
518 since a static method always belongs to the declaring class. */
520 if (m->flags & ACC_STATIC) {
521 /* For static methods we reset the object. */
526 /* for convenience */
531 /* For instance methods we make a virtual function table lookup. */
533 resm = method_vftbl_lookup(vftbl, m);
536 STATISTICS(jnicallXmethodnvokation());
538 l = vm_call_method_long_jvalue(resm, o, args);
544 /* _Jv_jni_CallFloatMethod *****************************************************
546 Internal function to call Java float methods.
548 *******************************************************************************/
550 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
551 methodinfo *m, va_list ap)
556 /* Class initialization is done by the JIT compiler. This is ok
557 since a static method always belongs to the declaring class. */
559 if (m->flags & ACC_STATIC) {
560 /* For static methods we reset the object. */
565 /* for convenience */
570 /* For instance methods we make a virtual function table lookup. */
572 resm = method_vftbl_lookup(vftbl, m);
575 STATISTICS(jnicallXmethodnvokation());
577 f = vm_call_method_float_valist(resm, o, ap);
583 /* _Jv_jni_CallFloatMethodA ****************************************************
585 Internal function to call Java float methods.
587 *******************************************************************************/
589 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
590 methodinfo *m, const jvalue *args)
595 /* Class initialization is done by the JIT compiler. This is ok
596 since a static method always belongs to the declaring class. */
598 if (m->flags & ACC_STATIC) {
599 /* For static methods we reset the object. */
604 /* for convenience */
609 /* For instance methods we make a virtual function table lookup. */
611 resm = method_vftbl_lookup(vftbl, m);
614 STATISTICS(jnicallXmethodnvokation());
616 f = vm_call_method_float_jvalue(resm, o, args);
622 /* _Jv_jni_CallDoubleMethod ****************************************************
624 Internal function to call Java double methods.
626 *******************************************************************************/
628 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
629 methodinfo *m, va_list ap)
634 /* Class initialization is done by the JIT compiler. This is ok
635 since a static method always belongs to the declaring class. */
637 if (m->flags & ACC_STATIC) {
638 /* For static methods we reset the object. */
643 /* for convenience */
648 /* For instance methods we make a virtual function table lookup. */
650 resm = method_vftbl_lookup(vftbl, m);
653 d = vm_call_method_double_valist(resm, o, ap);
659 /* _Jv_jni_CallDoubleMethodA ***************************************************
661 Internal function to call Java double methods.
663 *******************************************************************************/
665 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
666 methodinfo *m, const jvalue *args)
671 /* Class initialization is done by the JIT compiler. This is ok
672 since a static method always belongs to the declaring class. */
674 if (m->flags & ACC_STATIC) {
675 /* For static methods we reset the object. */
680 /* for convenience */
685 /* For instance methods we make a virtual function table lookup. */
687 resm = method_vftbl_lookup(vftbl, m);
690 d = vm_call_method_double_jvalue(resm, o, args);
696 /* _Jv_jni_CallVoidMethod ******************************************************
698 Internal function to call Java void methods.
700 *******************************************************************************/
702 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
703 methodinfo *m, va_list ap)
708 exceptions_throw_nullpointerexception();
712 /* Class initialization is done by the JIT compiler. This is ok
713 since a static method always belongs to the declaring class. */
715 if (m->flags & ACC_STATIC) {
716 /* For static methods we reset the object. */
721 /* for convenience */
726 /* For instance methods we make a virtual function table lookup. */
728 resm = method_vftbl_lookup(vftbl, m);
731 STATISTICS(jnicallXmethodnvokation());
733 (void) vm_call_method_valist(resm, o, ap);
737 /* _Jv_jni_CallVoidMethodA *****************************************************
739 Internal function to call Java void methods.
741 *******************************************************************************/
743 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
744 methodinfo *m, const jvalue *args)
749 exceptions_throw_nullpointerexception();
753 /* Class initialization is done by the JIT compiler. This is ok
754 since a static method always belongs to the declaring class. */
756 if (m->flags & ACC_STATIC) {
757 /* For static methods we reset the object. */
762 /* for convenience */
767 /* For instance methods we make a virtual function table lookup. */
769 resm = method_vftbl_lookup(vftbl, m);
772 STATISTICS(jnicallXmethodnvokation());
774 (void) vm_call_method_jvalue(resm, o, args);
778 /* _Jv_jni_invokeNative ********************************************************
780 Invoke a method on the given object with the given arguments.
782 For instance methods OBJ must be != NULL and the method is looked up
783 in the vftbl of the object.
785 For static methods, OBJ is ignored.
787 *******************************************************************************/
789 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
790 java_handle_objectarray_t *params)
802 exceptions_throw_nullpointerexception();
806 argcount = m->parseddesc->paramcount;
807 paramcount = argcount;
809 /* if method is non-static, remove the `this' pointer */
811 if (!(m->flags & ACC_STATIC))
814 /* For instance methods the object has to be an instance of the
815 class the method belongs to. For static methods the obj
816 parameter is ignored. */
818 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
819 exceptions_throw_illegalargumentexception();
823 /* check if we got the right number of arguments */
825 if (((params == NULL) && (paramcount != 0)) ||
826 (params && (LLNI_array_size(params) != paramcount)))
828 exceptions_throw_illegalargumentexception();
832 /* for instance methods we need an object */
834 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
835 /* XXX not sure if that is the correct exception */
836 exceptions_throw_nullpointerexception();
840 /* for static methods, zero object to make subsequent code simpler */
841 if (m->flags & ACC_STATIC)
845 /* for instance methods we must do a vftbl lookup */
846 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
849 /* for static methods, just for convenience */
853 /* mark start of dump memory area */
855 dumpsize = dump_size();
857 /* Fill the argument array from a object-array. */
859 array = vm_array_from_objectarray(resm, o, params);
861 /* The array can be NULL if we don't have any arguments to pass
862 and the architecture does not have any argument registers
863 (e.g. i386). In that case we additionally check for an
866 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
867 /* release dump area */
869 dump_release(dumpsize);
874 switch (resm->parseddesc->returntype.decltype) {
876 (void) vm_call_array(resm, array);
880 case PRIMITIVETYPE_BOOLEAN:
881 case PRIMITIVETYPE_BYTE:
882 case PRIMITIVETYPE_CHAR:
883 case PRIMITIVETYPE_SHORT:
884 case PRIMITIVETYPE_INT:
885 value.i = vm_call_int_array(resm, array);
886 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
889 case PRIMITIVETYPE_LONG:
890 value.l = vm_call_long_array(resm, array);
891 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
894 case PRIMITIVETYPE_FLOAT:
895 value.f = vm_call_float_array(resm, array);
896 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
899 case PRIMITIVETYPE_DOUBLE:
900 value.d = vm_call_double_array(resm, array);
901 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
905 ro = vm_call_array(resm, array);
909 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
912 xptr = exceptions_get_exception();
915 /* clear exception pointer, we are calling JIT code again */
917 exceptions_clear_exception();
919 exceptions_throw_invocationtargetexception(xptr);
922 /* release dump area */
924 dump_release(dumpsize);
930 /* GetVersion ******************************************************************
932 Returns the major version number in the higher 16 bits and the
933 minor version number in the lower 16 bits.
935 *******************************************************************************/
937 jint _Jv_JNI_GetVersion(JNIEnv *env)
939 TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
941 /* We support JNI 1.6. */
943 return JNI_VERSION_1_6;
947 /* Class Operations ***********************************************************/
949 /* DefineClass *****************************************************************
951 Loads a class from a buffer of raw class data. The buffer
952 containing the raw class data is not referenced by the VM after the
953 DefineClass call returns, and it may be discarded if desired.
955 *******************************************************************************/
957 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
958 const jbyte *buf, jsize bufLen)
960 #if defined(ENABLE_JAVASE)
966 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
968 u = utf_new_char(name);
969 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
971 c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
973 co = LLNI_classinfo_wrap(c);
975 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
977 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
979 /* keep compiler happy */
986 /* FindClass *******************************************************************
988 This function loads a locally-defined class. It searches the
989 directories and zip files specified by the CLASSPATH environment
990 variable for the class with the specified name.
992 *******************************************************************************/
994 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
996 #if defined(ENABLE_JAVASE)
1000 java_lang_Class *co;
1002 STATISTICS(jniinvokation());
1004 u = utf_new_char_classname((char *) name);
1006 /* Check stacktrace for classloader, if one found use it,
1007 otherwise use the system classloader. */
1009 /* Quote from the JNI documentation:
1011 In the Java 2 Platform, FindClass locates the class loader
1012 associated with the current native method. If the native code
1013 belongs to a system class, no class loader will be
1014 involved. Otherwise, the proper class loader will be invoked to
1015 load and link the named class. When FindClass is called through
1016 the Invocation Interface, there is no current native method or
1017 its associated class loader. In that case, the result of
1018 ClassLoader.getBaseClassLoader is used." */
1020 cc = stacktrace_getCurrentClass();
1023 c = load_class_from_sysloader(u);
1025 c = load_class_from_classloader(u, cc->classloader);
1033 co = LLNI_classinfo_wrap(c);
1035 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1037 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1039 /* keep compiler happy */
1046 /* GetSuperclass ***************************************************************
1048 If clazz represents any class other than the class Object, then
1049 this function returns the object that represents the superclass of
1050 the class specified by clazz.
1052 *******************************************************************************/
1054 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1058 java_lang_Class *co;
1060 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1062 c = LLNI_classinfo_unwrap(sub);
1067 super = class_get_superclass(c);
1069 co = LLNI_classinfo_wrap(super);
1071 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1075 /* IsAssignableFrom ************************************************************
1077 Determines whether an object of sub can be safely cast to sup.
1079 *******************************************************************************/
1081 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1083 java_lang_Class *csup;
1084 java_lang_Class *csub;
1086 csup = (java_lang_Class *) sup;
1087 csub = (java_lang_Class *) sub;
1089 STATISTICS(jniinvokation());
1091 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1095 /* Throw ***********************************************************************
1097 Causes a java.lang.Throwable object to be thrown.
1099 *******************************************************************************/
1101 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1105 STATISTICS(jniinvokation());
1107 o = (java_handle_t *) obj;
1109 exceptions_set_exception(o);
1115 /* ThrowNew ********************************************************************
1117 Constructs an exception object from the specified class with the
1118 message specified by message and causes that exception to be
1121 *******************************************************************************/
1123 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1129 STATISTICS(jniinvokation());
1131 c = LLNI_classinfo_unwrap(clazz);
1134 s = javastring_new_from_utf_string(msg);
1136 /* instantiate exception object */
1138 o = native_new_and_init_string(c, s);
1143 exceptions_set_exception(o);
1149 /* ExceptionOccurred ***********************************************************
1151 Determines if an exception is being thrown. The exception stays
1152 being thrown until either the native code calls ExceptionClear(),
1153 or the Java code handles the exception.
1155 *******************************************************************************/
1157 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1161 TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1163 o = exceptions_get_exception();
1165 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1169 /* ExceptionDescribe ***********************************************************
1171 Prints an exception and a backtrace of the stack to a system
1172 error-reporting channel, such as stderr. This is a convenience
1173 routine provided for debugging.
1175 *******************************************************************************/
1177 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1183 TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1185 /* Clear exception, because we are probably calling Java code
1188 o = exceptions_get_and_clear_exception();
1191 /* get printStackTrace method from exception class */
1193 LLNI_class_get(o, c);
1195 m = class_resolveclassmethod(c,
1196 utf_printStackTrace,
1202 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1204 /* Print the stacktrace. */
1206 (void) vm_call_method(m, o);
1211 /* ExceptionClear **************************************************************
1213 Clears any exception that is currently being thrown. If no
1214 exception is currently being thrown, this routine has no effect.
1216 *******************************************************************************/
1218 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1220 STATISTICS(jniinvokation());
1222 exceptions_clear_exception();
1226 /* FatalError ******************************************************************
1228 Raises a fatal error and does not expect the VM to recover. This
1229 function does not return.
1231 *******************************************************************************/
1233 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1235 STATISTICS(jniinvokation());
1237 /* this seems to be the best way */
1239 vm_abort("JNI Fatal error: %s", msg);
1243 /* PushLocalFrame **************************************************************
1245 Creates a new local reference frame, in which at least a given
1246 number of local references can be created.
1248 *******************************************************************************/
1250 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1252 STATISTICS(jniinvokation());
1257 /* add new local reference frame to current table */
1259 if (!localref_frame_push(capacity))
1266 /* PopLocalFrame ***************************************************************
1268 Pops off the current local reference frame, frees all the local
1269 references, and returns a local reference in the previous local
1270 reference frame for the given result object.
1272 *******************************************************************************/
1274 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1276 STATISTICS(jniinvokation());
1278 /* release all current local frames */
1280 localref_frame_pop_all();
1282 /* add local reference and return the value */
1284 return _Jv_JNI_NewLocalRef(env, result);
1288 /* DeleteLocalRef **************************************************************
1290 Deletes the local reference pointed to by localRef.
1292 *******************************************************************************/
1294 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1298 STATISTICS(jniinvokation());
1300 o = (java_handle_t *) localRef;
1302 /* delete the reference */
1308 /* IsSameObject ****************************************************************
1310 Tests whether two references refer to the same Java object.
1312 *******************************************************************************/
1314 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1320 STATISTICS(jniinvokation());
1322 o1 = (java_handle_t *) ref1;
1323 o2 = (java_handle_t *) ref2;
1325 LLNI_CRITICAL_START;
1327 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1338 /* NewLocalRef *****************************************************************
1340 Creates a new local reference that refers to the same object as ref.
1342 *******************************************************************************/
1344 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1347 java_handle_t *localref;
1349 STATISTICS(jniinvokation());
1354 o = (java_handle_t *) ref;
1356 /* insert the reference */
1358 localref = localref_add(LLNI_DIRECT(o));
1364 /* EnsureLocalCapacity *********************************************************
1366 Ensures that at least a given number of local references can be
1367 created in the current thread
1369 *******************************************************************************/
1371 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1373 localref_table *lrt;
1375 STATISTICS(jniinvokation());
1377 /* get local reference table (thread specific) */
1379 lrt = LOCALREFTABLE;
1381 /* check if capacity elements are available in the local references table */
1383 if ((lrt->used + capacity) > lrt->capacity)
1384 return _Jv_JNI_PushLocalFrame(env, capacity);
1390 /* AllocObject *****************************************************************
1392 Allocates a new Java object without invoking any of the
1393 constructors for the object. Returns a reference to the object.
1395 *******************************************************************************/
1397 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1402 STATISTICS(jniinvokation());
1404 c = LLNI_classinfo_unwrap(clazz);
1406 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1407 exceptions_throw_instantiationexception(c);
1413 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1417 /* NewObject *******************************************************************
1419 Programmers place all arguments that are to be passed to the
1420 constructor immediately following the methodID
1421 argument. NewObject() accepts these arguments and passes them to
1422 the Java method that the programmer wishes to invoke.
1424 *******************************************************************************/
1426 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1433 STATISTICS(jniinvokation());
1435 c = LLNI_classinfo_unwrap(clazz);
1436 m = (methodinfo *) methodID;
1445 /* call constructor */
1447 va_start(ap, methodID);
1448 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1451 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1455 /* NewObjectV ******************************************************************
1457 Programmers place all arguments that are to be passed to the
1458 constructor in an args argument of type va_list that immediately
1459 follows the methodID argument. NewObjectV() accepts these
1460 arguments, and, in turn, passes them to the Java method that the
1461 programmer wishes to invoke.
1463 *******************************************************************************/
1465 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1472 STATISTICS(jniinvokation());
1474 c = LLNI_classinfo_unwrap(clazz);
1475 m = (methodinfo *) methodID;
1484 /* call constructor */
1486 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1488 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1492 /* NewObjectA *****************************************************************
1494 Programmers place all arguments that are to be passed to the
1495 constructor in an args array of jvalues that immediately follows
1496 the methodID argument. NewObjectA() accepts the arguments in this
1497 array, and, in turn, passes them to the Java method that the
1498 programmer wishes to invoke.
1500 *******************************************************************************/
1502 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1509 STATISTICS(jniinvokation());
1511 c = LLNI_classinfo_unwrap(clazz);
1512 m = (methodinfo *) methodID;
1521 /* call constructor */
1523 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1525 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1529 /* GetObjectClass **************************************************************
1531 Returns the class of an object.
1533 *******************************************************************************/
1535 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1539 java_lang_Class *co;
1541 STATISTICS(jniinvokation());
1543 o = (java_handle_t *) obj;
1545 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1548 LLNI_class_get(o, c);
1550 co = LLNI_classinfo_wrap(c);
1552 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1556 /* IsInstanceOf ****************************************************************
1558 Tests whether an object is an instance of a class.
1560 *******************************************************************************/
1562 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1565 java_lang_Object *o;
1567 STATISTICS(jniinvokation());
1569 c = (java_lang_Class *) clazz;
1570 o = (java_lang_Object *) obj;
1572 return _Jv_java_lang_Class_isInstance(c, o);
1576 /* Reflection Support *********************************************************/
1578 /* FromReflectedMethod *********************************************************
1580 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1581 object to a method ID.
1583 *******************************************************************************/
1585 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1587 #if defined(ENABLE_JAVASE)
1593 STATISTICS(jniinvokation());
1595 o = (java_handle_t *) method;
1600 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1601 java_lang_reflect_Method *rm;
1603 rm = (java_lang_reflect_Method *) method;
1604 LLNI_field_get_cls(rm, clazz, c);
1605 LLNI_field_get_val(rm, slot , slot);
1607 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1608 java_lang_reflect_Constructor *rc;
1610 rc = (java_lang_reflect_Constructor *) method;
1611 LLNI_field_get_cls(rc, clazz, c);
1612 LLNI_field_get_val(rc, slot , slot);
1617 m = &(c->methods[slot]);
1619 return (jmethodID) m;
1621 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1623 /* keep compiler happy */
1630 /* FromReflectedField **********************************************************
1632 Converts a java.lang.reflect.Field to a field ID.
1634 *******************************************************************************/
1636 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1638 #if defined(ENABLE_JAVASE)
1639 java_lang_reflect_Field *rf;
1644 STATISTICS(jniinvokation());
1646 rf = (java_lang_reflect_Field *) field;
1651 LLNI_field_get_cls(rf, clazz, c);
1652 LLNI_field_get_val(rf, slot , slot);
1653 f = &(c->fields[slot]);
1655 return (jfieldID) f;
1657 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1659 /* keep compiler happy */
1666 /* ToReflectedMethod ***********************************************************
1668 Converts a method ID derived from cls to an instance of the
1669 java.lang.reflect.Method class or to an instance of the
1670 java.lang.reflect.Constructor class.
1672 *******************************************************************************/
1674 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1677 #if defined(ENABLE_JAVASE)
1679 java_lang_reflect_Constructor *rc;
1680 java_lang_reflect_Method *rm;
1682 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1684 m = (methodinfo *) methodID;
1686 /* HotSpot does the same assert. */
1688 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1690 if (m->name == utf_init) {
1691 rc = reflect_constructor_new(m);
1693 return (jobject) rc;
1696 rm = reflect_method_new(m);
1698 return (jobject) rm;
1701 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1703 /* keep compiler happy */
1710 /* ToReflectedField ************************************************************
1712 Converts a field ID derived from cls to an instance of the
1713 java.lang.reflect.Field class.
1715 *******************************************************************************/
1717 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1720 STATISTICS(jniinvokation());
1722 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1728 /* Calling Instance Methods ***************************************************/
1730 /* GetMethodID *****************************************************************
1732 Returns the method ID for an instance (nonstatic) method of a class
1733 or interface. The method may be defined in one of the clazz's
1734 superclasses and inherited by clazz. The method is determined by
1735 its name and signature.
1737 GetMethodID() causes an uninitialized class to be initialized.
1739 *******************************************************************************/
1741 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1749 STATISTICS(jniinvokation());
1751 c = LLNI_classinfo_unwrap(clazz);
1756 if (!(c->state & CLASS_INITIALIZED))
1757 if (!initialize_class(c))
1760 /* try to get the method of the class or one of it's superclasses */
1762 uname = utf_new_char((char *) name);
1763 udesc = utf_new_char((char *) sig);
1765 m = class_resolvemethod(c, uname, udesc);
1767 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1768 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1773 return (jmethodID) m;
1777 /* JNI-functions for calling instance methods *********************************/
1779 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1780 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1781 jmethodID methodID, ...) \
1788 o = (java_handle_t *) obj; \
1789 m = (methodinfo *) methodID; \
1791 va_start(ap, methodID); \
1792 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1798 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1799 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1800 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1801 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1802 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1803 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1804 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1805 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1808 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1809 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1810 jmethodID methodID, va_list args) \
1816 o = (java_handle_t *) obj; \
1817 m = (methodinfo *) methodID; \
1819 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1824 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1825 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1826 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1827 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1828 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1829 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1830 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1831 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1834 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1835 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1836 jmethodID methodID, \
1837 const jvalue *args) \
1843 o = (java_handle_t *) obj; \
1844 m = (methodinfo *) methodID; \
1846 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1851 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1852 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1853 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1854 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1855 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1856 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1857 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1858 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1861 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1869 o = (java_handle_t *) obj;
1870 m = (methodinfo *) methodID;
1872 va_start(ap, methodID);
1873 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1876 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1880 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1887 o = (java_handle_t *) obj;
1888 m = (methodinfo *) methodID;
1890 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1892 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1896 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1903 o = (java_handle_t *) obj;
1904 m = (methodinfo *) methodID;
1906 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1908 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1913 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1919 o = (java_handle_t *) obj;
1920 m = (methodinfo *) methodID;
1922 va_start(ap, methodID);
1923 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1928 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1934 o = (java_handle_t *) obj;
1935 m = (methodinfo *) methodID;
1937 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1941 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1947 o = (java_handle_t *) obj;
1948 m = (methodinfo *) methodID;
1950 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1955 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1956 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1957 jclass clazz, jmethodID methodID, \
1966 o = (java_handle_t *) obj; \
1967 c = LLNI_classinfo_unwrap(clazz); \
1968 m = (methodinfo *) methodID; \
1970 va_start(ap, methodID); \
1971 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1977 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1978 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1979 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1983 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1984 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1987 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1988 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1989 jclass clazz, jmethodID methodID, \
1997 o = (java_handle_t *) obj; \
1998 c = LLNI_classinfo_unwrap(clazz); \
1999 m = (methodinfo *) methodID; \
2001 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2006 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2008 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2009 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2010 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2011 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2012 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2013 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2016 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2017 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2018 jclass clazz, jmethodID methodID, \
2019 const jvalue *args) \
2021 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2026 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2027 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2028 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2032 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2033 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2035 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2036 jclass clazz, jmethodID methodID,
2045 o = (java_handle_t *) obj;
2046 c = LLNI_classinfo_unwrap(clazz);
2047 m = (methodinfo *) methodID;
2049 va_start(ap, methodID);
2050 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2053 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2057 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2058 jclass clazz, jmethodID methodID,
2066 o = (java_handle_t *) obj;
2067 c = LLNI_classinfo_unwrap(clazz);
2068 m = (methodinfo *) methodID;
2070 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2072 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2076 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2077 jclass clazz, jmethodID methodID,
2080 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2082 return _Jv_JNI_NewLocalRef(env, NULL);
2086 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2087 jmethodID methodID, ...)
2094 o = (java_handle_t *) obj;
2095 c = LLNI_classinfo_unwrap(clazz);
2096 m = (methodinfo *) methodID;
2098 va_start(ap, methodID);
2099 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2104 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2105 jmethodID methodID, va_list args)
2111 o = (java_handle_t *) obj;
2112 c = LLNI_classinfo_unwrap(clazz);
2113 m = (methodinfo *) methodID;
2115 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2119 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2120 jmethodID methodID, const jvalue * args)
2126 o = (java_handle_t *) obj;
2127 c = LLNI_classinfo_unwrap(clazz);
2128 m = (methodinfo *) methodID;
2130 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2134 /* Accessing Fields of Objects ************************************************/
2136 /* GetFieldID ******************************************************************
2138 Returns the field ID for an instance (nonstatic) field of a
2139 class. The field is specified by its name and signature. The
2140 Get<type>Field and Set<type>Field families of accessor functions
2141 use field IDs to retrieve object fields.
2143 *******************************************************************************/
2145 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2153 STATISTICS(jniinvokation());
2155 c = LLNI_classinfo_unwrap(clazz);
2157 /* XXX NPE check? */
2159 uname = utf_new_char((char *) name);
2160 udesc = utf_new_char((char *) sig);
2162 f = class_findfield(c, uname, udesc);
2165 exceptions_throw_nosuchfielderror(c, uname);
2167 return (jfieldID) f;
2171 /* Get<type>Field Routines *****************************************************
2173 This family of accessor routines returns the value of an instance
2174 (nonstatic) field of an object. The field to access is specified by
2175 a field ID obtained by calling GetFieldID().
2177 *******************************************************************************/
2179 #define JNI_GET_FIELD(name, type, intern) \
2180 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2184 STATISTICS(jniinvokation()); \
2186 ret = GET_FIELD(obj, intern, fieldID); \
2188 return (type) ret; \
2191 JNI_GET_FIELD(Boolean, jboolean, s4)
2192 JNI_GET_FIELD(Byte, jbyte, s4)
2193 JNI_GET_FIELD(Char, jchar, s4)
2194 JNI_GET_FIELD(Short, jshort, s4)
2195 JNI_GET_FIELD(Int, jint, s4)
2196 JNI_GET_FIELD(Long, jlong, s8)
2197 JNI_GET_FIELD(Float, jfloat, float)
2198 JNI_GET_FIELD(Double, jdouble, double)
2201 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2205 STATISTICS(jniinvokation());
2207 vm_abort("this needs to be fixed");
2208 o = GET_FIELD(obj, java_handle_t*, fieldID);
2210 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2214 /* Set<type>Field Routines *****************************************************
2216 This family of accessor routines sets the value of an instance
2217 (nonstatic) field of an object. The field to access is specified by
2218 a field ID obtained by calling GetFieldID().
2220 *******************************************************************************/
2222 #define JNI_SET_FIELD(name, type, intern) \
2223 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2226 STATISTICS(jniinvokation()); \
2228 SET_FIELD(obj, intern, fieldID, value); \
2231 JNI_SET_FIELD(Boolean, jboolean, s4)
2232 JNI_SET_FIELD(Byte, jbyte, s4)
2233 JNI_SET_FIELD(Char, jchar, s4)
2234 JNI_SET_FIELD(Short, jshort, s4)
2235 JNI_SET_FIELD(Int, jint, s4)
2236 JNI_SET_FIELD(Long, jlong, s8)
2237 JNI_SET_FIELD(Float, jfloat, float)
2238 JNI_SET_FIELD(Double, jdouble, double)
2241 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2244 STATISTICS(jniinvokation());
2246 vm_abort("this needs to be fixed");
2247 SET_FIELD(obj, java_handle_t*, fieldID, value);
2251 /* Calling Static Methods *****************************************************/
2253 /* GetStaticMethodID ***********************************************************
2255 Returns the method ID for a static method of a class. The method is
2256 specified by its name and signature.
2258 GetStaticMethodID() causes an uninitialized class to be
2261 *******************************************************************************/
2263 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2271 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2273 c = LLNI_classinfo_unwrap(clazz);
2278 if (!(c->state & CLASS_INITIALIZED))
2279 if (!initialize_class(c))
2282 /* try to get the static method of the class */
2284 uname = utf_new_char((char *) name);
2285 udesc = utf_new_char((char *) sig);
2287 m = class_resolvemethod(c, uname, udesc);
2289 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2290 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2295 return (jmethodID) m;
2299 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2300 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2301 jmethodID methodID, ...) \
2307 m = (methodinfo *) methodID; \
2309 va_start(ap, methodID); \
2310 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2316 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2317 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2318 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2319 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2320 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2321 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2322 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2323 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2326 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2327 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2328 jmethodID methodID, va_list args) \
2333 m = (methodinfo *) methodID; \
2335 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2340 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2341 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2342 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2343 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2344 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2345 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2346 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2347 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2350 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2351 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2352 jmethodID methodID, const jvalue *args) \
2357 m = (methodinfo *) methodID; \
2359 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2364 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2365 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2366 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2367 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2368 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2369 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2370 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2371 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2374 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2375 jmethodID methodID, ...)
2381 m = (methodinfo *) methodID;
2383 va_start(ap, methodID);
2384 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2387 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2391 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2392 jmethodID methodID, va_list args)
2397 m = (methodinfo *) methodID;
2399 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2401 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2405 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2406 jmethodID methodID, const jvalue *args)
2411 m = (methodinfo *) methodID;
2413 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2415 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2419 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2420 jmethodID methodID, ...)
2425 m = (methodinfo *) methodID;
2427 va_start(ap, methodID);
2428 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2433 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2434 jmethodID methodID, va_list args)
2438 m = (methodinfo *) methodID;
2440 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2444 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2445 jmethodID methodID, const jvalue * args)
2449 m = (methodinfo *) methodID;
2451 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2455 /* Accessing Static Fields ****************************************************/
2457 /* GetStaticFieldID ************************************************************
2459 Returns the field ID for a static field of a class. The field is
2460 specified by its name and signature. The GetStatic<type>Field and
2461 SetStatic<type>Field families of accessor functions use field IDs
2462 to retrieve static fields.
2464 *******************************************************************************/
2466 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2474 STATISTICS(jniinvokation());
2476 c = LLNI_classinfo_unwrap(clazz);
2478 uname = utf_new_char((char *) name);
2479 usig = utf_new_char((char *) sig);
2481 f = class_findfield(c, uname, usig);
2484 exceptions_throw_nosuchfielderror(c, uname);
2486 return (jfieldID) f;
2490 /* GetStatic<type>Field ********************************************************
2492 This family of accessor routines returns the value of a static
2495 *******************************************************************************/
2497 #define JNI_GET_STATIC_FIELD(name, type, field) \
2498 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2504 STATISTICS(jniinvokation()); \
2506 c = LLNI_classinfo_unwrap(clazz); \
2507 f = (fieldinfo *) fieldID; \
2509 if (!(c->state & CLASS_INITIALIZED)) \
2510 if (!initialize_class(c)) \
2513 return f->value->field; \
2516 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2517 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2518 JNI_GET_STATIC_FIELD(Char, jchar, i)
2519 JNI_GET_STATIC_FIELD(Short, jshort, i)
2520 JNI_GET_STATIC_FIELD(Int, jint, i)
2521 JNI_GET_STATIC_FIELD(Long, jlong, l)
2522 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2523 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2526 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2532 STATISTICS(jniinvokation());
2534 c = LLNI_classinfo_unwrap(clazz);
2535 f = (fieldinfo *) fieldID;
2537 if (!(c->state & CLASS_INITIALIZED))
2538 if (!initialize_class(c))
2541 return _Jv_JNI_NewLocalRef(env, f->value->a);
2545 /* SetStatic<type>Field *******************************************************
2547 This family of accessor routines sets the value of a static field
2550 *******************************************************************************/
2552 #define JNI_SET_STATIC_FIELD(name, type, field) \
2553 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2560 STATISTICS(jniinvokation()); \
2562 c = LLNI_classinfo_unwrap(clazz); \
2563 f = (fieldinfo *) fieldID; \
2565 if (!(c->state & CLASS_INITIALIZED)) \
2566 if (!initialize_class(c)) \
2569 f->value->field = value; \
2572 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2573 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2574 JNI_SET_STATIC_FIELD(Char, jchar, i)
2575 JNI_SET_STATIC_FIELD(Short, jshort, i)
2576 JNI_SET_STATIC_FIELD(Int, jint, i)
2577 JNI_SET_STATIC_FIELD(Long, jlong, l)
2578 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2579 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2582 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2588 STATISTICS(jniinvokation());
2590 c = LLNI_classinfo_unwrap(clazz);
2591 f = (fieldinfo *) fieldID;
2593 if (!(c->state & CLASS_INITIALIZED))
2594 if (!initialize_class(c))
2597 f->value->a = value;
2601 /* String Operations **********************************************************/
2603 /* NewString *******************************************************************
2605 Create new java.lang.String object from an array of Unicode
2608 *******************************************************************************/
2610 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2612 java_lang_String *s;
2613 java_handle_chararray_t *a;
2616 STATISTICS(jniinvokation());
2618 s = (java_lang_String *) builtin_new(class_java_lang_String);
2619 a = builtin_newarray_char(len);
2621 /* javastring or characterarray could not be created */
2622 if ((a == NULL) || (s == NULL))
2626 for (i = 0; i < len; i++)
2627 LLNI_array_direct(a, i) = buf[i];
2629 LLNI_field_set_ref(s, value , a);
2630 LLNI_field_set_val(s, offset, 0);
2631 LLNI_field_set_val(s, count , len);
2633 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2637 static jchar emptyStringJ[]={0,0};
2639 /* GetStringLength *************************************************************
2641 Returns the length (the count of Unicode characters) of a Java
2644 *******************************************************************************/
2646 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2648 java_lang_String *s;
2651 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2653 s = (java_lang_String *) str;
2655 LLNI_field_get_val(s, count, len);
2661 /******************** convertes javastring to u2-array ****************************/
2663 u2 *javastring_tou2(jstring so)
2665 java_lang_String *s;
2666 java_handle_chararray_t *a;
2672 STATISTICS(jniinvokation());
2674 s = (java_lang_String *) so;
2679 LLNI_field_get_ref(s, value, a);
2684 LLNI_field_get_val(s, count, count);
2685 LLNI_field_get_val(s, offset, offset);
2687 /* allocate memory */
2689 stringbuffer = MNEW(u2, count + 1);
2693 for (i = 0; i < count; i++)
2694 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2696 /* terminate string */
2698 stringbuffer[i] = '\0';
2700 return stringbuffer;
2704 /* GetStringChars **************************************************************
2706 Returns a pointer to the array of Unicode characters of the
2707 string. This pointer is valid until ReleaseStringChars() is called.
2709 *******************************************************************************/
2711 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2715 STATISTICS(jniinvokation());
2717 jc = javastring_tou2(str);
2729 return emptyStringJ;
2733 /* ReleaseStringChars **********************************************************
2735 Informs the VM that the native code no longer needs access to
2736 chars. The chars argument is a pointer obtained from string using
2739 *******************************************************************************/
2741 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2743 java_lang_String *s;
2745 STATISTICS(jniinvokation());
2747 if (chars == emptyStringJ)
2750 s = (java_lang_String *) str;
2752 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2756 /* NewStringUTF ****************************************************************
2758 Constructs a new java.lang.String object from an array of UTF-8
2761 *******************************************************************************/
2763 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2765 java_lang_String *s;
2767 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2769 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2771 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2775 /****************** returns the utf8 length in bytes of a string *******************/
2777 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2779 java_lang_String *s;
2782 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2784 s = (java_lang_String *) string;
2786 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2792 /* GetStringUTFChars ***********************************************************
2794 Returns a pointer to an array of UTF-8 characters of the
2795 string. This array is valid until it is released by
2796 ReleaseStringUTFChars().
2798 *******************************************************************************/
2800 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2805 STATISTICS(jniinvokation());
2813 u = javastring_toutf((java_handle_t *) string, false);
2822 /* ReleaseStringUTFChars *******************************************************
2824 Informs the VM that the native code no longer needs access to
2825 utf. The utf argument is a pointer derived from string using
2826 GetStringUTFChars().
2828 *******************************************************************************/
2830 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2832 STATISTICS(jniinvokation());
2834 /* XXX we don't release utf chars right now, perhaps that should be done
2835 later. Since there is always one reference the garbage collector will
2840 /* Array Operations ***********************************************************/
2842 /* GetArrayLength **************************************************************
2844 Returns the number of elements in the array.
2846 *******************************************************************************/
2848 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2853 STATISTICS(jniinvokation());
2855 a = (java_handle_t *) array;
2857 size = LLNI_array_size(a);
2863 /* NewObjectArray **************************************************************
2865 Constructs a new array holding objects in class elementClass. All
2866 elements are initially set to initialElement.
2868 *******************************************************************************/
2870 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2871 jclass elementClass, jobject initialElement)
2875 java_handle_objectarray_t *oa;
2878 STATISTICS(jniinvokation());
2880 c = LLNI_classinfo_unwrap(elementClass);
2881 o = (java_handle_t *) initialElement;
2884 exceptions_throw_negativearraysizeexception();
2888 oa = builtin_anewarray(length, c);
2893 /* set all elements to initialElement */
2895 for (i = 0; i < length; i++)
2896 LLNI_objectarray_element_set(oa, i, o);
2898 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2902 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2905 java_handle_objectarray_t *oa;
2908 STATISTICS(jniinvokation());
2910 oa = (java_handle_objectarray_t *) array;
2912 if (index >= LLNI_array_size(oa)) {
2913 exceptions_throw_arrayindexoutofboundsexception();
2917 LLNI_objectarray_element_get(oa, index, o);
2919 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2923 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2924 jsize index, jobject val)
2926 java_handle_objectarray_t *oa;
2929 STATISTICS(jniinvokation());
2931 oa = (java_handle_objectarray_t *) array;
2932 o = (java_handle_t *) val;
2934 if (index >= LLNI_array_size(oa)) {
2935 exceptions_throw_arrayindexoutofboundsexception();
2939 /* check if the class of value is a subclass of the element class
2942 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2945 LLNI_objectarray_element_set(oa, index, o);
2949 #define JNI_NEW_ARRAY(name, type, intern) \
2950 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2952 java_handle_##intern##array_t *a; \
2954 STATISTICS(jniinvokation()); \
2957 exceptions_throw_negativearraysizeexception(); \
2961 a = builtin_newarray_##intern(len); \
2963 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2966 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2967 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2968 JNI_NEW_ARRAY(Char, jcharArray, char)
2969 JNI_NEW_ARRAY(Short, jshortArray, byte)
2970 JNI_NEW_ARRAY(Int, jintArray, int)
2971 JNI_NEW_ARRAY(Long, jlongArray, long)
2972 JNI_NEW_ARRAY(Float, jfloatArray, float)
2973 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2976 /* Get<PrimitiveType>ArrayElements *********************************************
2978 A family of functions that returns the body of the primitive array.
2980 *******************************************************************************/
2982 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2983 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2986 java_handle_##intern##array_t *a; \
2988 STATISTICS(jniinvokation()); \
2990 a = (java_handle_##intern##array_t *) array; \
2993 *isCopy = JNI_FALSE; \
2995 return LLNI_array_data(a); \
2998 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2999 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3000 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3001 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3002 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3003 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3004 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3005 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3008 /* Release<PrimitiveType>ArrayElements *****************************************
3010 A family of functions that informs the VM that the native code no
3011 longer needs access to elems. The elems argument is a pointer
3012 derived from array using the corresponding
3013 Get<PrimitiveType>ArrayElements() function. If necessary, this
3014 function copies back all changes made to elems to the original
3017 *******************************************************************************/
3019 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3020 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3021 type *elems, jint mode) \
3023 java_handle_##intern##array_t *a; \
3025 STATISTICS(jniinvokation()); \
3027 a = (java_handle_##intern##array_t *) array; \
3029 if (elems != LLNI_array_data(a)) { \
3032 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3035 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3036 /* XXX TWISTI how should it be freed? */ \
3039 /* XXX TWISTI how should it be freed? */ \
3045 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3046 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3047 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3048 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3049 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3050 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3051 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3052 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3055 /* Get<PrimitiveType>ArrayRegion **********************************************
3057 A family of functions that copies a region of a primitive array
3060 *******************************************************************************/
3062 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3063 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3064 jsize start, jsize len, type *buf) \
3066 java_handle_##intern##array_t *a; \
3068 STATISTICS(jniinvokation()); \
3070 a = (java_handle_##intern##array_t *) array; \
3072 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3073 exceptions_throw_arrayindexoutofboundsexception(); \
3075 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3078 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3079 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3080 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3081 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3082 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3083 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3084 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3085 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3088 /* Set<PrimitiveType>ArrayRegion **********************************************
3090 A family of functions that copies back a region of a primitive
3091 array from a buffer.
3093 *******************************************************************************/
3095 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3096 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3097 jsize start, jsize len, const type *buf) \
3099 java_handle_##intern##array_t *a; \
3101 STATISTICS(jniinvokation()); \
3103 a = (java_handle_##intern##array_t *) array; \
3105 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3106 exceptions_throw_arrayindexoutofboundsexception(); \
3108 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3111 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3112 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3113 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3114 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3115 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3116 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3117 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3118 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3121 /* Registering Native Methods *************************************************/
3123 /* RegisterNatives *************************************************************
3125 Registers native methods with the class specified by the clazz
3126 argument. The methods parameter specifies an array of
3127 JNINativeMethod structures that contain the names, signatures, and
3128 function pointers of the native methods. The nMethods parameter
3129 specifies the number of native methods in the array.
3131 *******************************************************************************/
3133 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3134 const JNINativeMethod *methods, jint nMethods)
3138 STATISTICS(jniinvokation());
3140 c = LLNI_classinfo_unwrap(clazz);
3142 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3143 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3146 native_method_register(c->name, methods, nMethods);
3152 /* UnregisterNatives ***********************************************************
3154 Unregisters native methods of a class. The class goes back to the
3155 state before it was linked or registered with its native method
3158 This function should not be used in normal native code. Instead, it
3159 provides special programs a way to reload and relink native
3162 *******************************************************************************/
3164 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3166 STATISTICS(jniinvokation());
3168 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3170 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3176 /* Monitor Operations *********************************************************/
3178 /* MonitorEnter ****************************************************************
3180 Enters the monitor associated with the underlying Java object
3183 *******************************************************************************/
3185 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3187 STATISTICS(jniinvokation());
3190 exceptions_throw_nullpointerexception();
3194 LOCK_MONITOR_ENTER(obj);
3200 /* MonitorExit *****************************************************************
3202 The current thread must be the owner of the monitor associated with
3203 the underlying Java object referred to by obj. The thread
3204 decrements the counter indicating the number of times it has
3205 entered this monitor. If the value of the counter becomes zero, the
3206 current thread releases the monitor.
3208 *******************************************************************************/
3210 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3212 STATISTICS(jniinvokation());
3215 exceptions_throw_nullpointerexception();
3219 LOCK_MONITOR_EXIT(obj);
3225 /* JavaVM Interface ***********************************************************/
3227 /* GetJavaVM *******************************************************************
3229 Returns the Java VM interface (used in the Invocation API)
3230 associated with the current thread. The result is placed at the
3231 location pointed to by the second argument, vm.
3233 *******************************************************************************/
3235 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3237 STATISTICS(jniinvokation());
3239 *vm = (JavaVM *) _Jv_jvm;
3245 /* GetStringRegion *************************************************************
3247 Copies len number of Unicode characters beginning at offset start
3248 to the given buffer buf.
3250 Throws StringIndexOutOfBoundsException on index overflow.
3252 *******************************************************************************/
3254 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3257 java_lang_String *s;
3258 java_handle_chararray_t *ca;
3260 STATISTICS(jniinvokation());
3262 s = (java_lang_String *) str;
3263 LLNI_field_get_ref(s, value, ca);
3265 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3266 (start + len > LLNI_field_direct(s, count))) {
3267 exceptions_throw_stringindexoutofboundsexception();
3271 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3275 /* GetStringUTFRegion **********************************************************
3277 Translates len number of Unicode characters beginning at offset
3278 start into UTF-8 format and place the result in the given buffer
3281 Throws StringIndexOutOfBoundsException on index overflow.
3283 *******************************************************************************/
3285 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3286 jsize len, char *buf)
3288 java_lang_String *s;
3289 java_handle_chararray_t *ca;
3294 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3296 s = (java_lang_String *) str;
3297 LLNI_field_get_ref(s, value, ca);
3298 LLNI_field_get_val(s, count, count);
3299 LLNI_field_get_val(s, offset, offset);
3301 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3302 exceptions_throw_stringindexoutofboundsexception();
3306 for (i = 0; i < len; i++)
3307 buf[i] = LLNI_array_direct(ca, offset + start + i);
3313 /* GetPrimitiveArrayCritical ***************************************************
3315 Obtain a direct pointer to array elements.
3317 *******************************************************************************/
3319 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3322 java_handle_bytearray_t *ba;
3325 ba = (java_handle_bytearray_t *) array;
3327 /* do the same as Kaffe does */
3329 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3335 /* ReleasePrimitiveArrayCritical ***********************************************
3337 No specific documentation.
3339 *******************************************************************************/
3341 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3342 void *carray, jint mode)
3344 STATISTICS(jniinvokation());
3346 /* do the same as Kaffe does */
3348 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3353 /* GetStringCritical ***********************************************************
3355 The semantics of these two functions are similar to the existing
3356 Get/ReleaseStringChars functions.
3358 *******************************************************************************/
3360 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3363 STATISTICS(jniinvokation());
3365 return _Jv_JNI_GetStringChars(env, string, isCopy);
3369 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3370 const jchar *cstring)
3372 STATISTICS(jniinvokation());
3374 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3378 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3380 STATISTICS(jniinvokation());
3382 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3388 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3390 STATISTICS(jniinvokation());
3392 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3396 /* NewGlobalRef ****************************************************************
3398 Creates a new global reference to the object referred to by the obj
3401 *******************************************************************************/
3403 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3405 hashtable_global_ref_entry *gre;
3406 u4 key; /* hashkey */
3407 u4 slot; /* slot in hashtable */
3410 STATISTICS(jniinvokation());
3412 o = (java_handle_t *) obj;
3414 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3416 LLNI_CRITICAL_START;
3418 /* normally addresses are aligned to 4, 8 or 16 bytes */
3420 #if defined(ENABLE_GC_CACAO)
3421 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3423 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3425 slot = key & (hashtable_global_ref->size - 1);
3426 gre = hashtable_global_ref->ptr[slot];
3428 /* search external hash chain for the entry */
3431 if (gre->o == LLNI_DIRECT(o)) {
3432 /* global object found, increment the reference */
3439 gre = gre->hashlink; /* next element in external chain */
3442 /* global ref not found, create a new one */
3445 gre = NEW(hashtable_global_ref_entry);
3447 #if defined(ENABLE_GC_CACAO)
3448 /* register global ref with the GC */
3450 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3453 gre->o = LLNI_DIRECT(o);
3456 /* insert entry into hashtable */
3458 gre->hashlink = hashtable_global_ref->ptr[slot];
3460 hashtable_global_ref->ptr[slot] = gre;
3462 /* update number of hashtable-entries */
3464 hashtable_global_ref->entries++;
3469 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3471 #if defined(ENABLE_HANDLES)
3479 /* DeleteGlobalRef *************************************************************
3481 Deletes the global reference pointed to by globalRef.
3483 *******************************************************************************/
3485 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3487 hashtable_global_ref_entry *gre;
3488 hashtable_global_ref_entry *prevgre;
3489 u4 key; /* hashkey */
3490 u4 slot; /* slot in hashtable */
3493 STATISTICS(jniinvokation());
3495 o = (java_handle_t *) globalRef;
3497 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3499 LLNI_CRITICAL_START;
3501 /* normally addresses are aligned to 4, 8 or 16 bytes */
3503 #if defined(ENABLE_GC_CACAO)
3504 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3506 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3508 slot = key & (hashtable_global_ref->size - 1);
3509 gre = hashtable_global_ref->ptr[slot];
3511 /* initialize prevgre */
3515 /* search external hash chain for the entry */
3518 if (gre->o == LLNI_DIRECT(o)) {
3519 /* global object found, decrement the reference count */
3523 /* if reference count is 0, remove the entry */
3525 if (gre->refs == 0) {
3526 /* special handling if it's the first in the chain */
3528 if (prevgre == NULL)
3529 hashtable_global_ref->ptr[slot] = gre->hashlink;
3531 prevgre->hashlink = gre->hashlink;
3533 #if defined(ENABLE_GC_CACAO)
3534 /* unregister global ref with the GC */
3536 gc_reference_unregister(&(gre->o));
3539 FREE(gre, hashtable_global_ref_entry);
3544 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3549 prevgre = gre; /* save current pointer for removal */
3550 gre = gre->hashlink; /* next element in external chain */
3553 log_println("JNI-DeleteGlobalRef: global reference not found");
3557 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3561 /* ExceptionCheck **************************************************************
3563 Returns JNI_TRUE when there is a pending exception; otherwise,
3566 *******************************************************************************/
3568 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3572 STATISTICS(jniinvokation());
3574 o = exceptions_get_exception();
3576 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3580 /* New JNI 1.4 functions ******************************************************/
3582 /* NewDirectByteBuffer *********************************************************
3584 Allocates and returns a direct java.nio.ByteBuffer referring to the
3585 block of memory starting at the memory address address and
3586 extending capacity bytes.
3588 *******************************************************************************/
3590 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3592 #if defined(ENABLE_JAVASE)
3593 # if defined(WITH_CLASSPATH_GNU)
3594 java_handle_t *nbuf;
3596 # if SIZEOF_VOID_P == 8
3597 gnu_classpath_Pointer64 *paddress;
3599 gnu_classpath_Pointer32 *paddress;
3602 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3604 /* alocate a gnu.classpath.Pointer{32,64} object */
3606 # if SIZEOF_VOID_P == 8
3607 if (!(paddress = (gnu_classpath_Pointer64 *)
3608 builtin_new(class_gnu_classpath_Pointer64)))
3610 if (!(paddress = (gnu_classpath_Pointer32 *)
3611 builtin_new(class_gnu_classpath_Pointer32)))
3615 /* fill gnu.classpath.Pointer{32,64} with address */
3617 LLNI_field_set_val(paddress, data, (ptrint) address);
3619 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3621 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3622 (jmethodID) dbbirw_init, NULL, paddress,
3623 (jint) capacity, (jint) capacity, (jint) 0);
3625 /* add local reference and return the value */
3627 return _Jv_JNI_NewLocalRef(env, nbuf);
3629 # elif defined(WITH_CLASSPATH_SUN)
3635 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3637 /* Be paranoid about address sign-extension. */
3639 addr = (int64_t) ((uintptr_t) address);
3640 cap = (int32_t) capacity;
3642 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3643 (jmethodID) dbb_init, addr, cap);
3645 /* Add local reference and return the value. */
3647 return _Jv_JNI_NewLocalRef(env, o);
3650 # error unknown classpath configuration
3654 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3656 /* keep compiler happy */
3663 /* GetDirectBufferAddress ******************************************************
3665 Fetches and returns the starting address of the memory region
3666 referenced by the given direct java.nio.Buffer.
3668 *******************************************************************************/
3670 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3672 #if defined(ENABLE_JAVASE)
3673 # if defined(WITH_CLASSPATH_GNU)
3675 java_nio_DirectByteBufferImpl *nbuf;
3676 # if SIZEOF_VOID_P == 8
3677 gnu_classpath_Pointer64 *paddress;
3679 gnu_classpath_Pointer32 *paddress;
3683 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3685 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3688 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3690 # if SIZEOF_VOID_P == 8
3691 LLNI_field_get_ref(nbuf, address, paddress);
3692 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3694 LLNI_field_get_ref(nbuf, address, paddress);
3695 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3698 if (paddress == NULL)
3701 LLNI_field_get_val(paddress, data, address);
3702 /* this was the cast to avaoid warning: (void *) paddress->data */
3706 # elif defined(WITH_CLASSPATH_SUN)
3712 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3714 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3717 o = (java_nio_Buffer *) buf;
3719 LLNI_field_get_val(o, address, address);
3721 p = (void *) (intptr_t) address;
3726 # error unknown classpath configuration
3731 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3733 /* keep compiler happy */
3741 /* GetDirectBufferCapacity *****************************************************
3743 Fetches and returns the capacity in bytes of the memory region
3744 referenced by the given direct java.nio.Buffer.
3746 *******************************************************************************/
3748 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3750 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3752 java_nio_Buffer *nbuf;
3755 STATISTICS(jniinvokation());
3757 o = (java_handle_t *) buf;
3759 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3762 nbuf = (java_nio_Buffer *) o;
3764 LLNI_field_get_val(nbuf, cap, capacity);
3768 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3770 /* keep compiler happy */
3777 /* GetObjectRefType ************************************************************
3779 Returns the type of the object referred to by the obj argument. The
3780 argument obj can either be a local, global or weak global
3783 *******************************************************************************/
3785 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3787 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3793 /* DestroyJavaVM ***************************************************************
3795 Unloads a Java VM and reclaims its resources. Only the main thread
3796 can unload the VM. The system waits until the main thread is only
3797 remaining user thread before it destroys the VM.
3799 *******************************************************************************/
3801 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3805 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3807 status = vm_destroy(vm);
3813 /* AttachCurrentThread *********************************************************
3815 Attaches the current thread to a Java VM. Returns a JNI interface
3816 pointer in the JNIEnv argument.
3818 Trying to attach a thread that is already attached is a no-op.
3820 A native thread cannot be attached simultaneously to two Java VMs.
3822 When a thread is attached to the VM, the context class loader is
3823 the bootstrap loader.
3825 *******************************************************************************/
3827 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3829 JavaVMAttachArgs *vm_aargs;
3831 #if defined(ENABLE_THREADS)
3832 if (threads_get_current_threadobject() == NULL) {
3833 vm_aargs = (JavaVMAttachArgs *) thr_args;
3835 if (vm_aargs != NULL) {
3836 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3837 (vm_aargs->version != JNI_VERSION_1_4))
3838 return JNI_EVERSION;
3841 if (!threads_attach_current_thread(vm_aargs, false))
3844 if (!localref_table_init())
3855 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3857 STATISTICS(jniinvokation());
3859 return jni_attach_current_thread(p_env, thr_args, false);
3863 /* DetachCurrentThread *********************************************************
3865 Detaches the current thread from a Java VM. All Java monitors held
3866 by this thread are released. All Java threads waiting for this
3867 thread to die are notified.
3869 In JDK 1.1, the main thread cannot be detached from the VM. It must
3870 call DestroyJavaVM to unload the entire VM.
3872 In the JDK, the main thread can be detached from the VM.
3874 The main thread, which is the thread that created the Java VM,
3875 cannot be detached from the VM. Instead, the main thread must call
3876 JNI_DestroyJavaVM() to unload the entire VM.
3878 *******************************************************************************/
3880 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3882 #if defined(ENABLE_THREADS)
3883 threadobject *thread;
3885 STATISTICS(jniinvokation());
3887 thread = threads_get_current_threadobject();
3892 if (!localref_table_destroy())
3895 if (!threads_detach_thread(thread))
3903 /* GetEnv **********************************************************************
3905 If the current thread is not attached to the VM, sets *env to NULL,
3906 and returns JNI_EDETACHED. If the specified version is not
3907 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3908 sets *env to the appropriate interface, and returns JNI_OK.
3910 *******************************************************************************/
3912 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3914 STATISTICS(jniinvokation());
3916 #if defined(ENABLE_THREADS)
3917 if (threads_get_current_threadobject() == NULL) {
3920 return JNI_EDETACHED;
3924 /* check the JNI version */
3927 case JNI_VERSION_1_1:
3928 case JNI_VERSION_1_2:
3929 case JNI_VERSION_1_4:
3937 #if defined(ENABLE_JVMTI)
3938 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3939 == JVMTI_VERSION_INTERFACE_JVMTI) {
3941 *env = (void *) jvmti_new_environment();
3950 return JNI_EVERSION;
3954 /* AttachCurrentThreadAsDaemon *************************************************
3956 Same semantics as AttachCurrentThread, but the newly-created
3957 java.lang.Thread instance is a daemon.
3959 If the thread has already been attached via either
3960 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3961 simply sets the value pointed to by penv to the JNIEnv of the
3962 current thread. In this case neither AttachCurrentThread nor this
3963 routine have any effect on the daemon status of the thread.
3965 *******************************************************************************/
3967 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3969 STATISTICS(jniinvokation());
3971 return jni_attach_current_thread(penv, args, true);
3975 /* JNI invocation table *******************************************************/
3977 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3982 _Jv_JNI_DestroyJavaVM,
3983 _Jv_JNI_AttachCurrentThread,
3984 _Jv_JNI_DetachCurrentThread,
3986 _Jv_JNI_AttachCurrentThreadAsDaemon
3990 /* JNI function table *********************************************************/
3992 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3999 _Jv_JNI_DefineClass,
4001 _Jv_JNI_FromReflectedMethod,
4002 _Jv_JNI_FromReflectedField,
4003 _Jv_JNI_ToReflectedMethod,
4004 _Jv_JNI_GetSuperclass,
4005 _Jv_JNI_IsAssignableFrom,
4006 _Jv_JNI_ToReflectedField,
4010 _Jv_JNI_ExceptionOccurred,
4011 _Jv_JNI_ExceptionDescribe,
4012 _Jv_JNI_ExceptionClear,
4014 _Jv_JNI_PushLocalFrame,
4015 _Jv_JNI_PopLocalFrame,
4017 _Jv_JNI_NewGlobalRef,
4018 _Jv_JNI_DeleteGlobalRef,
4019 _Jv_JNI_DeleteLocalRef,
4020 _Jv_JNI_IsSameObject,
4021 _Jv_JNI_NewLocalRef,
4022 _Jv_JNI_EnsureLocalCapacity,
4024 _Jv_JNI_AllocObject,
4029 _Jv_JNI_GetObjectClass,
4030 _Jv_JNI_IsInstanceOf,
4032 _Jv_JNI_GetMethodID,
4034 _Jv_JNI_CallObjectMethod,
4035 _Jv_JNI_CallObjectMethodV,
4036 _Jv_JNI_CallObjectMethodA,
4037 _Jv_JNI_CallBooleanMethod,
4038 _Jv_JNI_CallBooleanMethodV,
4039 _Jv_JNI_CallBooleanMethodA,
4040 _Jv_JNI_CallByteMethod,
4041 _Jv_JNI_CallByteMethodV,
4042 _Jv_JNI_CallByteMethodA,
4043 _Jv_JNI_CallCharMethod,
4044 _Jv_JNI_CallCharMethodV,
4045 _Jv_JNI_CallCharMethodA,
4046 _Jv_JNI_CallShortMethod,
4047 _Jv_JNI_CallShortMethodV,
4048 _Jv_JNI_CallShortMethodA,
4049 _Jv_JNI_CallIntMethod,
4050 _Jv_JNI_CallIntMethodV,
4051 _Jv_JNI_CallIntMethodA,
4052 _Jv_JNI_CallLongMethod,
4053 _Jv_JNI_CallLongMethodV,
4054 _Jv_JNI_CallLongMethodA,
4055 _Jv_JNI_CallFloatMethod,
4056 _Jv_JNI_CallFloatMethodV,
4057 _Jv_JNI_CallFloatMethodA,
4058 _Jv_JNI_CallDoubleMethod,
4059 _Jv_JNI_CallDoubleMethodV,
4060 _Jv_JNI_CallDoubleMethodA,
4061 _Jv_JNI_CallVoidMethod,
4062 _Jv_JNI_CallVoidMethodV,
4063 _Jv_JNI_CallVoidMethodA,
4065 _Jv_JNI_CallNonvirtualObjectMethod,
4066 _Jv_JNI_CallNonvirtualObjectMethodV,
4067 _Jv_JNI_CallNonvirtualObjectMethodA,
4068 _Jv_JNI_CallNonvirtualBooleanMethod,
4069 _Jv_JNI_CallNonvirtualBooleanMethodV,
4070 _Jv_JNI_CallNonvirtualBooleanMethodA,
4071 _Jv_JNI_CallNonvirtualByteMethod,
4072 _Jv_JNI_CallNonvirtualByteMethodV,
4073 _Jv_JNI_CallNonvirtualByteMethodA,
4074 _Jv_JNI_CallNonvirtualCharMethod,
4075 _Jv_JNI_CallNonvirtualCharMethodV,
4076 _Jv_JNI_CallNonvirtualCharMethodA,
4077 _Jv_JNI_CallNonvirtualShortMethod,
4078 _Jv_JNI_CallNonvirtualShortMethodV,
4079 _Jv_JNI_CallNonvirtualShortMethodA,
4080 _Jv_JNI_CallNonvirtualIntMethod,
4081 _Jv_JNI_CallNonvirtualIntMethodV,
4082 _Jv_JNI_CallNonvirtualIntMethodA,
4083 _Jv_JNI_CallNonvirtualLongMethod,
4084 _Jv_JNI_CallNonvirtualLongMethodV,
4085 _Jv_JNI_CallNonvirtualLongMethodA,
4086 _Jv_JNI_CallNonvirtualFloatMethod,
4087 _Jv_JNI_CallNonvirtualFloatMethodV,
4088 _Jv_JNI_CallNonvirtualFloatMethodA,
4089 _Jv_JNI_CallNonvirtualDoubleMethod,
4090 _Jv_JNI_CallNonvirtualDoubleMethodV,
4091 _Jv_JNI_CallNonvirtualDoubleMethodA,
4092 _Jv_JNI_CallNonvirtualVoidMethod,
4093 _Jv_JNI_CallNonvirtualVoidMethodV,
4094 _Jv_JNI_CallNonvirtualVoidMethodA,
4098 _Jv_JNI_GetObjectField,
4099 _Jv_JNI_GetBooleanField,
4100 _Jv_JNI_GetByteField,
4101 _Jv_JNI_GetCharField,
4102 _Jv_JNI_GetShortField,
4103 _Jv_JNI_GetIntField,
4104 _Jv_JNI_GetLongField,
4105 _Jv_JNI_GetFloatField,
4106 _Jv_JNI_GetDoubleField,
4107 _Jv_JNI_SetObjectField,
4108 _Jv_JNI_SetBooleanField,
4109 _Jv_JNI_SetByteField,
4110 _Jv_JNI_SetCharField,
4111 _Jv_JNI_SetShortField,
4112 _Jv_JNI_SetIntField,
4113 _Jv_JNI_SetLongField,
4114 _Jv_JNI_SetFloatField,
4115 _Jv_JNI_SetDoubleField,
4117 _Jv_JNI_GetStaticMethodID,
4119 _Jv_JNI_CallStaticObjectMethod,
4120 _Jv_JNI_CallStaticObjectMethodV,
4121 _Jv_JNI_CallStaticObjectMethodA,
4122 _Jv_JNI_CallStaticBooleanMethod,
4123 _Jv_JNI_CallStaticBooleanMethodV,
4124 _Jv_JNI_CallStaticBooleanMethodA,
4125 _Jv_JNI_CallStaticByteMethod,
4126 _Jv_JNI_CallStaticByteMethodV,
4127 _Jv_JNI_CallStaticByteMethodA,
4128 _Jv_JNI_CallStaticCharMethod,
4129 _Jv_JNI_CallStaticCharMethodV,
4130 _Jv_JNI_CallStaticCharMethodA,
4131 _Jv_JNI_CallStaticShortMethod,
4132 _Jv_JNI_CallStaticShortMethodV,
4133 _Jv_JNI_CallStaticShortMethodA,
4134 _Jv_JNI_CallStaticIntMethod,
4135 _Jv_JNI_CallStaticIntMethodV,
4136 _Jv_JNI_CallStaticIntMethodA,
4137 _Jv_JNI_CallStaticLongMethod,
4138 _Jv_JNI_CallStaticLongMethodV,
4139 _Jv_JNI_CallStaticLongMethodA,
4140 _Jv_JNI_CallStaticFloatMethod,
4141 _Jv_JNI_CallStaticFloatMethodV,
4142 _Jv_JNI_CallStaticFloatMethodA,
4143 _Jv_JNI_CallStaticDoubleMethod,
4144 _Jv_JNI_CallStaticDoubleMethodV,
4145 _Jv_JNI_CallStaticDoubleMethodA,
4146 _Jv_JNI_CallStaticVoidMethod,
4147 _Jv_JNI_CallStaticVoidMethodV,
4148 _Jv_JNI_CallStaticVoidMethodA,
4150 _Jv_JNI_GetStaticFieldID,
4152 _Jv_JNI_GetStaticObjectField,
4153 _Jv_JNI_GetStaticBooleanField,
4154 _Jv_JNI_GetStaticByteField,
4155 _Jv_JNI_GetStaticCharField,
4156 _Jv_JNI_GetStaticShortField,
4157 _Jv_JNI_GetStaticIntField,
4158 _Jv_JNI_GetStaticLongField,
4159 _Jv_JNI_GetStaticFloatField,
4160 _Jv_JNI_GetStaticDoubleField,
4161 _Jv_JNI_SetStaticObjectField,
4162 _Jv_JNI_SetStaticBooleanField,
4163 _Jv_JNI_SetStaticByteField,
4164 _Jv_JNI_SetStaticCharField,
4165 _Jv_JNI_SetStaticShortField,
4166 _Jv_JNI_SetStaticIntField,
4167 _Jv_JNI_SetStaticLongField,
4168 _Jv_JNI_SetStaticFloatField,
4169 _Jv_JNI_SetStaticDoubleField,
4172 _Jv_JNI_GetStringLength,
4173 _Jv_JNI_GetStringChars,
4174 _Jv_JNI_ReleaseStringChars,
4176 _Jv_JNI_NewStringUTF,
4177 _Jv_JNI_GetStringUTFLength,
4178 _Jv_JNI_GetStringUTFChars,
4179 _Jv_JNI_ReleaseStringUTFChars,
4181 _Jv_JNI_GetArrayLength,
4183 _Jv_JNI_NewObjectArray,
4184 _Jv_JNI_GetObjectArrayElement,
4185 _Jv_JNI_SetObjectArrayElement,
4187 _Jv_JNI_NewBooleanArray,
4188 _Jv_JNI_NewByteArray,
4189 _Jv_JNI_NewCharArray,
4190 _Jv_JNI_NewShortArray,
4191 _Jv_JNI_NewIntArray,
4192 _Jv_JNI_NewLongArray,
4193 _Jv_JNI_NewFloatArray,
4194 _Jv_JNI_NewDoubleArray,
4196 _Jv_JNI_GetBooleanArrayElements,
4197 _Jv_JNI_GetByteArrayElements,
4198 _Jv_JNI_GetCharArrayElements,
4199 _Jv_JNI_GetShortArrayElements,
4200 _Jv_JNI_GetIntArrayElements,
4201 _Jv_JNI_GetLongArrayElements,
4202 _Jv_JNI_GetFloatArrayElements,
4203 _Jv_JNI_GetDoubleArrayElements,
4205 _Jv_JNI_ReleaseBooleanArrayElements,
4206 _Jv_JNI_ReleaseByteArrayElements,
4207 _Jv_JNI_ReleaseCharArrayElements,
4208 _Jv_JNI_ReleaseShortArrayElements,
4209 _Jv_JNI_ReleaseIntArrayElements,
4210 _Jv_JNI_ReleaseLongArrayElements,
4211 _Jv_JNI_ReleaseFloatArrayElements,
4212 _Jv_JNI_ReleaseDoubleArrayElements,
4214 _Jv_JNI_GetBooleanArrayRegion,
4215 _Jv_JNI_GetByteArrayRegion,
4216 _Jv_JNI_GetCharArrayRegion,
4217 _Jv_JNI_GetShortArrayRegion,
4218 _Jv_JNI_GetIntArrayRegion,
4219 _Jv_JNI_GetLongArrayRegion,
4220 _Jv_JNI_GetFloatArrayRegion,
4221 _Jv_JNI_GetDoubleArrayRegion,
4222 _Jv_JNI_SetBooleanArrayRegion,
4223 _Jv_JNI_SetByteArrayRegion,
4224 _Jv_JNI_SetCharArrayRegion,
4225 _Jv_JNI_SetShortArrayRegion,
4226 _Jv_JNI_SetIntArrayRegion,
4227 _Jv_JNI_SetLongArrayRegion,
4228 _Jv_JNI_SetFloatArrayRegion,
4229 _Jv_JNI_SetDoubleArrayRegion,
4231 _Jv_JNI_RegisterNatives,
4232 _Jv_JNI_UnregisterNatives,
4234 _Jv_JNI_MonitorEnter,
4235 _Jv_JNI_MonitorExit,
4239 /* New JNI 1.2 functions. */
4241 _Jv_JNI_GetStringRegion,
4242 _Jv_JNI_GetStringUTFRegion,
4244 _Jv_JNI_GetPrimitiveArrayCritical,
4245 _Jv_JNI_ReleasePrimitiveArrayCritical,
4247 _Jv_JNI_GetStringCritical,
4248 _Jv_JNI_ReleaseStringCritical,
4250 _Jv_JNI_NewWeakGlobalRef,
4251 _Jv_JNI_DeleteWeakGlobalRef,
4253 _Jv_JNI_ExceptionCheck,
4255 /* New JNI 1.4 functions. */
4257 _Jv_JNI_NewDirectByteBuffer,
4258 _Jv_JNI_GetDirectBufferAddress,
4259 _Jv_JNI_GetDirectBufferCapacity,
4261 /* New JNI 1.6 functions. */
4263 jni_GetObjectRefType
4267 /* Invocation API Functions ***************************************************/
4269 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4271 Returns a default configuration for the Java VM.
4273 *******************************************************************************/
4275 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4277 JavaVMInitArgs *_vm_args;
4279 _vm_args = (JavaVMInitArgs *) vm_args;
4281 /* GNU classpath currently supports JNI 1.2 */
4283 switch (_vm_args->version) {
4284 case JNI_VERSION_1_1:
4285 _vm_args->version = JNI_VERSION_1_1;
4288 case JNI_VERSION_1_2:
4289 case JNI_VERSION_1_4:
4290 _vm_args->ignoreUnrecognized = JNI_FALSE;
4291 _vm_args->options = NULL;
4292 _vm_args->nOptions = 0;
4303 /* JNI_GetCreatedJavaVMs *******************************************************
4305 Returns all Java VMs that have been created. Pointers to VMs are written in
4306 the buffer vmBuf in the order they are created. At most bufLen number of
4307 entries will be written. The total number of created VMs is returned in
4310 *******************************************************************************/
4312 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4314 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4319 /* We currently only support 1 VM running. */
4321 vmBuf[0] = (JavaVM *) _Jv_jvm;
4328 /* JNI_CreateJavaVM ************************************************************
4330 Loads and initializes a Java VM. The current thread becomes the main thread.
4331 Sets the env argument to the JNI interface pointer of the main thread.
4333 *******************************************************************************/
4335 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4337 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4339 /* actually create the JVM */
4341 if (!vm_createjvm(p_vm, p_env, vm_args))
4349 * These are local overrides for various environment variables in Emacs.
4350 * Please do not remove this and leave it at the end of the file, where
4351 * Emacs will automagically detect them.
4352 * ---------------------------------------------------------------------
4355 * indent-tabs-mode: t
4359 * vim:noexpandtab:sw=4:ts=4: