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)
1001 java_lang_Class *co;
1003 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
1005 u = utf_new_char_classname((char *) name);
1007 /* Check stacktrace for classloader, if one found use it,
1008 otherwise use the system classloader. */
1010 /* Quote from the JNI documentation:
1012 In the Java 2 Platform, FindClass locates the class loader
1013 associated with the current native method. If the native code
1014 belongs to a system class, no class loader will be
1015 involved. Otherwise, the proper class loader will be invoked to
1016 load and link the named class. When FindClass is called through
1017 the Invocation Interface, there is no current native method or
1018 its associated class loader. In that case, the result of
1019 ClassLoader.getBaseClassLoader is used." */
1021 cc = stacktrace_getCurrentClass();
1024 c = load_class_from_sysloader(u);
1026 c = load_class_from_classloader(u, cc->classloader);
1034 co = LLNI_classinfo_wrap(c);
1036 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1038 #elif defined(ENABLE_JAVAME_CLDC1_1)
1043 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
1045 u = utf_new_char_classname((char *) name);
1046 c = load_class_bootstrap(u);
1054 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1057 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1059 /* keep compiler happy */
1066 /* GetSuperclass ***************************************************************
1068 If clazz represents any class other than the class Object, then
1069 this function returns the object that represents the superclass of
1070 the class specified by clazz.
1072 *******************************************************************************/
1074 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1078 java_lang_Class *co;
1080 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1082 c = LLNI_classinfo_unwrap(sub);
1087 super = class_get_superclass(c);
1089 co = LLNI_classinfo_wrap(super);
1091 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1095 /* IsAssignableFrom ************************************************************
1097 Determines whether an object of sub can be safely cast to sup.
1099 *******************************************************************************/
1101 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1103 java_lang_Class *csup;
1104 java_lang_Class *csub;
1106 csup = (java_lang_Class *) sup;
1107 csub = (java_lang_Class *) sub;
1109 STATISTICS(jniinvokation());
1111 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1115 /* Throw ***********************************************************************
1117 Causes a java.lang.Throwable object to be thrown.
1119 *******************************************************************************/
1121 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1125 STATISTICS(jniinvokation());
1127 o = (java_handle_t *) obj;
1129 exceptions_set_exception(o);
1135 /* ThrowNew ********************************************************************
1137 Constructs an exception object from the specified class with the
1138 message specified by message and causes that exception to be
1141 *******************************************************************************/
1143 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1149 STATISTICS(jniinvokation());
1151 c = LLNI_classinfo_unwrap(clazz);
1154 s = javastring_new_from_utf_string(msg);
1156 /* instantiate exception object */
1158 o = native_new_and_init_string(c, s);
1163 exceptions_set_exception(o);
1169 /* ExceptionOccurred ***********************************************************
1171 Determines if an exception is being thrown. The exception stays
1172 being thrown until either the native code calls ExceptionClear(),
1173 or the Java code handles the exception.
1175 *******************************************************************************/
1177 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1181 TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1183 o = exceptions_get_exception();
1185 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1189 /* ExceptionDescribe ***********************************************************
1191 Prints an exception and a backtrace of the stack to a system
1192 error-reporting channel, such as stderr. This is a convenience
1193 routine provided for debugging.
1195 *******************************************************************************/
1197 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1203 TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1205 /* Clear exception, because we are probably calling Java code
1208 o = exceptions_get_and_clear_exception();
1211 /* get printStackTrace method from exception class */
1213 LLNI_class_get(o, c);
1215 m = class_resolveclassmethod(c,
1216 utf_printStackTrace,
1222 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1224 /* Print the stacktrace. */
1226 (void) vm_call_method(m, o);
1231 /* ExceptionClear **************************************************************
1233 Clears any exception that is currently being thrown. If no
1234 exception is currently being thrown, this routine has no effect.
1236 *******************************************************************************/
1238 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1240 STATISTICS(jniinvokation());
1242 exceptions_clear_exception();
1246 /* FatalError ******************************************************************
1248 Raises a fatal error and does not expect the VM to recover. This
1249 function does not return.
1251 *******************************************************************************/
1253 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1255 STATISTICS(jniinvokation());
1257 /* this seems to be the best way */
1259 vm_abort("JNI Fatal error: %s", msg);
1263 /* PushLocalFrame **************************************************************
1265 Creates a new local reference frame, in which at least a given
1266 number of local references can be created.
1268 *******************************************************************************/
1270 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1272 STATISTICS(jniinvokation());
1277 /* add new local reference frame to current table */
1279 if (!localref_frame_push(capacity))
1286 /* PopLocalFrame ***************************************************************
1288 Pops off the current local reference frame, frees all the local
1289 references, and returns a local reference in the previous local
1290 reference frame for the given result object.
1292 *******************************************************************************/
1294 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1296 STATISTICS(jniinvokation());
1298 /* release all current local frames */
1300 localref_frame_pop_all();
1302 /* add local reference and return the value */
1304 return _Jv_JNI_NewLocalRef(env, result);
1308 /* DeleteLocalRef **************************************************************
1310 Deletes the local reference pointed to by localRef.
1312 *******************************************************************************/
1314 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1318 STATISTICS(jniinvokation());
1320 o = (java_handle_t *) localRef;
1322 /* delete the reference */
1328 /* IsSameObject ****************************************************************
1330 Tests whether two references refer to the same Java object.
1332 *******************************************************************************/
1334 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1340 STATISTICS(jniinvokation());
1342 o1 = (java_handle_t *) ref1;
1343 o2 = (java_handle_t *) ref2;
1345 LLNI_CRITICAL_START;
1347 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1358 /* NewLocalRef *****************************************************************
1360 Creates a new local reference that refers to the same object as ref.
1362 *******************************************************************************/
1364 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1367 java_handle_t *localref;
1369 STATISTICS(jniinvokation());
1374 o = (java_handle_t *) ref;
1376 /* insert the reference */
1378 localref = localref_add(LLNI_DIRECT(o));
1384 /* EnsureLocalCapacity *********************************************************
1386 Ensures that at least a given number of local references can be
1387 created in the current thread
1389 *******************************************************************************/
1391 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1393 localref_table *lrt;
1395 STATISTICS(jniinvokation());
1397 /* get local reference table (thread specific) */
1399 lrt = LOCALREFTABLE;
1401 /* check if capacity elements are available in the local references table */
1403 if ((lrt->used + capacity) > lrt->capacity)
1404 return _Jv_JNI_PushLocalFrame(env, capacity);
1410 /* AllocObject *****************************************************************
1412 Allocates a new Java object without invoking any of the
1413 constructors for the object. Returns a reference to the object.
1415 *******************************************************************************/
1417 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1422 STATISTICS(jniinvokation());
1424 c = LLNI_classinfo_unwrap(clazz);
1426 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1427 exceptions_throw_instantiationexception(c);
1433 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1437 /* NewObject *******************************************************************
1439 Programmers place all arguments that are to be passed to the
1440 constructor immediately following the methodID
1441 argument. NewObject() accepts these arguments and passes them to
1442 the Java method that the programmer wishes to invoke.
1444 *******************************************************************************/
1446 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1453 STATISTICS(jniinvokation());
1455 c = LLNI_classinfo_unwrap(clazz);
1456 m = (methodinfo *) methodID;
1465 /* call constructor */
1467 va_start(ap, methodID);
1468 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1471 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1475 /* NewObjectV ******************************************************************
1477 Programmers place all arguments that are to be passed to the
1478 constructor in an args argument of type va_list that immediately
1479 follows the methodID argument. NewObjectV() accepts these
1480 arguments, and, in turn, passes them to the Java method that the
1481 programmer wishes to invoke.
1483 *******************************************************************************/
1485 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1492 STATISTICS(jniinvokation());
1494 c = LLNI_classinfo_unwrap(clazz);
1495 m = (methodinfo *) methodID;
1504 /* call constructor */
1506 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1508 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1512 /* NewObjectA *****************************************************************
1514 Programmers place all arguments that are to be passed to the
1515 constructor in an args array of jvalues that immediately follows
1516 the methodID argument. NewObjectA() accepts the arguments in this
1517 array, and, in turn, passes them to the Java method that the
1518 programmer wishes to invoke.
1520 *******************************************************************************/
1522 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1529 STATISTICS(jniinvokation());
1531 c = LLNI_classinfo_unwrap(clazz);
1532 m = (methodinfo *) methodID;
1541 /* call constructor */
1543 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1545 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1549 /* GetObjectClass **************************************************************
1551 Returns the class of an object.
1553 *******************************************************************************/
1555 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1559 java_lang_Class *co;
1561 STATISTICS(jniinvokation());
1563 o = (java_handle_t *) obj;
1565 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1568 LLNI_class_get(o, c);
1570 co = LLNI_classinfo_wrap(c);
1572 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1576 /* IsInstanceOf ****************************************************************
1578 Tests whether an object is an instance of a class.
1580 *******************************************************************************/
1582 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1585 java_lang_Object *o;
1587 STATISTICS(jniinvokation());
1589 c = (java_lang_Class *) clazz;
1590 o = (java_lang_Object *) obj;
1592 return _Jv_java_lang_Class_isInstance(c, o);
1596 /* Reflection Support *********************************************************/
1598 /* FromReflectedMethod *********************************************************
1600 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1601 object to a method ID.
1603 *******************************************************************************/
1605 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1607 #if defined(ENABLE_JAVASE)
1613 STATISTICS(jniinvokation());
1615 o = (java_handle_t *) method;
1620 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1621 java_lang_reflect_Method *rm;
1623 rm = (java_lang_reflect_Method *) method;
1624 LLNI_field_get_cls(rm, clazz, c);
1625 LLNI_field_get_val(rm, slot , slot);
1627 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1628 java_lang_reflect_Constructor *rc;
1630 rc = (java_lang_reflect_Constructor *) method;
1631 LLNI_field_get_cls(rc, clazz, c);
1632 LLNI_field_get_val(rc, slot , slot);
1637 m = &(c->methods[slot]);
1639 return (jmethodID) m;
1641 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1643 /* keep compiler happy */
1650 /* FromReflectedField **********************************************************
1652 Converts a java.lang.reflect.Field to a field ID.
1654 *******************************************************************************/
1656 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1658 #if defined(ENABLE_JAVASE)
1659 java_lang_reflect_Field *rf;
1664 STATISTICS(jniinvokation());
1666 rf = (java_lang_reflect_Field *) field;
1671 LLNI_field_get_cls(rf, clazz, c);
1672 LLNI_field_get_val(rf, slot , slot);
1673 f = &(c->fields[slot]);
1675 return (jfieldID) f;
1677 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1679 /* keep compiler happy */
1686 /* ToReflectedMethod ***********************************************************
1688 Converts a method ID derived from cls to an instance of the
1689 java.lang.reflect.Method class or to an instance of the
1690 java.lang.reflect.Constructor class.
1692 *******************************************************************************/
1694 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1697 #if defined(ENABLE_JAVASE)
1699 java_lang_reflect_Constructor *rc;
1700 java_lang_reflect_Method *rm;
1702 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1704 m = (methodinfo *) methodID;
1706 /* HotSpot does the same assert. */
1708 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1710 if (m->name == utf_init) {
1711 rc = reflect_constructor_new(m);
1713 return (jobject) rc;
1716 rm = reflect_method_new(m);
1718 return (jobject) rm;
1721 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1723 /* keep compiler happy */
1730 /* ToReflectedField ************************************************************
1732 Converts a field ID derived from cls to an instance of the
1733 java.lang.reflect.Field class.
1735 *******************************************************************************/
1737 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1740 STATISTICS(jniinvokation());
1742 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1748 /* Calling Instance Methods ***************************************************/
1750 /* GetMethodID *****************************************************************
1752 Returns the method ID for an instance (nonstatic) method of a class
1753 or interface. The method may be defined in one of the clazz's
1754 superclasses and inherited by clazz. The method is determined by
1755 its name and signature.
1757 GetMethodID() causes an uninitialized class to be initialized.
1759 *******************************************************************************/
1761 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1769 STATISTICS(jniinvokation());
1771 c = LLNI_classinfo_unwrap(clazz);
1776 if (!(c->state & CLASS_INITIALIZED))
1777 if (!initialize_class(c))
1780 /* try to get the method of the class or one of it's superclasses */
1782 uname = utf_new_char((char *) name);
1783 udesc = utf_new_char((char *) sig);
1785 m = class_resolvemethod(c, uname, udesc);
1787 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1788 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1793 return (jmethodID) m;
1797 /* JNI-functions for calling instance methods *********************************/
1799 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1800 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1801 jmethodID methodID, ...) \
1808 o = (java_handle_t *) obj; \
1809 m = (methodinfo *) methodID; \
1811 va_start(ap, methodID); \
1812 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1818 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1819 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1820 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1821 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1822 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1823 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1824 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1825 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1828 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1829 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1830 jmethodID methodID, va_list args) \
1836 o = (java_handle_t *) obj; \
1837 m = (methodinfo *) methodID; \
1839 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1844 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1845 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1846 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1847 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1848 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1849 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1850 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1851 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1854 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1855 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1856 jmethodID methodID, \
1857 const jvalue *args) \
1863 o = (java_handle_t *) obj; \
1864 m = (methodinfo *) methodID; \
1866 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1871 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1872 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1873 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1874 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1875 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1876 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1877 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1878 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1881 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1889 o = (java_handle_t *) obj;
1890 m = (methodinfo *) methodID;
1892 va_start(ap, methodID);
1893 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1896 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1900 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1907 o = (java_handle_t *) obj;
1908 m = (methodinfo *) methodID;
1910 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1912 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1916 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1923 o = (java_handle_t *) obj;
1924 m = (methodinfo *) methodID;
1926 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1928 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1933 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1939 o = (java_handle_t *) obj;
1940 m = (methodinfo *) methodID;
1942 va_start(ap, methodID);
1943 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1948 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1954 o = (java_handle_t *) obj;
1955 m = (methodinfo *) methodID;
1957 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1961 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1967 o = (java_handle_t *) obj;
1968 m = (methodinfo *) methodID;
1970 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1975 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1976 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1977 jclass clazz, jmethodID methodID, \
1986 o = (java_handle_t *) obj; \
1987 c = LLNI_classinfo_unwrap(clazz); \
1988 m = (methodinfo *) methodID; \
1990 va_start(ap, methodID); \
1991 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1997 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1998 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1999 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
2000 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
2001 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
2002 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
2003 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
2004 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
2007 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
2008 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
2009 jclass clazz, jmethodID methodID, \
2017 o = (java_handle_t *) obj; \
2018 c = LLNI_classinfo_unwrap(clazz); \
2019 m = (methodinfo *) methodID; \
2021 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2026 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2027 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2028 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2032 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2033 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2036 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2037 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2038 jclass clazz, jmethodID methodID, \
2039 const jvalue *args) \
2041 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2046 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2047 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2048 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2049 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2050 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2051 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2052 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2053 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2055 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2056 jclass clazz, jmethodID methodID,
2065 o = (java_handle_t *) obj;
2066 c = LLNI_classinfo_unwrap(clazz);
2067 m = (methodinfo *) methodID;
2069 va_start(ap, methodID);
2070 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2073 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2077 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2078 jclass clazz, jmethodID methodID,
2086 o = (java_handle_t *) obj;
2087 c = LLNI_classinfo_unwrap(clazz);
2088 m = (methodinfo *) methodID;
2090 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2092 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2096 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2097 jclass clazz, jmethodID methodID,
2100 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2102 return _Jv_JNI_NewLocalRef(env, NULL);
2106 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2107 jmethodID methodID, ...)
2114 o = (java_handle_t *) obj;
2115 c = LLNI_classinfo_unwrap(clazz);
2116 m = (methodinfo *) methodID;
2118 va_start(ap, methodID);
2119 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2124 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2125 jmethodID methodID, va_list args)
2131 o = (java_handle_t *) obj;
2132 c = LLNI_classinfo_unwrap(clazz);
2133 m = (methodinfo *) methodID;
2135 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2139 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2140 jmethodID methodID, const jvalue * args)
2146 o = (java_handle_t *) obj;
2147 c = LLNI_classinfo_unwrap(clazz);
2148 m = (methodinfo *) methodID;
2150 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2154 /* Accessing Fields of Objects ************************************************/
2156 /* GetFieldID ******************************************************************
2158 Returns the field ID for an instance (nonstatic) field of a
2159 class. The field is specified by its name and signature. The
2160 Get<type>Field and Set<type>Field families of accessor functions
2161 use field IDs to retrieve object fields.
2163 *******************************************************************************/
2165 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2173 STATISTICS(jniinvokation());
2175 c = LLNI_classinfo_unwrap(clazz);
2177 /* XXX NPE check? */
2179 uname = utf_new_char((char *) name);
2180 udesc = utf_new_char((char *) sig);
2182 f = class_findfield(c, uname, udesc);
2185 exceptions_throw_nosuchfielderror(c, uname);
2187 return (jfieldID) f;
2191 /* Get<type>Field Routines *****************************************************
2193 This family of accessor routines returns the value of an instance
2194 (nonstatic) field of an object. The field to access is specified by
2195 a field ID obtained by calling GetFieldID().
2197 *******************************************************************************/
2199 #define JNI_GET_FIELD(name, type, intern) \
2200 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2204 STATISTICS(jniinvokation()); \
2206 ret = GET_FIELD(obj, intern, fieldID); \
2208 return (type) ret; \
2211 JNI_GET_FIELD(Boolean, jboolean, s4)
2212 JNI_GET_FIELD(Byte, jbyte, s4)
2213 JNI_GET_FIELD(Char, jchar, s4)
2214 JNI_GET_FIELD(Short, jshort, s4)
2215 JNI_GET_FIELD(Int, jint, s4)
2216 JNI_GET_FIELD(Long, jlong, s8)
2217 JNI_GET_FIELD(Float, jfloat, float)
2218 JNI_GET_FIELD(Double, jdouble, double)
2221 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2225 TRACEJNICALLS("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID);
2227 LLNI_CRITICAL_START;
2229 o = LLNI_WRAP(GET_FIELD(obj, java_handle_t*, fieldID));
2233 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2237 /* Set<type>Field Routines *****************************************************
2239 This family of accessor routines sets the value of an instance
2240 (nonstatic) field of an object. The field to access is specified by
2241 a field ID obtained by calling GetFieldID().
2243 *******************************************************************************/
2245 #define JNI_SET_FIELD(name, type, intern) \
2246 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2249 STATISTICS(jniinvokation()); \
2251 SET_FIELD(obj, intern, fieldID, value); \
2254 JNI_SET_FIELD(Boolean, jboolean, s4)
2255 JNI_SET_FIELD(Byte, jbyte, s4)
2256 JNI_SET_FIELD(Char, jchar, s4)
2257 JNI_SET_FIELD(Short, jshort, s4)
2258 JNI_SET_FIELD(Int, jint, s4)
2259 JNI_SET_FIELD(Long, jlong, s8)
2260 JNI_SET_FIELD(Float, jfloat, float)
2261 JNI_SET_FIELD(Double, jdouble, double)
2264 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2267 TRACEJNICALLS("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value);
2269 LLNI_CRITICAL_START;
2271 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP(value));
2277 /* Calling Static Methods *****************************************************/
2279 /* GetStaticMethodID ***********************************************************
2281 Returns the method ID for a static method of a class. The method is
2282 specified by its name and signature.
2284 GetStaticMethodID() causes an uninitialized class to be
2287 *******************************************************************************/
2289 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2297 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2299 c = LLNI_classinfo_unwrap(clazz);
2304 if (!(c->state & CLASS_INITIALIZED))
2305 if (!initialize_class(c))
2308 /* try to get the static method of the class */
2310 uname = utf_new_char((char *) name);
2311 udesc = utf_new_char((char *) sig);
2313 m = class_resolvemethod(c, uname, udesc);
2315 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2316 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2321 return (jmethodID) m;
2325 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2326 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2327 jmethodID methodID, ...) \
2333 m = (methodinfo *) methodID; \
2335 va_start(ap, methodID); \
2336 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2342 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2343 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2344 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2345 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2346 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2347 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2348 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2349 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2352 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2353 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2354 jmethodID methodID, va_list args) \
2359 m = (methodinfo *) methodID; \
2361 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2366 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2367 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2368 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2369 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2370 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2371 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2372 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2373 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2376 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2377 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2378 jmethodID methodID, const jvalue *args) \
2383 m = (methodinfo *) methodID; \
2385 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2390 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2391 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2392 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2393 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2394 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2395 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2396 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2397 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2400 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2401 jmethodID methodID, ...)
2407 m = (methodinfo *) methodID;
2409 va_start(ap, methodID);
2410 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2413 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2417 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2418 jmethodID methodID, va_list args)
2423 m = (methodinfo *) methodID;
2425 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2427 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2431 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2432 jmethodID methodID, const jvalue *args)
2437 m = (methodinfo *) methodID;
2439 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2441 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2445 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2446 jmethodID methodID, ...)
2451 m = (methodinfo *) methodID;
2453 va_start(ap, methodID);
2454 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2459 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2460 jmethodID methodID, va_list args)
2464 m = (methodinfo *) methodID;
2466 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2470 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2471 jmethodID methodID, const jvalue * args)
2475 m = (methodinfo *) methodID;
2477 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2481 /* Accessing Static Fields ****************************************************/
2483 /* GetStaticFieldID ************************************************************
2485 Returns the field ID for a static field of a class. The field is
2486 specified by its name and signature. The GetStatic<type>Field and
2487 SetStatic<type>Field families of accessor functions use field IDs
2488 to retrieve static fields.
2490 *******************************************************************************/
2492 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2500 STATISTICS(jniinvokation());
2502 c = LLNI_classinfo_unwrap(clazz);
2504 uname = utf_new_char((char *) name);
2505 usig = utf_new_char((char *) sig);
2507 f = class_findfield(c, uname, usig);
2510 exceptions_throw_nosuchfielderror(c, uname);
2512 return (jfieldID) f;
2516 /* GetStatic<type>Field ********************************************************
2518 This family of accessor routines returns the value of a static
2521 *******************************************************************************/
2523 #define JNI_GET_STATIC_FIELD(name, type, field) \
2524 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2530 STATISTICS(jniinvokation()); \
2532 c = LLNI_classinfo_unwrap(clazz); \
2533 f = (fieldinfo *) fieldID; \
2535 if (!(c->state & CLASS_INITIALIZED)) \
2536 if (!initialize_class(c)) \
2539 return f->value->field; \
2542 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2543 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2544 JNI_GET_STATIC_FIELD(Char, jchar, i)
2545 JNI_GET_STATIC_FIELD(Short, jshort, i)
2546 JNI_GET_STATIC_FIELD(Int, jint, i)
2547 JNI_GET_STATIC_FIELD(Long, jlong, l)
2548 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2549 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2552 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2558 STATISTICS(jniinvokation());
2560 c = LLNI_classinfo_unwrap(clazz);
2561 f = (fieldinfo *) fieldID;
2563 if (!(c->state & CLASS_INITIALIZED))
2564 if (!initialize_class(c))
2567 return _Jv_JNI_NewLocalRef(env, f->value->a);
2571 /* SetStatic<type>Field *******************************************************
2573 This family of accessor routines sets the value of a static field
2576 *******************************************************************************/
2578 #define JNI_SET_STATIC_FIELD(name, type, field) \
2579 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2586 STATISTICS(jniinvokation()); \
2588 c = LLNI_classinfo_unwrap(clazz); \
2589 f = (fieldinfo *) fieldID; \
2591 if (!(c->state & CLASS_INITIALIZED)) \
2592 if (!initialize_class(c)) \
2595 f->value->field = value; \
2598 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2599 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2600 JNI_SET_STATIC_FIELD(Char, jchar, i)
2601 JNI_SET_STATIC_FIELD(Short, jshort, i)
2602 JNI_SET_STATIC_FIELD(Int, jint, i)
2603 JNI_SET_STATIC_FIELD(Long, jlong, l)
2604 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2605 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2608 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2614 STATISTICS(jniinvokation());
2616 c = LLNI_classinfo_unwrap(clazz);
2617 f = (fieldinfo *) fieldID;
2619 if (!(c->state & CLASS_INITIALIZED))
2620 if (!initialize_class(c))
2623 f->value->a = value;
2627 /* String Operations **********************************************************/
2629 /* NewString *******************************************************************
2631 Create new java.lang.String object from an array of Unicode
2634 *******************************************************************************/
2636 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2638 java_lang_String *s;
2639 java_handle_chararray_t *a;
2642 STATISTICS(jniinvokation());
2644 s = (java_lang_String *) builtin_new(class_java_lang_String);
2645 a = builtin_newarray_char(len);
2647 /* javastring or characterarray could not be created */
2648 if ((a == NULL) || (s == NULL))
2652 for (i = 0; i < len; i++)
2653 LLNI_array_direct(a, i) = buf[i];
2655 LLNI_field_set_ref(s, value , a);
2656 LLNI_field_set_val(s, offset, 0);
2657 LLNI_field_set_val(s, count , len);
2659 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2663 static jchar emptyStringJ[]={0,0};
2665 /* GetStringLength *************************************************************
2667 Returns the length (the count of Unicode characters) of a Java
2670 *******************************************************************************/
2672 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2674 java_lang_String *s;
2677 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2679 s = (java_lang_String *) str;
2681 LLNI_field_get_val(s, count, len);
2687 /******************** convertes javastring to u2-array ****************************/
2689 u2 *javastring_tou2(jstring so)
2691 java_lang_String *s;
2692 java_handle_chararray_t *a;
2698 STATISTICS(jniinvokation());
2700 s = (java_lang_String *) so;
2705 LLNI_field_get_ref(s, value, a);
2710 LLNI_field_get_val(s, count, count);
2711 LLNI_field_get_val(s, offset, offset);
2713 /* allocate memory */
2715 stringbuffer = MNEW(u2, count + 1);
2719 for (i = 0; i < count; i++)
2720 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2722 /* terminate string */
2724 stringbuffer[i] = '\0';
2726 return stringbuffer;
2730 /* GetStringChars **************************************************************
2732 Returns a pointer to the array of Unicode characters of the
2733 string. This pointer is valid until ReleaseStringChars() is called.
2735 *******************************************************************************/
2737 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2741 STATISTICS(jniinvokation());
2743 jc = javastring_tou2(str);
2755 return emptyStringJ;
2759 /* ReleaseStringChars **********************************************************
2761 Informs the VM that the native code no longer needs access to
2762 chars. The chars argument is a pointer obtained from string using
2765 *******************************************************************************/
2767 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2769 java_lang_String *s;
2771 STATISTICS(jniinvokation());
2773 if (chars == emptyStringJ)
2776 s = (java_lang_String *) str;
2778 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2782 /* NewStringUTF ****************************************************************
2784 Constructs a new java.lang.String object from an array of UTF-8
2787 *******************************************************************************/
2789 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2791 java_lang_String *s;
2793 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2795 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2797 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2801 /****************** returns the utf8 length in bytes of a string *******************/
2803 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2805 java_lang_String *s;
2808 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2810 s = (java_lang_String *) string;
2812 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2818 /* GetStringUTFChars ***********************************************************
2820 Returns a pointer to an array of UTF-8 characters of the
2821 string. This array is valid until it is released by
2822 ReleaseStringUTFChars().
2824 *******************************************************************************/
2826 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2831 STATISTICS(jniinvokation());
2839 u = javastring_toutf((java_handle_t *) string, false);
2848 /* ReleaseStringUTFChars *******************************************************
2850 Informs the VM that the native code no longer needs access to
2851 utf. The utf argument is a pointer derived from string using
2852 GetStringUTFChars().
2854 *******************************************************************************/
2856 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2858 STATISTICS(jniinvokation());
2860 /* XXX we don't release utf chars right now, perhaps that should be done
2861 later. Since there is always one reference the garbage collector will
2866 /* Array Operations ***********************************************************/
2868 /* GetArrayLength **************************************************************
2870 Returns the number of elements in the array.
2872 *******************************************************************************/
2874 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2879 STATISTICS(jniinvokation());
2881 a = (java_handle_t *) array;
2883 size = LLNI_array_size(a);
2889 /* NewObjectArray **************************************************************
2891 Constructs a new array holding objects in class elementClass. All
2892 elements are initially set to initialElement.
2894 *******************************************************************************/
2896 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2897 jclass elementClass, jobject initialElement)
2901 java_handle_objectarray_t *oa;
2904 STATISTICS(jniinvokation());
2906 c = LLNI_classinfo_unwrap(elementClass);
2907 o = (java_handle_t *) initialElement;
2910 exceptions_throw_negativearraysizeexception();
2914 oa = builtin_anewarray(length, c);
2919 /* set all elements to initialElement */
2921 for (i = 0; i < length; i++)
2922 LLNI_objectarray_element_set(oa, i, o);
2924 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2928 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2931 java_handle_objectarray_t *oa;
2934 STATISTICS(jniinvokation());
2936 oa = (java_handle_objectarray_t *) array;
2938 if (index >= LLNI_array_size(oa)) {
2939 exceptions_throw_arrayindexoutofboundsexception();
2943 LLNI_objectarray_element_get(oa, index, o);
2945 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2949 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2950 jsize index, jobject val)
2952 java_handle_objectarray_t *oa;
2955 STATISTICS(jniinvokation());
2957 oa = (java_handle_objectarray_t *) array;
2958 o = (java_handle_t *) val;
2960 if (index >= LLNI_array_size(oa)) {
2961 exceptions_throw_arrayindexoutofboundsexception();
2965 /* check if the class of value is a subclass of the element class
2968 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2971 LLNI_objectarray_element_set(oa, index, o);
2975 #define JNI_NEW_ARRAY(name, type, intern) \
2976 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2978 java_handle_##intern##array_t *a; \
2980 STATISTICS(jniinvokation()); \
2983 exceptions_throw_negativearraysizeexception(); \
2987 a = builtin_newarray_##intern(len); \
2989 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2992 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2993 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2994 JNI_NEW_ARRAY(Char, jcharArray, char)
2995 JNI_NEW_ARRAY(Short, jshortArray, byte)
2996 JNI_NEW_ARRAY(Int, jintArray, int)
2997 JNI_NEW_ARRAY(Long, jlongArray, long)
2998 JNI_NEW_ARRAY(Float, jfloatArray, float)
2999 JNI_NEW_ARRAY(Double, jdoubleArray, double)
3002 /* Get<PrimitiveType>ArrayElements *********************************************
3004 A family of functions that returns the body of the primitive array.
3006 *******************************************************************************/
3008 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
3009 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
3012 java_handle_##intern##array_t *a; \
3014 STATISTICS(jniinvokation()); \
3016 a = (java_handle_##intern##array_t *) array; \
3019 *isCopy = JNI_FALSE; \
3021 return LLNI_array_data(a); \
3024 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3025 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3026 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3027 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3028 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3029 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3030 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3031 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3034 /* Release<PrimitiveType>ArrayElements *****************************************
3036 A family of functions that informs the VM that the native code no
3037 longer needs access to elems. The elems argument is a pointer
3038 derived from array using the corresponding
3039 Get<PrimitiveType>ArrayElements() function. If necessary, this
3040 function copies back all changes made to elems to the original
3043 *******************************************************************************/
3045 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3046 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3047 type *elems, jint mode) \
3049 java_handle_##intern##array_t *a; \
3051 STATISTICS(jniinvokation()); \
3053 a = (java_handle_##intern##array_t *) array; \
3055 if (elems != LLNI_array_data(a)) { \
3058 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3061 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3062 /* XXX TWISTI how should it be freed? */ \
3065 /* XXX TWISTI how should it be freed? */ \
3071 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3072 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3073 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3074 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3075 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3076 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3077 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3078 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3081 /* Get<PrimitiveType>ArrayRegion **********************************************
3083 A family of functions that copies a region of a primitive array
3086 *******************************************************************************/
3088 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3089 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3090 jsize start, jsize len, type *buf) \
3092 java_handle_##intern##array_t *a; \
3094 STATISTICS(jniinvokation()); \
3096 a = (java_handle_##intern##array_t *) array; \
3098 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3099 exceptions_throw_arrayindexoutofboundsexception(); \
3101 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3104 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3105 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3106 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3107 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3108 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3109 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3110 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3111 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3114 /* Set<PrimitiveType>ArrayRegion **********************************************
3116 A family of functions that copies back a region of a primitive
3117 array from a buffer.
3119 *******************************************************************************/
3121 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3122 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3123 jsize start, jsize len, const type *buf) \
3125 java_handle_##intern##array_t *a; \
3127 STATISTICS(jniinvokation()); \
3129 a = (java_handle_##intern##array_t *) array; \
3131 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3132 exceptions_throw_arrayindexoutofboundsexception(); \
3134 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3137 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3138 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3139 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3140 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3141 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3142 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3143 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3144 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3147 /* Registering Native Methods *************************************************/
3149 /* RegisterNatives *************************************************************
3151 Registers native methods with the class specified by the clazz
3152 argument. The methods parameter specifies an array of
3153 JNINativeMethod structures that contain the names, signatures, and
3154 function pointers of the native methods. The nMethods parameter
3155 specifies the number of native methods in the array.
3157 *******************************************************************************/
3159 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3160 const JNINativeMethod *methods, jint nMethods)
3164 STATISTICS(jniinvokation());
3166 c = LLNI_classinfo_unwrap(clazz);
3168 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3169 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3172 native_method_register(c->name, methods, nMethods);
3178 /* UnregisterNatives ***********************************************************
3180 Unregisters native methods of a class. The class goes back to the
3181 state before it was linked or registered with its native method
3184 This function should not be used in normal native code. Instead, it
3185 provides special programs a way to reload and relink native
3188 *******************************************************************************/
3190 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3192 STATISTICS(jniinvokation());
3194 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3196 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3202 /* Monitor Operations *********************************************************/
3204 /* MonitorEnter ****************************************************************
3206 Enters the monitor associated with the underlying Java object
3209 *******************************************************************************/
3211 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3213 STATISTICS(jniinvokation());
3216 exceptions_throw_nullpointerexception();
3220 LOCK_MONITOR_ENTER(obj);
3226 /* MonitorExit *****************************************************************
3228 The current thread must be the owner of the monitor associated with
3229 the underlying Java object referred to by obj. The thread
3230 decrements the counter indicating the number of times it has
3231 entered this monitor. If the value of the counter becomes zero, the
3232 current thread releases the monitor.
3234 *******************************************************************************/
3236 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3238 STATISTICS(jniinvokation());
3241 exceptions_throw_nullpointerexception();
3245 LOCK_MONITOR_EXIT(obj);
3251 /* JavaVM Interface ***********************************************************/
3253 /* GetJavaVM *******************************************************************
3255 Returns the Java VM interface (used in the Invocation API)
3256 associated with the current thread. The result is placed at the
3257 location pointed to by the second argument, vm.
3259 *******************************************************************************/
3261 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3263 STATISTICS(jniinvokation());
3265 *vm = (JavaVM *) _Jv_jvm;
3271 /* GetStringRegion *************************************************************
3273 Copies len number of Unicode characters beginning at offset start
3274 to the given buffer buf.
3276 Throws StringIndexOutOfBoundsException on index overflow.
3278 *******************************************************************************/
3280 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3283 java_lang_String *s;
3284 java_handle_chararray_t *ca;
3286 STATISTICS(jniinvokation());
3288 s = (java_lang_String *) str;
3289 LLNI_field_get_ref(s, value, ca);
3291 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3292 (start + len > LLNI_field_direct(s, count))) {
3293 exceptions_throw_stringindexoutofboundsexception();
3297 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3301 /* GetStringUTFRegion **********************************************************
3303 Translates len number of Unicode characters beginning at offset
3304 start into UTF-8 format and place the result in the given buffer
3307 Throws StringIndexOutOfBoundsException on index overflow.
3309 *******************************************************************************/
3311 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3312 jsize len, char *buf)
3314 java_lang_String *s;
3315 java_handle_chararray_t *ca;
3320 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3322 s = (java_lang_String *) str;
3323 LLNI_field_get_ref(s, value, ca);
3324 LLNI_field_get_val(s, count, count);
3325 LLNI_field_get_val(s, offset, offset);
3327 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3328 exceptions_throw_stringindexoutofboundsexception();
3332 for (i = 0; i < len; i++)
3333 buf[i] = LLNI_array_direct(ca, offset + start + i);
3339 /* GetPrimitiveArrayCritical ***************************************************
3341 Obtain a direct pointer to array elements.
3343 *******************************************************************************/
3345 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3348 java_handle_bytearray_t *ba;
3351 ba = (java_handle_bytearray_t *) array;
3353 /* do the same as Kaffe does */
3355 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3361 /* ReleasePrimitiveArrayCritical ***********************************************
3363 No specific documentation.
3365 *******************************************************************************/
3367 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3368 void *carray, jint mode)
3370 STATISTICS(jniinvokation());
3372 /* do the same as Kaffe does */
3374 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3379 /* GetStringCritical ***********************************************************
3381 The semantics of these two functions are similar to the existing
3382 Get/ReleaseStringChars functions.
3384 *******************************************************************************/
3386 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3389 STATISTICS(jniinvokation());
3391 return _Jv_JNI_GetStringChars(env, string, isCopy);
3395 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3396 const jchar *cstring)
3398 STATISTICS(jniinvokation());
3400 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3404 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3406 STATISTICS(jniinvokation());
3408 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3414 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3416 STATISTICS(jniinvokation());
3418 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3422 /* NewGlobalRef ****************************************************************
3424 Creates a new global reference to the object referred to by the obj
3427 *******************************************************************************/
3429 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3431 hashtable_global_ref_entry *gre;
3432 u4 key; /* hashkey */
3433 u4 slot; /* slot in hashtable */
3436 STATISTICS(jniinvokation());
3438 o = (java_handle_t *) obj;
3440 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3442 LLNI_CRITICAL_START;
3444 /* normally addresses are aligned to 4, 8 or 16 bytes */
3446 #if defined(ENABLE_GC_CACAO)
3447 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3449 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3451 slot = key & (hashtable_global_ref->size - 1);
3452 gre = hashtable_global_ref->ptr[slot];
3454 /* search external hash chain for the entry */
3457 if (gre->o == LLNI_DIRECT(o)) {
3458 /* global object found, increment the reference */
3465 gre = gre->hashlink; /* next element in external chain */
3468 /* global ref not found, create a new one */
3471 gre = NEW(hashtable_global_ref_entry);
3473 #if defined(ENABLE_GC_CACAO)
3474 /* register global ref with the GC */
3476 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3479 gre->o = LLNI_DIRECT(o);
3482 /* insert entry into hashtable */
3484 gre->hashlink = hashtable_global_ref->ptr[slot];
3486 hashtable_global_ref->ptr[slot] = gre;
3488 /* update number of hashtable-entries */
3490 hashtable_global_ref->entries++;
3495 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3497 #if defined(ENABLE_HANDLES)
3505 /* DeleteGlobalRef *************************************************************
3507 Deletes the global reference pointed to by globalRef.
3509 *******************************************************************************/
3511 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3513 hashtable_global_ref_entry *gre;
3514 hashtable_global_ref_entry *prevgre;
3515 u4 key; /* hashkey */
3516 u4 slot; /* slot in hashtable */
3519 STATISTICS(jniinvokation());
3521 o = (java_handle_t *) globalRef;
3523 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3525 LLNI_CRITICAL_START;
3527 /* normally addresses are aligned to 4, 8 or 16 bytes */
3529 #if defined(ENABLE_GC_CACAO)
3530 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3532 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3534 slot = key & (hashtable_global_ref->size - 1);
3535 gre = hashtable_global_ref->ptr[slot];
3537 /* initialize prevgre */
3541 /* search external hash chain for the entry */
3544 if (gre->o == LLNI_DIRECT(o)) {
3545 /* global object found, decrement the reference count */
3549 /* if reference count is 0, remove the entry */
3551 if (gre->refs == 0) {
3552 /* special handling if it's the first in the chain */
3554 if (prevgre == NULL)
3555 hashtable_global_ref->ptr[slot] = gre->hashlink;
3557 prevgre->hashlink = gre->hashlink;
3559 #if defined(ENABLE_GC_CACAO)
3560 /* unregister global ref with the GC */
3562 gc_reference_unregister(&(gre->o));
3565 FREE(gre, hashtable_global_ref_entry);
3570 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3575 prevgre = gre; /* save current pointer for removal */
3576 gre = gre->hashlink; /* next element in external chain */
3579 log_println("JNI-DeleteGlobalRef: global reference not found");
3583 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3587 /* ExceptionCheck **************************************************************
3589 Returns JNI_TRUE when there is a pending exception; otherwise,
3592 *******************************************************************************/
3594 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3598 STATISTICS(jniinvokation());
3600 o = exceptions_get_exception();
3602 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3606 /* New JNI 1.4 functions ******************************************************/
3608 /* NewDirectByteBuffer *********************************************************
3610 Allocates and returns a direct java.nio.ByteBuffer referring to the
3611 block of memory starting at the memory address address and
3612 extending capacity bytes.
3614 *******************************************************************************/
3616 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3618 #if defined(ENABLE_JAVASE)
3619 # if defined(WITH_CLASSPATH_GNU)
3620 java_handle_t *nbuf;
3622 # if SIZEOF_VOID_P == 8
3623 gnu_classpath_Pointer64 *paddress;
3625 gnu_classpath_Pointer32 *paddress;
3628 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3630 /* alocate a gnu.classpath.Pointer{32,64} object */
3632 # if SIZEOF_VOID_P == 8
3633 if (!(paddress = (gnu_classpath_Pointer64 *)
3634 builtin_new(class_gnu_classpath_Pointer64)))
3636 if (!(paddress = (gnu_classpath_Pointer32 *)
3637 builtin_new(class_gnu_classpath_Pointer32)))
3641 /* fill gnu.classpath.Pointer{32,64} with address */
3643 LLNI_field_set_val(paddress, data, (ptrint) address);
3645 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3647 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3648 (jmethodID) dbbirw_init, NULL, paddress,
3649 (jint) capacity, (jint) capacity, (jint) 0);
3651 /* add local reference and return the value */
3653 return _Jv_JNI_NewLocalRef(env, nbuf);
3655 # elif defined(WITH_CLASSPATH_SUN)
3661 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3663 /* Be paranoid about address sign-extension. */
3665 addr = (int64_t) ((uintptr_t) address);
3666 cap = (int32_t) capacity;
3668 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3669 (jmethodID) dbb_init, addr, cap);
3671 /* Add local reference and return the value. */
3673 return _Jv_JNI_NewLocalRef(env, o);
3676 # error unknown classpath configuration
3680 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3682 /* keep compiler happy */
3689 /* GetDirectBufferAddress ******************************************************
3691 Fetches and returns the starting address of the memory region
3692 referenced by the given direct java.nio.Buffer.
3694 *******************************************************************************/
3696 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3698 #if defined(ENABLE_JAVASE)
3699 # if defined(WITH_CLASSPATH_GNU)
3701 java_nio_DirectByteBufferImpl *nbuf;
3702 # if SIZEOF_VOID_P == 8
3703 gnu_classpath_Pointer64 *paddress;
3705 gnu_classpath_Pointer32 *paddress;
3709 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3711 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3714 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3716 # if SIZEOF_VOID_P == 8
3717 LLNI_field_get_ref(nbuf, address, paddress);
3718 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3720 LLNI_field_get_ref(nbuf, address, paddress);
3721 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3724 if (paddress == NULL)
3727 LLNI_field_get_val(paddress, data, address);
3728 /* this was the cast to avaoid warning: (void *) paddress->data */
3732 # elif defined(WITH_CLASSPATH_SUN)
3738 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3740 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3743 o = (java_nio_Buffer *) buf;
3745 LLNI_field_get_val(o, address, address);
3747 p = (void *) (intptr_t) address;
3752 # error unknown classpath configuration
3757 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3759 /* keep compiler happy */
3767 /* GetDirectBufferCapacity *****************************************************
3769 Fetches and returns the capacity in bytes of the memory region
3770 referenced by the given direct java.nio.Buffer.
3772 *******************************************************************************/
3774 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3776 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3778 java_nio_Buffer *nbuf;
3781 STATISTICS(jniinvokation());
3783 o = (java_handle_t *) buf;
3785 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3788 nbuf = (java_nio_Buffer *) o;
3790 LLNI_field_get_val(nbuf, cap, capacity);
3794 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3796 /* keep compiler happy */
3803 /* GetObjectRefType ************************************************************
3805 Returns the type of the object referred to by the obj argument. The
3806 argument obj can either be a local, global or weak global
3809 *******************************************************************************/
3811 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3813 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3819 /* DestroyJavaVM ***************************************************************
3821 Unloads a Java VM and reclaims its resources. Only the main thread
3822 can unload the VM. The system waits until the main thread is only
3823 remaining user thread before it destroys the VM.
3825 *******************************************************************************/
3827 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3831 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3833 status = vm_destroy(vm);
3839 /* AttachCurrentThread *********************************************************
3841 Attaches the current thread to a Java VM. Returns a JNI interface
3842 pointer in the JNIEnv argument.
3844 Trying to attach a thread that is already attached is a no-op.
3846 A native thread cannot be attached simultaneously to two Java VMs.
3848 When a thread is attached to the VM, the context class loader is
3849 the bootstrap loader.
3851 *******************************************************************************/
3853 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3855 JavaVMAttachArgs *vm_aargs;
3857 #if defined(ENABLE_THREADS)
3858 if (threads_get_current_threadobject() == NULL) {
3859 vm_aargs = (JavaVMAttachArgs *) thr_args;
3861 if (vm_aargs != NULL) {
3862 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3863 (vm_aargs->version != JNI_VERSION_1_4))
3864 return JNI_EVERSION;
3867 if (!threads_attach_current_thread(vm_aargs, false))
3870 if (!localref_table_init())
3881 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3883 STATISTICS(jniinvokation());
3885 return jni_attach_current_thread(p_env, thr_args, false);
3889 /* DetachCurrentThread *********************************************************
3891 Detaches the current thread from a Java VM. All Java monitors held
3892 by this thread are released. All Java threads waiting for this
3893 thread to die are notified.
3895 In JDK 1.1, the main thread cannot be detached from the VM. It must
3896 call DestroyJavaVM to unload the entire VM.
3898 In the JDK, the main thread can be detached from the VM.
3900 The main thread, which is the thread that created the Java VM,
3901 cannot be detached from the VM. Instead, the main thread must call
3902 JNI_DestroyJavaVM() to unload the entire VM.
3904 *******************************************************************************/
3906 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3908 #if defined(ENABLE_THREADS)
3909 threadobject *thread;
3911 STATISTICS(jniinvokation());
3913 thread = threads_get_current_threadobject();
3918 if (!localref_table_destroy())
3921 if (!threads_detach_thread(thread))
3929 /* GetEnv **********************************************************************
3931 If the current thread is not attached to the VM, sets *env to NULL,
3932 and returns JNI_EDETACHED. If the specified version is not
3933 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3934 sets *env to the appropriate interface, and returns JNI_OK.
3936 *******************************************************************************/
3938 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3940 STATISTICS(jniinvokation());
3942 #if defined(ENABLE_THREADS)
3943 if (threads_get_current_threadobject() == NULL) {
3946 return JNI_EDETACHED;
3950 /* check the JNI version */
3953 case JNI_VERSION_1_1:
3954 case JNI_VERSION_1_2:
3955 case JNI_VERSION_1_4:
3963 #if defined(ENABLE_JVMTI)
3964 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3965 == JVMTI_VERSION_INTERFACE_JVMTI) {
3967 *env = (void *) jvmti_new_environment();
3976 return JNI_EVERSION;
3980 /* AttachCurrentThreadAsDaemon *************************************************
3982 Same semantics as AttachCurrentThread, but the newly-created
3983 java.lang.Thread instance is a daemon.
3985 If the thread has already been attached via either
3986 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3987 simply sets the value pointed to by penv to the JNIEnv of the
3988 current thread. In this case neither AttachCurrentThread nor this
3989 routine have any effect on the daemon status of the thread.
3991 *******************************************************************************/
3993 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3995 STATISTICS(jniinvokation());
3997 return jni_attach_current_thread(penv, args, true);
4001 /* JNI invocation table *******************************************************/
4003 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4008 _Jv_JNI_DestroyJavaVM,
4009 _Jv_JNI_AttachCurrentThread,
4010 _Jv_JNI_DetachCurrentThread,
4012 _Jv_JNI_AttachCurrentThreadAsDaemon
4016 /* JNI function table *********************************************************/
4018 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4025 _Jv_JNI_DefineClass,
4027 _Jv_JNI_FromReflectedMethod,
4028 _Jv_JNI_FromReflectedField,
4029 _Jv_JNI_ToReflectedMethod,
4030 _Jv_JNI_GetSuperclass,
4031 _Jv_JNI_IsAssignableFrom,
4032 _Jv_JNI_ToReflectedField,
4036 _Jv_JNI_ExceptionOccurred,
4037 _Jv_JNI_ExceptionDescribe,
4038 _Jv_JNI_ExceptionClear,
4040 _Jv_JNI_PushLocalFrame,
4041 _Jv_JNI_PopLocalFrame,
4043 _Jv_JNI_NewGlobalRef,
4044 _Jv_JNI_DeleteGlobalRef,
4045 _Jv_JNI_DeleteLocalRef,
4046 _Jv_JNI_IsSameObject,
4047 _Jv_JNI_NewLocalRef,
4048 _Jv_JNI_EnsureLocalCapacity,
4050 _Jv_JNI_AllocObject,
4055 _Jv_JNI_GetObjectClass,
4056 _Jv_JNI_IsInstanceOf,
4058 _Jv_JNI_GetMethodID,
4060 _Jv_JNI_CallObjectMethod,
4061 _Jv_JNI_CallObjectMethodV,
4062 _Jv_JNI_CallObjectMethodA,
4063 _Jv_JNI_CallBooleanMethod,
4064 _Jv_JNI_CallBooleanMethodV,
4065 _Jv_JNI_CallBooleanMethodA,
4066 _Jv_JNI_CallByteMethod,
4067 _Jv_JNI_CallByteMethodV,
4068 _Jv_JNI_CallByteMethodA,
4069 _Jv_JNI_CallCharMethod,
4070 _Jv_JNI_CallCharMethodV,
4071 _Jv_JNI_CallCharMethodA,
4072 _Jv_JNI_CallShortMethod,
4073 _Jv_JNI_CallShortMethodV,
4074 _Jv_JNI_CallShortMethodA,
4075 _Jv_JNI_CallIntMethod,
4076 _Jv_JNI_CallIntMethodV,
4077 _Jv_JNI_CallIntMethodA,
4078 _Jv_JNI_CallLongMethod,
4079 _Jv_JNI_CallLongMethodV,
4080 _Jv_JNI_CallLongMethodA,
4081 _Jv_JNI_CallFloatMethod,
4082 _Jv_JNI_CallFloatMethodV,
4083 _Jv_JNI_CallFloatMethodA,
4084 _Jv_JNI_CallDoubleMethod,
4085 _Jv_JNI_CallDoubleMethodV,
4086 _Jv_JNI_CallDoubleMethodA,
4087 _Jv_JNI_CallVoidMethod,
4088 _Jv_JNI_CallVoidMethodV,
4089 _Jv_JNI_CallVoidMethodA,
4091 _Jv_JNI_CallNonvirtualObjectMethod,
4092 _Jv_JNI_CallNonvirtualObjectMethodV,
4093 _Jv_JNI_CallNonvirtualObjectMethodA,
4094 _Jv_JNI_CallNonvirtualBooleanMethod,
4095 _Jv_JNI_CallNonvirtualBooleanMethodV,
4096 _Jv_JNI_CallNonvirtualBooleanMethodA,
4097 _Jv_JNI_CallNonvirtualByteMethod,
4098 _Jv_JNI_CallNonvirtualByteMethodV,
4099 _Jv_JNI_CallNonvirtualByteMethodA,
4100 _Jv_JNI_CallNonvirtualCharMethod,
4101 _Jv_JNI_CallNonvirtualCharMethodV,
4102 _Jv_JNI_CallNonvirtualCharMethodA,
4103 _Jv_JNI_CallNonvirtualShortMethod,
4104 _Jv_JNI_CallNonvirtualShortMethodV,
4105 _Jv_JNI_CallNonvirtualShortMethodA,
4106 _Jv_JNI_CallNonvirtualIntMethod,
4107 _Jv_JNI_CallNonvirtualIntMethodV,
4108 _Jv_JNI_CallNonvirtualIntMethodA,
4109 _Jv_JNI_CallNonvirtualLongMethod,
4110 _Jv_JNI_CallNonvirtualLongMethodV,
4111 _Jv_JNI_CallNonvirtualLongMethodA,
4112 _Jv_JNI_CallNonvirtualFloatMethod,
4113 _Jv_JNI_CallNonvirtualFloatMethodV,
4114 _Jv_JNI_CallNonvirtualFloatMethodA,
4115 _Jv_JNI_CallNonvirtualDoubleMethod,
4116 _Jv_JNI_CallNonvirtualDoubleMethodV,
4117 _Jv_JNI_CallNonvirtualDoubleMethodA,
4118 _Jv_JNI_CallNonvirtualVoidMethod,
4119 _Jv_JNI_CallNonvirtualVoidMethodV,
4120 _Jv_JNI_CallNonvirtualVoidMethodA,
4124 _Jv_JNI_GetObjectField,
4125 _Jv_JNI_GetBooleanField,
4126 _Jv_JNI_GetByteField,
4127 _Jv_JNI_GetCharField,
4128 _Jv_JNI_GetShortField,
4129 _Jv_JNI_GetIntField,
4130 _Jv_JNI_GetLongField,
4131 _Jv_JNI_GetFloatField,
4132 _Jv_JNI_GetDoubleField,
4133 _Jv_JNI_SetObjectField,
4134 _Jv_JNI_SetBooleanField,
4135 _Jv_JNI_SetByteField,
4136 _Jv_JNI_SetCharField,
4137 _Jv_JNI_SetShortField,
4138 _Jv_JNI_SetIntField,
4139 _Jv_JNI_SetLongField,
4140 _Jv_JNI_SetFloatField,
4141 _Jv_JNI_SetDoubleField,
4143 _Jv_JNI_GetStaticMethodID,
4145 _Jv_JNI_CallStaticObjectMethod,
4146 _Jv_JNI_CallStaticObjectMethodV,
4147 _Jv_JNI_CallStaticObjectMethodA,
4148 _Jv_JNI_CallStaticBooleanMethod,
4149 _Jv_JNI_CallStaticBooleanMethodV,
4150 _Jv_JNI_CallStaticBooleanMethodA,
4151 _Jv_JNI_CallStaticByteMethod,
4152 _Jv_JNI_CallStaticByteMethodV,
4153 _Jv_JNI_CallStaticByteMethodA,
4154 _Jv_JNI_CallStaticCharMethod,
4155 _Jv_JNI_CallStaticCharMethodV,
4156 _Jv_JNI_CallStaticCharMethodA,
4157 _Jv_JNI_CallStaticShortMethod,
4158 _Jv_JNI_CallStaticShortMethodV,
4159 _Jv_JNI_CallStaticShortMethodA,
4160 _Jv_JNI_CallStaticIntMethod,
4161 _Jv_JNI_CallStaticIntMethodV,
4162 _Jv_JNI_CallStaticIntMethodA,
4163 _Jv_JNI_CallStaticLongMethod,
4164 _Jv_JNI_CallStaticLongMethodV,
4165 _Jv_JNI_CallStaticLongMethodA,
4166 _Jv_JNI_CallStaticFloatMethod,
4167 _Jv_JNI_CallStaticFloatMethodV,
4168 _Jv_JNI_CallStaticFloatMethodA,
4169 _Jv_JNI_CallStaticDoubleMethod,
4170 _Jv_JNI_CallStaticDoubleMethodV,
4171 _Jv_JNI_CallStaticDoubleMethodA,
4172 _Jv_JNI_CallStaticVoidMethod,
4173 _Jv_JNI_CallStaticVoidMethodV,
4174 _Jv_JNI_CallStaticVoidMethodA,
4176 _Jv_JNI_GetStaticFieldID,
4178 _Jv_JNI_GetStaticObjectField,
4179 _Jv_JNI_GetStaticBooleanField,
4180 _Jv_JNI_GetStaticByteField,
4181 _Jv_JNI_GetStaticCharField,
4182 _Jv_JNI_GetStaticShortField,
4183 _Jv_JNI_GetStaticIntField,
4184 _Jv_JNI_GetStaticLongField,
4185 _Jv_JNI_GetStaticFloatField,
4186 _Jv_JNI_GetStaticDoubleField,
4187 _Jv_JNI_SetStaticObjectField,
4188 _Jv_JNI_SetStaticBooleanField,
4189 _Jv_JNI_SetStaticByteField,
4190 _Jv_JNI_SetStaticCharField,
4191 _Jv_JNI_SetStaticShortField,
4192 _Jv_JNI_SetStaticIntField,
4193 _Jv_JNI_SetStaticLongField,
4194 _Jv_JNI_SetStaticFloatField,
4195 _Jv_JNI_SetStaticDoubleField,
4198 _Jv_JNI_GetStringLength,
4199 _Jv_JNI_GetStringChars,
4200 _Jv_JNI_ReleaseStringChars,
4202 _Jv_JNI_NewStringUTF,
4203 _Jv_JNI_GetStringUTFLength,
4204 _Jv_JNI_GetStringUTFChars,
4205 _Jv_JNI_ReleaseStringUTFChars,
4207 _Jv_JNI_GetArrayLength,
4209 _Jv_JNI_NewObjectArray,
4210 _Jv_JNI_GetObjectArrayElement,
4211 _Jv_JNI_SetObjectArrayElement,
4213 _Jv_JNI_NewBooleanArray,
4214 _Jv_JNI_NewByteArray,
4215 _Jv_JNI_NewCharArray,
4216 _Jv_JNI_NewShortArray,
4217 _Jv_JNI_NewIntArray,
4218 _Jv_JNI_NewLongArray,
4219 _Jv_JNI_NewFloatArray,
4220 _Jv_JNI_NewDoubleArray,
4222 _Jv_JNI_GetBooleanArrayElements,
4223 _Jv_JNI_GetByteArrayElements,
4224 _Jv_JNI_GetCharArrayElements,
4225 _Jv_JNI_GetShortArrayElements,
4226 _Jv_JNI_GetIntArrayElements,
4227 _Jv_JNI_GetLongArrayElements,
4228 _Jv_JNI_GetFloatArrayElements,
4229 _Jv_JNI_GetDoubleArrayElements,
4231 _Jv_JNI_ReleaseBooleanArrayElements,
4232 _Jv_JNI_ReleaseByteArrayElements,
4233 _Jv_JNI_ReleaseCharArrayElements,
4234 _Jv_JNI_ReleaseShortArrayElements,
4235 _Jv_JNI_ReleaseIntArrayElements,
4236 _Jv_JNI_ReleaseLongArrayElements,
4237 _Jv_JNI_ReleaseFloatArrayElements,
4238 _Jv_JNI_ReleaseDoubleArrayElements,
4240 _Jv_JNI_GetBooleanArrayRegion,
4241 _Jv_JNI_GetByteArrayRegion,
4242 _Jv_JNI_GetCharArrayRegion,
4243 _Jv_JNI_GetShortArrayRegion,
4244 _Jv_JNI_GetIntArrayRegion,
4245 _Jv_JNI_GetLongArrayRegion,
4246 _Jv_JNI_GetFloatArrayRegion,
4247 _Jv_JNI_GetDoubleArrayRegion,
4248 _Jv_JNI_SetBooleanArrayRegion,
4249 _Jv_JNI_SetByteArrayRegion,
4250 _Jv_JNI_SetCharArrayRegion,
4251 _Jv_JNI_SetShortArrayRegion,
4252 _Jv_JNI_SetIntArrayRegion,
4253 _Jv_JNI_SetLongArrayRegion,
4254 _Jv_JNI_SetFloatArrayRegion,
4255 _Jv_JNI_SetDoubleArrayRegion,
4257 _Jv_JNI_RegisterNatives,
4258 _Jv_JNI_UnregisterNatives,
4260 _Jv_JNI_MonitorEnter,
4261 _Jv_JNI_MonitorExit,
4265 /* New JNI 1.2 functions. */
4267 _Jv_JNI_GetStringRegion,
4268 _Jv_JNI_GetStringUTFRegion,
4270 _Jv_JNI_GetPrimitiveArrayCritical,
4271 _Jv_JNI_ReleasePrimitiveArrayCritical,
4273 _Jv_JNI_GetStringCritical,
4274 _Jv_JNI_ReleaseStringCritical,
4276 _Jv_JNI_NewWeakGlobalRef,
4277 _Jv_JNI_DeleteWeakGlobalRef,
4279 _Jv_JNI_ExceptionCheck,
4281 /* New JNI 1.4 functions. */
4283 _Jv_JNI_NewDirectByteBuffer,
4284 _Jv_JNI_GetDirectBufferAddress,
4285 _Jv_JNI_GetDirectBufferCapacity,
4287 /* New JNI 1.6 functions. */
4289 jni_GetObjectRefType
4293 /* Invocation API Functions ***************************************************/
4295 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4297 Returns a default configuration for the Java VM.
4299 *******************************************************************************/
4301 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4303 JavaVMInitArgs *_vm_args;
4305 _vm_args = (JavaVMInitArgs *) vm_args;
4307 /* GNU classpath currently supports JNI 1.2 */
4309 switch (_vm_args->version) {
4310 case JNI_VERSION_1_1:
4311 _vm_args->version = JNI_VERSION_1_1;
4314 case JNI_VERSION_1_2:
4315 case JNI_VERSION_1_4:
4316 _vm_args->ignoreUnrecognized = JNI_FALSE;
4317 _vm_args->options = NULL;
4318 _vm_args->nOptions = 0;
4329 /* JNI_GetCreatedJavaVMs *******************************************************
4331 Returns all Java VMs that have been created. Pointers to VMs are written in
4332 the buffer vmBuf in the order they are created. At most bufLen number of
4333 entries will be written. The total number of created VMs is returned in
4336 *******************************************************************************/
4338 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4340 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4345 /* We currently only support 1 VM running. */
4347 vmBuf[0] = (JavaVM *) _Jv_jvm;
4354 /* JNI_CreateJavaVM ************************************************************
4356 Loads and initializes a Java VM. The current thread becomes the main thread.
4357 Sets the env argument to the JNI interface pointer of the main thread.
4359 *******************************************************************************/
4361 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4363 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4365 /* actually create the JVM */
4367 if (!vm_createjvm(p_vm, p_env, vm_args))
4375 * These are local overrides for various environment variables in Emacs.
4376 * Please do not remove this and leave it at the end of the file, where
4377 * Emacs will automagically detect them.
4378 * ---------------------------------------------------------------------
4381 * indent-tabs-mode: t
4385 * vim:noexpandtab:sw=4:ts=4: