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/argument.h"
104 #include "vm/jit/asmpart.h"
105 #include "vm/jit/jit.h"
106 #include "vm/jit/stacktrace.h"
108 #include "vmcore/loader.h"
109 #include "vmcore/options.h"
110 #include "vmcore/statistics.h"
113 /* debug **********************************************************************/
116 # define TRACEJNICALLS(format, ...) \
118 if (opt_TraceJNICalls) { \
119 log_println((format), __VA_ARGS__); \
123 # define TRACEJNICALLS(format, ...)
127 /* global variables ***********************************************************/
129 /* global reference table *****************************************************/
131 /* hashsize must be power of 2 */
133 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
135 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
138 /* direct buffer stuff ********************************************************/
140 #if defined(ENABLE_JAVASE)
141 static classinfo *class_java_nio_Buffer;
143 # if defined(WITH_CLASSPATH_GNU)
145 static classinfo *class_java_nio_DirectByteBufferImpl;
146 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
148 # if SIZEOF_VOID_P == 8
149 static classinfo *class_gnu_classpath_Pointer64;
151 static classinfo *class_gnu_classpath_Pointer32;
154 static methodinfo *dbbirw_init;
156 # elif defined(WITH_CLASSPATH_SUN)
158 static classinfo *class_sun_nio_ch_DirectBuffer;
159 static classinfo *class_java_nio_DirectByteBuffer;
161 static methodinfo *dbb_init;
167 /* accessing instance fields macros *******************************************/
169 #define SET_FIELD(o,type,f,value) \
170 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
172 #define GET_FIELD(o,type,f) \
173 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
176 /* some forward declarations **************************************************/
178 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
181 /* jni_init ********************************************************************
183 Initialize the JNI subsystem.
185 *******************************************************************************/
189 /* create global ref hashtable */
191 hashtable_global_ref = NEW(hashtable);
193 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
196 #if defined(ENABLE_JAVASE)
197 /* Direct buffer stuff. */
199 if (!(class_java_nio_Buffer =
200 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
201 !link_class(class_java_nio_Buffer))
204 # if defined(WITH_CLASSPATH_GNU)
206 if (!(class_java_nio_DirectByteBufferImpl =
207 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
208 !link_class(class_java_nio_DirectByteBufferImpl))
211 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
212 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
213 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
217 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
219 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
222 # if SIZEOF_VOID_P == 8
223 if (!(class_gnu_classpath_Pointer64 =
224 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
225 !link_class(class_gnu_classpath_Pointer64))
228 if (!(class_gnu_classpath_Pointer32 =
229 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
230 !link_class(class_gnu_classpath_Pointer32))
234 # elif defined(WITH_CLASSPATH_SUN)
236 if (!(class_sun_nio_ch_DirectBuffer =
237 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
238 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
240 if (!link_class(class_sun_nio_ch_DirectBuffer))
241 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
243 if (!(class_java_nio_DirectByteBuffer =
244 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
245 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
247 if (!link_class(class_java_nio_DirectByteBuffer))
248 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
251 class_resolvemethod(class_java_nio_DirectByteBuffer,
253 utf_new_char("(JI)V"))))
254 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
258 #endif /* defined(ENABLE_JAVASE) */
264 /* jni_version_check ***********************************************************
266 Check if the given JNI version is supported.
269 version....JNI version to check
273 false......not supported
275 *******************************************************************************/
277 bool jni_version_check(int version)
280 case JNI_VERSION_1_1:
281 case JNI_VERSION_1_2:
282 case JNI_VERSION_1_4:
283 case JNI_VERSION_1_6:
291 /* _Jv_jni_CallObjectMethod ****************************************************
293 Internal function to call Java Object methods.
295 *******************************************************************************/
297 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
299 methodinfo *m, va_list ap)
304 STATISTICS(jniinvokation());
307 exceptions_throw_nullpointerexception();
311 /* Class initialization is done by the JIT compiler. This is ok
312 since a static method always belongs to the declaring class. */
314 if (m->flags & ACC_STATIC) {
315 /* For static methods we reset the object. */
320 /* for convenience */
325 /* For instance methods we make a virtual function table lookup. */
327 resm = method_vftbl_lookup(vftbl, m);
330 STATISTICS(jnicallXmethodnvokation());
332 ro = vm_call_method_valist(resm, o, ap);
338 /* _Jv_jni_CallObjectMethodA ***************************************************
340 Internal function to call Java Object methods.
342 *******************************************************************************/
344 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
352 STATISTICS(jniinvokation());
355 exceptions_throw_nullpointerexception();
359 /* Class initialization is done by the JIT compiler. This is ok
360 since a static method always belongs to the declaring class. */
362 if (m->flags & ACC_STATIC) {
363 /* For static methods we reset the object. */
368 /* for convenience */
373 /* For instance methods we make a virtual function table lookup. */
375 resm = method_vftbl_lookup(vftbl, m);
378 STATISTICS(jnicallXmethodnvokation());
380 ro = vm_call_method_jvalue(resm, o, args);
386 /* _Jv_jni_CallIntMethod *******************************************************
388 Internal function to call Java integer class methods (boolean,
389 byte, char, short, int).
391 *******************************************************************************/
393 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
394 methodinfo *m, va_list ap)
399 STATISTICS(jniinvokation());
402 exceptions_throw_nullpointerexception();
406 /* Class initialization is done by the JIT compiler. This is ok
407 since a static method always belongs to the declaring class. */
409 if (m->flags & ACC_STATIC) {
410 /* For static methods we reset the object. */
415 /* for convenience */
420 /* For instance methods we make a virtual function table lookup. */
422 resm = method_vftbl_lookup(vftbl, m);
425 STATISTICS(jnicallXmethodnvokation());
427 i = vm_call_method_int_valist(resm, o, ap);
433 /* _Jv_jni_CallIntMethodA ******************************************************
435 Internal function to call Java integer class methods (boolean,
436 byte, char, short, int).
438 *******************************************************************************/
440 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
441 methodinfo *m, const jvalue *args)
446 STATISTICS(jniinvokation());
449 exceptions_throw_nullpointerexception();
453 /* Class initialization is done by the JIT compiler. This is ok
454 since a static method always belongs to the declaring class. */
456 if (m->flags & ACC_STATIC) {
457 /* For static methods we reset the object. */
462 /* for convenience */
467 /* For instance methods we make a virtual function table lookup. */
469 resm = method_vftbl_lookup(vftbl, m);
472 STATISTICS(jnicallXmethodnvokation());
474 i = vm_call_method_int_jvalue(resm, o, args);
480 /* _Jv_jni_CallLongMethod ******************************************************
482 Internal function to call Java long methods.
484 *******************************************************************************/
486 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
487 methodinfo *m, va_list ap)
492 STATISTICS(jniinvokation());
495 exceptions_throw_nullpointerexception();
499 /* Class initialization is done by the JIT compiler. This is ok
500 since a static method always belongs to the declaring class. */
502 if (m->flags & ACC_STATIC) {
503 /* For static methods we reset the object. */
508 /* for convenience */
513 /* For instance methods we make a virtual function table lookup. */
515 resm = method_vftbl_lookup(vftbl, m);
518 STATISTICS(jnicallXmethodnvokation());
520 l = vm_call_method_long_valist(resm, o, ap);
526 /* _Jv_jni_CallLongMethodA *****************************************************
528 Internal function to call Java long methods.
530 *******************************************************************************/
532 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
533 methodinfo *m, const jvalue *args)
538 STATISTICS(jniinvokation());
541 exceptions_throw_nullpointerexception();
545 /* Class initialization is done by the JIT compiler. This is ok
546 since a static method always belongs to the declaring class. */
548 if (m->flags & ACC_STATIC) {
549 /* For static methods we reset the object. */
554 /* for convenience */
559 /* For instance methods we make a virtual function table lookup. */
561 resm = method_vftbl_lookup(vftbl, m);
564 STATISTICS(jnicallXmethodnvokation());
566 l = vm_call_method_long_jvalue(resm, o, args);
572 /* _Jv_jni_CallFloatMethod *****************************************************
574 Internal function to call Java float methods.
576 *******************************************************************************/
578 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
579 methodinfo *m, va_list ap)
584 /* Class initialization is done by the JIT compiler. This is ok
585 since a static method always belongs to the declaring class. */
587 if (m->flags & ACC_STATIC) {
588 /* For static methods we reset the object. */
593 /* for convenience */
598 /* For instance methods we make a virtual function table lookup. */
600 resm = method_vftbl_lookup(vftbl, m);
603 STATISTICS(jnicallXmethodnvokation());
605 f = vm_call_method_float_valist(resm, o, ap);
611 /* _Jv_jni_CallFloatMethodA ****************************************************
613 Internal function to call Java float methods.
615 *******************************************************************************/
617 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
618 methodinfo *m, const jvalue *args)
623 /* Class initialization is done by the JIT compiler. This is ok
624 since a static method always belongs to the declaring class. */
626 if (m->flags & ACC_STATIC) {
627 /* For static methods we reset the object. */
632 /* for convenience */
637 /* For instance methods we make a virtual function table lookup. */
639 resm = method_vftbl_lookup(vftbl, m);
642 STATISTICS(jnicallXmethodnvokation());
644 f = vm_call_method_float_jvalue(resm, o, args);
650 /* _Jv_jni_CallDoubleMethod ****************************************************
652 Internal function to call Java double methods.
654 *******************************************************************************/
656 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
657 methodinfo *m, va_list ap)
662 /* Class initialization is done by the JIT compiler. This is ok
663 since a static method always belongs to the declaring class. */
665 if (m->flags & ACC_STATIC) {
666 /* For static methods we reset the object. */
671 /* for convenience */
676 /* For instance methods we make a virtual function table lookup. */
678 resm = method_vftbl_lookup(vftbl, m);
681 d = vm_call_method_double_valist(resm, o, ap);
687 /* _Jv_jni_CallDoubleMethodA ***************************************************
689 Internal function to call Java double methods.
691 *******************************************************************************/
693 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
694 methodinfo *m, const jvalue *args)
699 /* Class initialization is done by the JIT compiler. This is ok
700 since a static method always belongs to the declaring class. */
702 if (m->flags & ACC_STATIC) {
703 /* For static methods we reset the object. */
708 /* for convenience */
713 /* For instance methods we make a virtual function table lookup. */
715 resm = method_vftbl_lookup(vftbl, m);
718 d = vm_call_method_double_jvalue(resm, o, args);
724 /* _Jv_jni_CallVoidMethod ******************************************************
726 Internal function to call Java void methods.
728 *******************************************************************************/
730 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
731 methodinfo *m, va_list ap)
736 exceptions_throw_nullpointerexception();
740 /* Class initialization is done by the JIT compiler. This is ok
741 since a static method always belongs to the declaring class. */
743 if (m->flags & ACC_STATIC) {
744 /* For static methods we reset the object. */
749 /* for convenience */
754 /* For instance methods we make a virtual function table lookup. */
756 resm = method_vftbl_lookup(vftbl, m);
759 STATISTICS(jnicallXmethodnvokation());
761 (void) vm_call_method_valist(resm, o, ap);
765 /* _Jv_jni_CallVoidMethodA *****************************************************
767 Internal function to call Java void methods.
769 *******************************************************************************/
771 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
772 methodinfo *m, const jvalue *args)
777 exceptions_throw_nullpointerexception();
781 /* Class initialization is done by the JIT compiler. This is ok
782 since a static method always belongs to the declaring class. */
784 if (m->flags & ACC_STATIC) {
785 /* For static methods we reset the object. */
790 /* for convenience */
795 /* For instance methods we make a virtual function table lookup. */
797 resm = method_vftbl_lookup(vftbl, m);
800 STATISTICS(jnicallXmethodnvokation());
802 (void) vm_call_method_jvalue(resm, o, args);
806 /* _Jv_jni_invokeNative ********************************************************
808 Invoke a method on the given object with the given arguments.
810 For instance methods OBJ must be != NULL and the method is looked up
811 in the vftbl of the object.
813 For static methods, OBJ is ignored.
815 *******************************************************************************/
817 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
818 java_handle_objectarray_t *params)
826 exceptions_throw_nullpointerexception();
830 argcount = m->parseddesc->paramcount;
831 paramcount = argcount;
833 /* if method is non-static, remove the `this' pointer */
835 if (!(m->flags & ACC_STATIC))
838 /* For instance methods the object has to be an instance of the
839 class the method belongs to. For static methods the obj
840 parameter is ignored. */
842 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
843 exceptions_throw_illegalargumentexception();
847 /* check if we got the right number of arguments */
849 if (((params == NULL) && (paramcount != 0)) ||
850 (params && (LLNI_array_size(params) != paramcount)))
852 exceptions_throw_illegalargumentexception();
856 /* for instance methods we need an object */
858 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
859 /* XXX not sure if that is the correct exception */
860 exceptions_throw_nullpointerexception();
864 /* for static methods, zero object to make subsequent code simpler */
865 if (m->flags & ACC_STATIC)
869 /* for instance methods we must do a vftbl lookup */
870 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
873 /* for static methods, just for convenience */
877 ro = vm_call_method_objectarray(resm, o, params);
883 /* GetVersion ******************************************************************
885 Returns the major version number in the higher 16 bits and the
886 minor version number in the lower 16 bits.
888 *******************************************************************************/
890 jint _Jv_JNI_GetVersion(JNIEnv *env)
892 TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
894 /* We support JNI 1.6. */
896 return JNI_VERSION_1_6;
900 /* Class Operations ***********************************************************/
902 /* DefineClass *****************************************************************
904 Loads a class from a buffer of raw class data. The buffer
905 containing the raw class data is not referenced by the VM after the
906 DefineClass call returns, and it may be discarded if desired.
908 *******************************************************************************/
910 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
911 const jbyte *buf, jsize bufLen)
913 #if defined(ENABLE_JAVASE)
919 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
921 u = utf_new_char(name);
922 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
924 c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
926 co = LLNI_classinfo_wrap(c);
928 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
930 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
932 /* keep compiler happy */
939 /* FindClass *******************************************************************
941 This function loads a locally-defined class. It searches the
942 directories and zip files specified by the CLASSPATH environment
943 variable for the class with the specified name.
945 *******************************************************************************/
947 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
949 #if defined(ENABLE_JAVASE)
956 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
958 u = utf_new_char_classname((char *) name);
960 /* Check stacktrace for classloader, if one found use it,
961 otherwise use the system classloader. */
963 /* Quote from the JNI documentation:
965 In the Java 2 Platform, FindClass locates the class loader
966 associated with the current native method. If the native code
967 belongs to a system class, no class loader will be
968 involved. Otherwise, the proper class loader will be invoked to
969 load and link the named class. When FindClass is called through
970 the Invocation Interface, there is no current native method or
971 its associated class loader. In that case, the result of
972 ClassLoader.getBaseClassLoader is used." */
974 cc = stacktrace_getCurrentClass();
977 c = load_class_from_sysloader(u);
979 c = load_class_from_classloader(u, cc->classloader);
987 co = LLNI_classinfo_wrap(c);
989 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
991 #elif defined(ENABLE_JAVAME_CLDC1_1)
996 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
998 u = utf_new_char_classname((char *) name);
999 c = load_class_bootstrap(u);
1007 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1010 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1012 /* keep compiler happy */
1019 /* GetSuperclass ***************************************************************
1021 If clazz represents any class other than the class Object, then
1022 this function returns the object that represents the superclass of
1023 the class specified by clazz.
1025 *******************************************************************************/
1027 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1031 java_lang_Class *co;
1033 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1035 c = LLNI_classinfo_unwrap(sub);
1040 super = class_get_superclass(c);
1042 co = LLNI_classinfo_wrap(super);
1044 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1048 /* IsAssignableFrom ************************************************************
1050 Determines whether an object of sub can be safely cast to sup.
1052 *******************************************************************************/
1054 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1056 java_lang_Class *csup;
1057 java_lang_Class *csub;
1059 csup = (java_lang_Class *) sup;
1060 csub = (java_lang_Class *) sub;
1062 STATISTICS(jniinvokation());
1064 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1068 /* Throw ***********************************************************************
1070 Causes a java.lang.Throwable object to be thrown.
1072 *******************************************************************************/
1074 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1078 STATISTICS(jniinvokation());
1080 o = (java_handle_t *) obj;
1082 exceptions_set_exception(o);
1088 /* ThrowNew ********************************************************************
1090 Constructs an exception object from the specified class with the
1091 message specified by message and causes that exception to be
1094 *******************************************************************************/
1096 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1102 STATISTICS(jniinvokation());
1104 c = LLNI_classinfo_unwrap(clazz);
1107 s = javastring_new_from_utf_string(msg);
1109 /* instantiate exception object */
1111 o = native_new_and_init_string(c, s);
1116 exceptions_set_exception(o);
1122 /* ExceptionOccurred ***********************************************************
1124 Determines if an exception is being thrown. The exception stays
1125 being thrown until either the native code calls ExceptionClear(),
1126 or the Java code handles the exception.
1128 *******************************************************************************/
1130 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1134 TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1136 o = exceptions_get_exception();
1138 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1142 /* ExceptionDescribe ***********************************************************
1144 Prints an exception and a backtrace of the stack to a system
1145 error-reporting channel, such as stderr. This is a convenience
1146 routine provided for debugging.
1148 *******************************************************************************/
1150 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1156 TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1158 /* Clear exception, because we are probably calling Java code
1161 o = exceptions_get_and_clear_exception();
1164 /* get printStackTrace method from exception class */
1166 LLNI_class_get(o, c);
1168 m = class_resolveclassmethod(c,
1169 utf_printStackTrace,
1175 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1177 /* Print the stacktrace. */
1179 (void) vm_call_method(m, o);
1184 /* ExceptionClear **************************************************************
1186 Clears any exception that is currently being thrown. If no
1187 exception is currently being thrown, this routine has no effect.
1189 *******************************************************************************/
1191 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1193 STATISTICS(jniinvokation());
1195 exceptions_clear_exception();
1199 /* FatalError ******************************************************************
1201 Raises a fatal error and does not expect the VM to recover. This
1202 function does not return.
1204 *******************************************************************************/
1206 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1208 STATISTICS(jniinvokation());
1210 /* this seems to be the best way */
1212 vm_abort("JNI Fatal error: %s", msg);
1216 /* PushLocalFrame **************************************************************
1218 Creates a new local reference frame, in which at least a given
1219 number of local references can be created.
1221 *******************************************************************************/
1223 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1225 STATISTICS(jniinvokation());
1230 /* add new local reference frame to current table */
1232 if (!localref_frame_push(capacity))
1239 /* PopLocalFrame ***************************************************************
1241 Pops off the current local reference frame, frees all the local
1242 references, and returns a local reference in the previous local
1243 reference frame for the given result object.
1245 *******************************************************************************/
1247 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1249 STATISTICS(jniinvokation());
1251 /* release all current local frames */
1253 localref_frame_pop_all();
1255 /* add local reference and return the value */
1257 return _Jv_JNI_NewLocalRef(env, result);
1261 /* DeleteLocalRef **************************************************************
1263 Deletes the local reference pointed to by localRef.
1265 *******************************************************************************/
1267 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1271 STATISTICS(jniinvokation());
1273 o = (java_handle_t *) localRef;
1275 /* delete the reference */
1281 /* IsSameObject ****************************************************************
1283 Tests whether two references refer to the same Java object.
1285 *******************************************************************************/
1287 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1293 STATISTICS(jniinvokation());
1295 o1 = (java_handle_t *) ref1;
1296 o2 = (java_handle_t *) ref2;
1298 LLNI_CRITICAL_START;
1300 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1311 /* NewLocalRef *****************************************************************
1313 Creates a new local reference that refers to the same object as ref.
1315 *******************************************************************************/
1317 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1320 java_handle_t *localref;
1322 STATISTICS(jniinvokation());
1327 o = (java_handle_t *) ref;
1329 /* insert the reference */
1331 localref = localref_add(LLNI_DIRECT(o));
1337 /* EnsureLocalCapacity *********************************************************
1339 Ensures that at least a given number of local references can be
1340 created in the current thread
1342 *******************************************************************************/
1344 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1346 localref_table *lrt;
1348 STATISTICS(jniinvokation());
1350 /* get local reference table (thread specific) */
1352 lrt = LOCALREFTABLE;
1354 /* check if capacity elements are available in the local references table */
1356 if ((lrt->used + capacity) > lrt->capacity)
1357 return _Jv_JNI_PushLocalFrame(env, capacity);
1363 /* AllocObject *****************************************************************
1365 Allocates a new Java object without invoking any of the
1366 constructors for the object. Returns a reference to the object.
1368 *******************************************************************************/
1370 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1375 STATISTICS(jniinvokation());
1377 c = LLNI_classinfo_unwrap(clazz);
1379 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1380 exceptions_throw_instantiationexception(c);
1386 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1390 /* NewObject *******************************************************************
1392 Programmers place all arguments that are to be passed to the
1393 constructor immediately following the methodID
1394 argument. NewObject() accepts these arguments and passes them to
1395 the Java method that the programmer wishes to invoke.
1397 *******************************************************************************/
1399 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1406 STATISTICS(jniinvokation());
1408 c = LLNI_classinfo_unwrap(clazz);
1409 m = (methodinfo *) methodID;
1418 /* call constructor */
1420 va_start(ap, methodID);
1421 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1424 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1428 /* NewObjectV ******************************************************************
1430 Programmers place all arguments that are to be passed to the
1431 constructor in an args argument of type va_list that immediately
1432 follows the methodID argument. NewObjectV() accepts these
1433 arguments, and, in turn, passes them to the Java method that the
1434 programmer wishes to invoke.
1436 *******************************************************************************/
1438 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1445 STATISTICS(jniinvokation());
1447 c = LLNI_classinfo_unwrap(clazz);
1448 m = (methodinfo *) methodID;
1457 /* call constructor */
1459 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1461 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1465 /* NewObjectA *****************************************************************
1467 Programmers place all arguments that are to be passed to the
1468 constructor in an args array of jvalues that immediately follows
1469 the methodID argument. NewObjectA() accepts the arguments in this
1470 array, and, in turn, passes them to the Java method that the
1471 programmer wishes to invoke.
1473 *******************************************************************************/
1475 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1482 STATISTICS(jniinvokation());
1484 c = LLNI_classinfo_unwrap(clazz);
1485 m = (methodinfo *) methodID;
1494 /* call constructor */
1496 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1498 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1502 /* GetObjectClass **************************************************************
1504 Returns the class of an object.
1506 *******************************************************************************/
1508 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1512 java_lang_Class *co;
1514 STATISTICS(jniinvokation());
1516 o = (java_handle_t *) obj;
1518 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1521 LLNI_class_get(o, c);
1523 co = LLNI_classinfo_wrap(c);
1525 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1529 /* IsInstanceOf ****************************************************************
1531 Tests whether an object is an instance of a class.
1533 *******************************************************************************/
1535 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1538 java_lang_Object *o;
1540 STATISTICS(jniinvokation());
1542 c = (java_lang_Class *) clazz;
1543 o = (java_lang_Object *) obj;
1545 return _Jv_java_lang_Class_isInstance(c, o);
1549 /* Reflection Support *********************************************************/
1551 /* FromReflectedMethod *********************************************************
1553 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1554 object to a method ID.
1556 *******************************************************************************/
1558 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1560 #if defined(ENABLE_JAVASE)
1566 STATISTICS(jniinvokation());
1568 o = (java_handle_t *) method;
1573 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1574 java_lang_reflect_Method *rm;
1576 rm = (java_lang_reflect_Method *) method;
1577 LLNI_field_get_cls(rm, clazz, c);
1578 LLNI_field_get_val(rm, slot , slot);
1580 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1581 java_lang_reflect_Constructor *rc;
1583 rc = (java_lang_reflect_Constructor *) method;
1584 LLNI_field_get_cls(rc, clazz, c);
1585 LLNI_field_get_val(rc, slot , slot);
1590 m = &(c->methods[slot]);
1592 return (jmethodID) m;
1594 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1596 /* keep compiler happy */
1603 /* FromReflectedField **********************************************************
1605 Converts a java.lang.reflect.Field to a field ID.
1607 *******************************************************************************/
1609 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1611 #if defined(ENABLE_JAVASE)
1612 java_lang_reflect_Field *rf;
1617 STATISTICS(jniinvokation());
1619 rf = (java_lang_reflect_Field *) field;
1624 LLNI_field_get_cls(rf, clazz, c);
1625 LLNI_field_get_val(rf, slot , slot);
1626 f = &(c->fields[slot]);
1628 return (jfieldID) f;
1630 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1632 /* keep compiler happy */
1639 /* ToReflectedMethod ***********************************************************
1641 Converts a method ID derived from cls to an instance of the
1642 java.lang.reflect.Method class or to an instance of the
1643 java.lang.reflect.Constructor class.
1645 *******************************************************************************/
1647 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1650 #if defined(ENABLE_JAVASE)
1652 java_lang_reflect_Constructor *rc;
1653 java_lang_reflect_Method *rm;
1655 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1657 m = (methodinfo *) methodID;
1659 /* HotSpot does the same assert. */
1661 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1663 if (m->name == utf_init) {
1664 rc = reflect_constructor_new(m);
1666 return (jobject) rc;
1669 rm = reflect_method_new(m);
1671 return (jobject) rm;
1674 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1676 /* keep compiler happy */
1683 /* ToReflectedField ************************************************************
1685 Converts a field ID derived from cls to an instance of the
1686 java.lang.reflect.Field class.
1688 *******************************************************************************/
1690 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1693 STATISTICS(jniinvokation());
1695 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1701 /* Calling Instance Methods ***************************************************/
1703 /* GetMethodID *****************************************************************
1705 Returns the method ID for an instance (nonstatic) method of a class
1706 or interface. The method may be defined in one of the clazz's
1707 superclasses and inherited by clazz. The method is determined by
1708 its name and signature.
1710 GetMethodID() causes an uninitialized class to be initialized.
1712 *******************************************************************************/
1714 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1722 STATISTICS(jniinvokation());
1724 c = LLNI_classinfo_unwrap(clazz);
1729 if (!(c->state & CLASS_INITIALIZED))
1730 if (!initialize_class(c))
1733 /* try to get the method of the class or one of it's superclasses */
1735 uname = utf_new_char((char *) name);
1736 udesc = utf_new_char((char *) sig);
1738 m = class_resolvemethod(c, uname, udesc);
1740 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1741 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1746 return (jmethodID) m;
1750 /* JNI-functions for calling instance methods *********************************/
1752 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1753 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1754 jmethodID methodID, ...) \
1761 o = (java_handle_t *) obj; \
1762 m = (methodinfo *) methodID; \
1764 va_start(ap, methodID); \
1765 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1771 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1772 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1773 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1774 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1775 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1776 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1777 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1778 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1781 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1782 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1783 jmethodID methodID, va_list args) \
1789 o = (java_handle_t *) obj; \
1790 m = (methodinfo *) methodID; \
1792 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1797 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1798 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1799 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1800 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1801 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1802 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1803 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1804 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1807 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1808 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1809 jmethodID methodID, \
1810 const jvalue *args) \
1816 o = (java_handle_t *) obj; \
1817 m = (methodinfo *) methodID; \
1819 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1824 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1825 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1826 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1827 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1828 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1829 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1830 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1831 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1834 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1842 o = (java_handle_t *) obj;
1843 m = (methodinfo *) methodID;
1845 va_start(ap, methodID);
1846 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1849 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1853 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1860 o = (java_handle_t *) obj;
1861 m = (methodinfo *) methodID;
1863 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1865 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1869 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1876 o = (java_handle_t *) obj;
1877 m = (methodinfo *) methodID;
1879 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1881 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1886 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1892 o = (java_handle_t *) obj;
1893 m = (methodinfo *) methodID;
1895 va_start(ap, methodID);
1896 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1901 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1907 o = (java_handle_t *) obj;
1908 m = (methodinfo *) methodID;
1910 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1914 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1920 o = (java_handle_t *) obj;
1921 m = (methodinfo *) methodID;
1923 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1928 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1929 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1930 jclass clazz, jmethodID methodID, \
1939 o = (java_handle_t *) obj; \
1940 c = LLNI_classinfo_unwrap(clazz); \
1941 m = (methodinfo *) methodID; \
1943 va_start(ap, methodID); \
1944 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1950 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1951 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1952 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1953 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1954 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1955 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1956 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1957 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1960 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1961 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1962 jclass clazz, jmethodID methodID, \
1970 o = (java_handle_t *) obj; \
1971 c = LLNI_classinfo_unwrap(clazz); \
1972 m = (methodinfo *) methodID; \
1974 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1979 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1980 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1983 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1984 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1985 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1986 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1989 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1990 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1991 jclass clazz, jmethodID methodID, \
1992 const jvalue *args) \
1994 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1999 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2000 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2001 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2002 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2003 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2004 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2005 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2006 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2008 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2009 jclass clazz, jmethodID methodID,
2018 o = (java_handle_t *) obj;
2019 c = LLNI_classinfo_unwrap(clazz);
2020 m = (methodinfo *) methodID;
2022 va_start(ap, methodID);
2023 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2026 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2030 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2031 jclass clazz, jmethodID methodID,
2039 o = (java_handle_t *) obj;
2040 c = LLNI_classinfo_unwrap(clazz);
2041 m = (methodinfo *) methodID;
2043 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2045 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2049 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2050 jclass clazz, jmethodID methodID,
2053 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2055 return _Jv_JNI_NewLocalRef(env, NULL);
2059 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2060 jmethodID methodID, ...)
2067 o = (java_handle_t *) obj;
2068 c = LLNI_classinfo_unwrap(clazz);
2069 m = (methodinfo *) methodID;
2071 va_start(ap, methodID);
2072 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2077 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2078 jmethodID methodID, va_list args)
2084 o = (java_handle_t *) obj;
2085 c = LLNI_classinfo_unwrap(clazz);
2086 m = (methodinfo *) methodID;
2088 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2092 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2093 jmethodID methodID, const jvalue * args)
2099 o = (java_handle_t *) obj;
2100 c = LLNI_classinfo_unwrap(clazz);
2101 m = (methodinfo *) methodID;
2103 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2107 /* Accessing Fields of Objects ************************************************/
2109 /* GetFieldID ******************************************************************
2111 Returns the field ID for an instance (nonstatic) field of a
2112 class. The field is specified by its name and signature. The
2113 Get<type>Field and Set<type>Field families of accessor functions
2114 use field IDs to retrieve object fields.
2116 *******************************************************************************/
2118 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2126 STATISTICS(jniinvokation());
2128 c = LLNI_classinfo_unwrap(clazz);
2130 /* XXX NPE check? */
2132 uname = utf_new_char((char *) name);
2133 udesc = utf_new_char((char *) sig);
2135 f = class_findfield(c, uname, udesc);
2138 exceptions_throw_nosuchfielderror(c, uname);
2140 return (jfieldID) f;
2144 /* Get<type>Field Routines *****************************************************
2146 This family of accessor routines returns the value of an instance
2147 (nonstatic) field of an object. The field to access is specified by
2148 a field ID obtained by calling GetFieldID().
2150 *******************************************************************************/
2152 #define JNI_GET_FIELD(name, type, intern) \
2153 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2157 STATISTICS(jniinvokation()); \
2159 ret = GET_FIELD(obj, intern, fieldID); \
2161 return (type) ret; \
2164 JNI_GET_FIELD(Boolean, jboolean, s4)
2165 JNI_GET_FIELD(Byte, jbyte, s4)
2166 JNI_GET_FIELD(Char, jchar, s4)
2167 JNI_GET_FIELD(Short, jshort, s4)
2168 JNI_GET_FIELD(Int, jint, s4)
2169 JNI_GET_FIELD(Long, jlong, s8)
2170 JNI_GET_FIELD(Float, jfloat, float)
2171 JNI_GET_FIELD(Double, jdouble, double)
2174 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2178 TRACEJNICALLS("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID);
2180 LLNI_CRITICAL_START;
2182 o = LLNI_WRAP(GET_FIELD(obj, java_handle_t*, fieldID));
2186 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2190 /* Set<type>Field Routines *****************************************************
2192 This family of accessor routines sets the value of an instance
2193 (nonstatic) field of an object. The field to access is specified by
2194 a field ID obtained by calling GetFieldID().
2196 *******************************************************************************/
2198 #define JNI_SET_FIELD(name, type, intern) \
2199 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2202 STATISTICS(jniinvokation()); \
2204 SET_FIELD(obj, intern, fieldID, value); \
2207 JNI_SET_FIELD(Boolean, jboolean, s4)
2208 JNI_SET_FIELD(Byte, jbyte, s4)
2209 JNI_SET_FIELD(Char, jchar, s4)
2210 JNI_SET_FIELD(Short, jshort, s4)
2211 JNI_SET_FIELD(Int, jint, s4)
2212 JNI_SET_FIELD(Long, jlong, s8)
2213 JNI_SET_FIELD(Float, jfloat, float)
2214 JNI_SET_FIELD(Double, jdouble, double)
2217 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2220 TRACEJNICALLS("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value);
2222 LLNI_CRITICAL_START;
2224 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP(value));
2230 /* Calling Static Methods *****************************************************/
2232 /* GetStaticMethodID ***********************************************************
2234 Returns the method ID for a static method of a class. The method is
2235 specified by its name and signature.
2237 GetStaticMethodID() causes an uninitialized class to be
2240 *******************************************************************************/
2242 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2250 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2252 c = LLNI_classinfo_unwrap(clazz);
2257 if (!(c->state & CLASS_INITIALIZED))
2258 if (!initialize_class(c))
2261 /* try to get the static method of the class */
2263 uname = utf_new_char((char *) name);
2264 udesc = utf_new_char((char *) sig);
2266 m = class_resolvemethod(c, uname, udesc);
2268 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2269 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2274 return (jmethodID) m;
2278 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2279 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2280 jmethodID methodID, ...) \
2286 m = (methodinfo *) methodID; \
2288 va_start(ap, methodID); \
2289 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2295 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2296 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2297 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2298 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2299 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2300 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2301 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2302 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2305 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2306 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2307 jmethodID methodID, va_list args) \
2312 m = (methodinfo *) methodID; \
2314 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2319 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2320 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2321 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2322 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2323 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2324 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2325 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2326 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2329 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2330 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2331 jmethodID methodID, const jvalue *args) \
2336 m = (methodinfo *) methodID; \
2338 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2343 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2344 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2345 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2346 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2347 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2348 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2349 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2350 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2353 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2354 jmethodID methodID, ...)
2360 m = (methodinfo *) methodID;
2362 va_start(ap, methodID);
2363 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2366 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2370 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2371 jmethodID methodID, va_list args)
2376 m = (methodinfo *) methodID;
2378 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2380 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2384 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2385 jmethodID methodID, const jvalue *args)
2390 m = (methodinfo *) methodID;
2392 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2394 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2398 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2399 jmethodID methodID, ...)
2404 m = (methodinfo *) methodID;
2406 va_start(ap, methodID);
2407 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2412 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2413 jmethodID methodID, va_list args)
2417 m = (methodinfo *) methodID;
2419 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2423 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2424 jmethodID methodID, const jvalue * args)
2428 m = (methodinfo *) methodID;
2430 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2434 /* Accessing Static Fields ****************************************************/
2436 /* GetStaticFieldID ************************************************************
2438 Returns the field ID for a static field of a class. The field is
2439 specified by its name and signature. The GetStatic<type>Field and
2440 SetStatic<type>Field families of accessor functions use field IDs
2441 to retrieve static fields.
2443 *******************************************************************************/
2445 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2453 STATISTICS(jniinvokation());
2455 c = LLNI_classinfo_unwrap(clazz);
2457 uname = utf_new_char((char *) name);
2458 usig = utf_new_char((char *) sig);
2460 f = class_findfield(c, uname, usig);
2463 exceptions_throw_nosuchfielderror(c, uname);
2465 return (jfieldID) f;
2469 /* GetStatic<type>Field ********************************************************
2471 This family of accessor routines returns the value of a static
2474 *******************************************************************************/
2476 #define JNI_GET_STATIC_FIELD(name, type, field) \
2477 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2483 STATISTICS(jniinvokation()); \
2485 c = LLNI_classinfo_unwrap(clazz); \
2486 f = (fieldinfo *) fieldID; \
2488 if (!(c->state & CLASS_INITIALIZED)) \
2489 if (!initialize_class(c)) \
2492 return f->value->field; \
2495 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2496 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2497 JNI_GET_STATIC_FIELD(Char, jchar, i)
2498 JNI_GET_STATIC_FIELD(Short, jshort, i)
2499 JNI_GET_STATIC_FIELD(Int, jint, i)
2500 JNI_GET_STATIC_FIELD(Long, jlong, l)
2501 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2502 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2505 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2511 STATISTICS(jniinvokation());
2513 c = LLNI_classinfo_unwrap(clazz);
2514 f = (fieldinfo *) fieldID;
2516 if (!(c->state & CLASS_INITIALIZED))
2517 if (!initialize_class(c))
2520 return _Jv_JNI_NewLocalRef(env, f->value->a);
2524 /* SetStatic<type>Field *******************************************************
2526 This family of accessor routines sets the value of a static field
2529 *******************************************************************************/
2531 #define JNI_SET_STATIC_FIELD(name, type, field) \
2532 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2539 STATISTICS(jniinvokation()); \
2541 c = LLNI_classinfo_unwrap(clazz); \
2542 f = (fieldinfo *) fieldID; \
2544 if (!(c->state & CLASS_INITIALIZED)) \
2545 if (!initialize_class(c)) \
2548 f->value->field = value; \
2551 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2552 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2553 JNI_SET_STATIC_FIELD(Char, jchar, i)
2554 JNI_SET_STATIC_FIELD(Short, jshort, i)
2555 JNI_SET_STATIC_FIELD(Int, jint, i)
2556 JNI_SET_STATIC_FIELD(Long, jlong, l)
2557 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2558 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2561 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2567 STATISTICS(jniinvokation());
2569 c = LLNI_classinfo_unwrap(clazz);
2570 f = (fieldinfo *) fieldID;
2572 if (!(c->state & CLASS_INITIALIZED))
2573 if (!initialize_class(c))
2576 f->value->a = value;
2580 /* String Operations **********************************************************/
2582 /* NewString *******************************************************************
2584 Create new java.lang.String object from an array of Unicode
2587 *******************************************************************************/
2589 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2591 java_lang_String *s;
2592 java_handle_chararray_t *a;
2595 STATISTICS(jniinvokation());
2597 s = (java_lang_String *) builtin_new(class_java_lang_String);
2598 a = builtin_newarray_char(len);
2600 /* javastring or characterarray could not be created */
2601 if ((a == NULL) || (s == NULL))
2605 for (i = 0; i < len; i++)
2606 LLNI_array_direct(a, i) = buf[i];
2608 LLNI_field_set_ref(s, value , a);
2609 LLNI_field_set_val(s, offset, 0);
2610 LLNI_field_set_val(s, count , len);
2612 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2616 static jchar emptyStringJ[]={0,0};
2618 /* GetStringLength *************************************************************
2620 Returns the length (the count of Unicode characters) of a Java
2623 *******************************************************************************/
2625 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2627 java_lang_String *s;
2630 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2632 s = (java_lang_String *) str;
2634 LLNI_field_get_val(s, count, len);
2640 /******************** convertes javastring to u2-array ****************************/
2642 u2 *javastring_tou2(jstring so)
2644 java_lang_String *s;
2645 java_handle_chararray_t *a;
2651 STATISTICS(jniinvokation());
2653 s = (java_lang_String *) so;
2658 LLNI_field_get_ref(s, value, a);
2663 LLNI_field_get_val(s, count, count);
2664 LLNI_field_get_val(s, offset, offset);
2666 /* allocate memory */
2668 stringbuffer = MNEW(u2, count + 1);
2672 for (i = 0; i < count; i++)
2673 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2675 /* terminate string */
2677 stringbuffer[i] = '\0';
2679 return stringbuffer;
2683 /* GetStringChars **************************************************************
2685 Returns a pointer to the array of Unicode characters of the
2686 string. This pointer is valid until ReleaseStringChars() is called.
2688 *******************************************************************************/
2690 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2694 STATISTICS(jniinvokation());
2696 jc = javastring_tou2(str);
2708 return emptyStringJ;
2712 /* ReleaseStringChars **********************************************************
2714 Informs the VM that the native code no longer needs access to
2715 chars. The chars argument is a pointer obtained from string using
2718 *******************************************************************************/
2720 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2722 java_lang_String *s;
2724 STATISTICS(jniinvokation());
2726 if (chars == emptyStringJ)
2729 s = (java_lang_String *) str;
2731 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2735 /* NewStringUTF ****************************************************************
2737 Constructs a new java.lang.String object from an array of UTF-8
2740 *******************************************************************************/
2742 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2744 java_lang_String *s;
2746 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2748 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2750 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2754 /****************** returns the utf8 length in bytes of a string *******************/
2756 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2758 java_lang_String *s;
2761 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2763 s = (java_lang_String *) string;
2765 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2771 /* GetStringUTFChars ***********************************************************
2773 Returns a pointer to an array of UTF-8 characters of the
2774 string. This array is valid until it is released by
2775 ReleaseStringUTFChars().
2777 *******************************************************************************/
2779 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2784 STATISTICS(jniinvokation());
2792 u = javastring_toutf((java_handle_t *) string, false);
2801 /* ReleaseStringUTFChars *******************************************************
2803 Informs the VM that the native code no longer needs access to
2804 utf. The utf argument is a pointer derived from string using
2805 GetStringUTFChars().
2807 *******************************************************************************/
2809 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2811 STATISTICS(jniinvokation());
2813 /* XXX we don't release utf chars right now, perhaps that should be done
2814 later. Since there is always one reference the garbage collector will
2819 /* Array Operations ***********************************************************/
2821 /* GetArrayLength **************************************************************
2823 Returns the number of elements in the array.
2825 *******************************************************************************/
2827 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2832 STATISTICS(jniinvokation());
2834 a = (java_handle_t *) array;
2836 size = LLNI_array_size(a);
2842 /* NewObjectArray **************************************************************
2844 Constructs a new array holding objects in class elementClass. All
2845 elements are initially set to initialElement.
2847 *******************************************************************************/
2849 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2850 jclass elementClass, jobject initialElement)
2854 java_handle_objectarray_t *oa;
2857 STATISTICS(jniinvokation());
2859 c = LLNI_classinfo_unwrap(elementClass);
2860 o = (java_handle_t *) initialElement;
2863 exceptions_throw_negativearraysizeexception();
2867 oa = builtin_anewarray(length, c);
2872 /* set all elements to initialElement */
2874 for (i = 0; i < length; i++)
2875 LLNI_objectarray_element_set(oa, i, o);
2877 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2881 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2884 java_handle_objectarray_t *oa;
2887 STATISTICS(jniinvokation());
2889 oa = (java_handle_objectarray_t *) array;
2891 if (index >= LLNI_array_size(oa)) {
2892 exceptions_throw_arrayindexoutofboundsexception();
2896 LLNI_objectarray_element_get(oa, index, o);
2898 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2902 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2903 jsize index, jobject val)
2905 java_handle_objectarray_t *oa;
2908 STATISTICS(jniinvokation());
2910 oa = (java_handle_objectarray_t *) array;
2911 o = (java_handle_t *) val;
2913 if (index >= LLNI_array_size(oa)) {
2914 exceptions_throw_arrayindexoutofboundsexception();
2918 /* check if the class of value is a subclass of the element class
2921 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2924 LLNI_objectarray_element_set(oa, index, o);
2928 #define JNI_NEW_ARRAY(name, type, intern) \
2929 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2931 java_handle_##intern##array_t *a; \
2933 STATISTICS(jniinvokation()); \
2936 exceptions_throw_negativearraysizeexception(); \
2940 a = builtin_newarray_##intern(len); \
2942 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2945 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2946 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2947 JNI_NEW_ARRAY(Char, jcharArray, char)
2948 JNI_NEW_ARRAY(Short, jshortArray, byte)
2949 JNI_NEW_ARRAY(Int, jintArray, int)
2950 JNI_NEW_ARRAY(Long, jlongArray, long)
2951 JNI_NEW_ARRAY(Float, jfloatArray, float)
2952 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2955 /* Get<PrimitiveType>ArrayElements *********************************************
2957 A family of functions that returns the body of the primitive array.
2959 *******************************************************************************/
2961 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2962 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2965 java_handle_##intern##array_t *a; \
2967 STATISTICS(jniinvokation()); \
2969 a = (java_handle_##intern##array_t *) array; \
2972 *isCopy = JNI_FALSE; \
2974 return LLNI_array_data(a); \
2977 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2978 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2979 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2980 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2981 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2982 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2983 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2984 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2987 /* Release<PrimitiveType>ArrayElements *****************************************
2989 A family of functions that informs the VM that the native code no
2990 longer needs access to elems. The elems argument is a pointer
2991 derived from array using the corresponding
2992 Get<PrimitiveType>ArrayElements() function. If necessary, this
2993 function copies back all changes made to elems to the original
2996 *******************************************************************************/
2998 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2999 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3000 type *elems, jint mode) \
3002 java_handle_##intern##array_t *a; \
3004 STATISTICS(jniinvokation()); \
3006 a = (java_handle_##intern##array_t *) array; \
3008 if (elems != LLNI_array_data(a)) { \
3011 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3014 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3015 /* XXX TWISTI how should it be freed? */ \
3018 /* XXX TWISTI how should it be freed? */ \
3024 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3025 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3026 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3027 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3028 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3029 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3030 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3031 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3034 /* Get<PrimitiveType>ArrayRegion **********************************************
3036 A family of functions that copies a region of a primitive array
3039 *******************************************************************************/
3041 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3042 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3043 jsize start, jsize len, type *buf) \
3045 java_handle_##intern##array_t *a; \
3047 STATISTICS(jniinvokation()); \
3049 a = (java_handle_##intern##array_t *) array; \
3051 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3052 exceptions_throw_arrayindexoutofboundsexception(); \
3054 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3057 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3058 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3059 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3060 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3061 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3062 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3063 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3064 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3067 /* Set<PrimitiveType>ArrayRegion **********************************************
3069 A family of functions that copies back a region of a primitive
3070 array from a buffer.
3072 *******************************************************************************/
3074 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3075 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3076 jsize start, jsize len, const type *buf) \
3078 java_handle_##intern##array_t *a; \
3080 STATISTICS(jniinvokation()); \
3082 a = (java_handle_##intern##array_t *) array; \
3084 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3085 exceptions_throw_arrayindexoutofboundsexception(); \
3087 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3090 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3091 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3092 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3093 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3094 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3095 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3096 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3097 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3100 /* Registering Native Methods *************************************************/
3102 /* RegisterNatives *************************************************************
3104 Registers native methods with the class specified by the clazz
3105 argument. The methods parameter specifies an array of
3106 JNINativeMethod structures that contain the names, signatures, and
3107 function pointers of the native methods. The nMethods parameter
3108 specifies the number of native methods in the array.
3110 *******************************************************************************/
3112 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3113 const JNINativeMethod *methods, jint nMethods)
3117 STATISTICS(jniinvokation());
3119 c = LLNI_classinfo_unwrap(clazz);
3121 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3122 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3125 native_method_register(c->name, methods, nMethods);
3131 /* UnregisterNatives ***********************************************************
3133 Unregisters native methods of a class. The class goes back to the
3134 state before it was linked or registered with its native method
3137 This function should not be used in normal native code. Instead, it
3138 provides special programs a way to reload and relink native
3141 *******************************************************************************/
3143 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3145 STATISTICS(jniinvokation());
3147 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3149 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3155 /* Monitor Operations *********************************************************/
3157 /* MonitorEnter ****************************************************************
3159 Enters the monitor associated with the underlying Java object
3162 *******************************************************************************/
3164 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3166 STATISTICS(jniinvokation());
3169 exceptions_throw_nullpointerexception();
3173 LOCK_MONITOR_ENTER(obj);
3179 /* MonitorExit *****************************************************************
3181 The current thread must be the owner of the monitor associated with
3182 the underlying Java object referred to by obj. The thread
3183 decrements the counter indicating the number of times it has
3184 entered this monitor. If the value of the counter becomes zero, the
3185 current thread releases the monitor.
3187 *******************************************************************************/
3189 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3191 STATISTICS(jniinvokation());
3194 exceptions_throw_nullpointerexception();
3198 LOCK_MONITOR_EXIT(obj);
3204 /* JavaVM Interface ***********************************************************/
3206 /* GetJavaVM *******************************************************************
3208 Returns the Java VM interface (used in the Invocation API)
3209 associated with the current thread. The result is placed at the
3210 location pointed to by the second argument, vm.
3212 *******************************************************************************/
3214 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3216 STATISTICS(jniinvokation());
3218 *vm = (JavaVM *) _Jv_jvm;
3224 /* GetStringRegion *************************************************************
3226 Copies len number of Unicode characters beginning at offset start
3227 to the given buffer buf.
3229 Throws StringIndexOutOfBoundsException on index overflow.
3231 *******************************************************************************/
3233 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3236 java_lang_String *s;
3237 java_handle_chararray_t *ca;
3239 STATISTICS(jniinvokation());
3241 s = (java_lang_String *) str;
3242 LLNI_field_get_ref(s, value, ca);
3244 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3245 (start + len > LLNI_field_direct(s, count))) {
3246 exceptions_throw_stringindexoutofboundsexception();
3250 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3254 /* GetStringUTFRegion **********************************************************
3256 Translates len number of Unicode characters beginning at offset
3257 start into UTF-8 format and place the result in the given buffer
3260 Throws StringIndexOutOfBoundsException on index overflow.
3262 *******************************************************************************/
3264 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3265 jsize len, char *buf)
3267 java_lang_String *s;
3268 java_handle_chararray_t *ca;
3273 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3275 s = (java_lang_String *) str;
3276 LLNI_field_get_ref(s, value, ca);
3277 LLNI_field_get_val(s, count, count);
3278 LLNI_field_get_val(s, offset, offset);
3280 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3281 exceptions_throw_stringindexoutofboundsexception();
3285 for (i = 0; i < len; i++)
3286 buf[i] = LLNI_array_direct(ca, offset + start + i);
3292 /* GetPrimitiveArrayCritical ***************************************************
3294 Obtain a direct pointer to array elements.
3296 *******************************************************************************/
3298 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3301 java_handle_bytearray_t *ba;
3304 ba = (java_handle_bytearray_t *) array;
3306 /* do the same as Kaffe does */
3308 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3314 /* ReleasePrimitiveArrayCritical ***********************************************
3316 No specific documentation.
3318 *******************************************************************************/
3320 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3321 void *carray, jint mode)
3323 STATISTICS(jniinvokation());
3325 /* do the same as Kaffe does */
3327 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3332 /* GetStringCritical ***********************************************************
3334 The semantics of these two functions are similar to the existing
3335 Get/ReleaseStringChars functions.
3337 *******************************************************************************/
3339 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3342 STATISTICS(jniinvokation());
3344 return _Jv_JNI_GetStringChars(env, string, isCopy);
3348 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3349 const jchar *cstring)
3351 STATISTICS(jniinvokation());
3353 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3357 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3359 TRACEJNICALLS("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj);
3365 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3367 TRACEJNICALLS("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref);
3371 /* NewGlobalRef ****************************************************************
3373 Creates a new global reference to the object referred to by the obj
3376 *******************************************************************************/
3378 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3380 hashtable_global_ref_entry *gre;
3381 u4 key; /* hashkey */
3382 u4 slot; /* slot in hashtable */
3385 STATISTICS(jniinvokation());
3387 o = (java_handle_t *) obj;
3389 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3391 LLNI_CRITICAL_START;
3393 /* normally addresses are aligned to 4, 8 or 16 bytes */
3395 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3396 slot = key & (hashtable_global_ref->size - 1);
3397 gre = hashtable_global_ref->ptr[slot];
3399 /* search external hash chain for the entry */
3402 if (gre->o == LLNI_DIRECT(o)) {
3403 /* global object found, increment the reference */
3410 gre = gre->hashlink; /* next element in external chain */
3413 /* global ref not found, create a new one */
3416 gre = NEW(hashtable_global_ref_entry);
3418 #if defined(ENABLE_GC_CACAO)
3419 /* register global ref with the GC */
3421 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3424 gre->o = LLNI_DIRECT(o);
3427 /* insert entry into hashtable */
3429 gre->hashlink = hashtable_global_ref->ptr[slot];
3431 hashtable_global_ref->ptr[slot] = gre;
3433 /* update number of hashtable-entries */
3435 hashtable_global_ref->entries++;
3440 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3442 #if defined(ENABLE_HANDLES)
3450 /* DeleteGlobalRef *************************************************************
3452 Deletes the global reference pointed to by globalRef.
3454 *******************************************************************************/
3456 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3458 hashtable_global_ref_entry *gre;
3459 hashtable_global_ref_entry *prevgre;
3460 u4 key; /* hashkey */
3461 u4 slot; /* slot in hashtable */
3464 STATISTICS(jniinvokation());
3466 o = (java_handle_t *) globalRef;
3468 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3470 LLNI_CRITICAL_START;
3472 /* normally addresses are aligned to 4, 8 or 16 bytes */
3474 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3475 slot = key & (hashtable_global_ref->size - 1);
3476 gre = hashtable_global_ref->ptr[slot];
3478 /* initialize prevgre */
3482 /* search external hash chain for the entry */
3485 if (gre->o == LLNI_DIRECT(o)) {
3486 /* global object found, decrement the reference count */
3490 /* if reference count is 0, remove the entry */
3492 if (gre->refs == 0) {
3493 /* special handling if it's the first in the chain */
3495 if (prevgre == NULL)
3496 hashtable_global_ref->ptr[slot] = gre->hashlink;
3498 prevgre->hashlink = gre->hashlink;
3500 #if defined(ENABLE_GC_CACAO)
3501 /* unregister global ref with the GC */
3503 gc_reference_unregister(&(gre->o));
3506 FREE(gre, hashtable_global_ref_entry);
3511 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3516 prevgre = gre; /* save current pointer for removal */
3517 gre = gre->hashlink; /* next element in external chain */
3520 log_println("JNI-DeleteGlobalRef: global reference not found");
3524 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3528 /* ExceptionCheck **************************************************************
3530 Returns JNI_TRUE when there is a pending exception; otherwise,
3533 *******************************************************************************/
3535 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3539 STATISTICS(jniinvokation());
3541 o = exceptions_get_exception();
3543 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3547 /* New JNI 1.4 functions ******************************************************/
3549 /* NewDirectByteBuffer *********************************************************
3551 Allocates and returns a direct java.nio.ByteBuffer referring to the
3552 block of memory starting at the memory address address and
3553 extending capacity bytes.
3555 *******************************************************************************/
3557 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3559 #if defined(ENABLE_JAVASE)
3560 # if defined(WITH_CLASSPATH_GNU)
3561 java_handle_t *nbuf;
3563 # if SIZEOF_VOID_P == 8
3564 gnu_classpath_Pointer64 *paddress;
3566 gnu_classpath_Pointer32 *paddress;
3569 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3571 /* alocate a gnu.classpath.Pointer{32,64} object */
3573 # if SIZEOF_VOID_P == 8
3574 if (!(paddress = (gnu_classpath_Pointer64 *)
3575 builtin_new(class_gnu_classpath_Pointer64)))
3577 if (!(paddress = (gnu_classpath_Pointer32 *)
3578 builtin_new(class_gnu_classpath_Pointer32)))
3582 /* fill gnu.classpath.Pointer{32,64} with address */
3584 LLNI_field_set_val(paddress, data, (ptrint) address);
3586 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3588 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3589 (jmethodID) dbbirw_init, NULL, paddress,
3590 (jint) capacity, (jint) capacity, (jint) 0);
3592 /* add local reference and return the value */
3594 return _Jv_JNI_NewLocalRef(env, nbuf);
3596 # elif defined(WITH_CLASSPATH_SUN)
3602 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3604 /* Be paranoid about address sign-extension. */
3606 addr = (int64_t) ((uintptr_t) address);
3607 cap = (int32_t) capacity;
3609 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3610 (jmethodID) dbb_init, addr, cap);
3612 /* Add local reference and return the value. */
3614 return _Jv_JNI_NewLocalRef(env, o);
3617 # error unknown classpath configuration
3621 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3623 /* keep compiler happy */
3630 /* GetDirectBufferAddress ******************************************************
3632 Fetches and returns the starting address of the memory region
3633 referenced by the given direct java.nio.Buffer.
3635 *******************************************************************************/
3637 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3639 #if defined(ENABLE_JAVASE)
3640 # if defined(WITH_CLASSPATH_GNU)
3642 java_nio_DirectByteBufferImpl *nbuf;
3643 # if SIZEOF_VOID_P == 8
3644 gnu_classpath_Pointer64 *paddress;
3646 gnu_classpath_Pointer32 *paddress;
3650 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3652 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3655 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3657 # if SIZEOF_VOID_P == 8
3658 LLNI_field_get_ref(nbuf, address, paddress);
3659 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3661 LLNI_field_get_ref(nbuf, address, paddress);
3662 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3665 if (paddress == NULL)
3668 LLNI_field_get_val(paddress, data, address);
3669 /* this was the cast to avaoid warning: (void *) paddress->data */
3673 # elif defined(WITH_CLASSPATH_SUN)
3679 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3681 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3684 o = (java_nio_Buffer *) buf;
3686 LLNI_field_get_val(o, address, address);
3688 p = (void *) (intptr_t) address;
3693 # error unknown classpath configuration
3698 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3700 /* keep compiler happy */
3708 /* GetDirectBufferCapacity *****************************************************
3710 Fetches and returns the capacity in bytes of the memory region
3711 referenced by the given direct java.nio.Buffer.
3713 *******************************************************************************/
3715 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3717 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3719 java_nio_Buffer *nbuf;
3722 STATISTICS(jniinvokation());
3724 o = (java_handle_t *) buf;
3726 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3729 nbuf = (java_nio_Buffer *) o;
3731 LLNI_field_get_val(nbuf, cap, capacity);
3735 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3737 /* keep compiler happy */
3744 /* GetObjectRefType ************************************************************
3746 Returns the type of the object referred to by the obj argument. The
3747 argument obj can either be a local, global or weak global
3750 *******************************************************************************/
3752 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3754 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3760 /* DestroyJavaVM ***************************************************************
3762 Unloads a Java VM and reclaims its resources. Only the main thread
3763 can unload the VM. The system waits until the main thread is only
3764 remaining user thread before it destroys the VM.
3766 *******************************************************************************/
3768 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3772 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3774 status = vm_destroy(vm);
3780 /* AttachCurrentThread *********************************************************
3782 Attaches the current thread to a Java VM. Returns a JNI interface
3783 pointer in the JNIEnv argument.
3785 Trying to attach a thread that is already attached is a no-op.
3787 A native thread cannot be attached simultaneously to two Java VMs.
3789 When a thread is attached to the VM, the context class loader is
3790 the bootstrap loader.
3792 *******************************************************************************/
3794 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3796 JavaVMAttachArgs *vm_aargs;
3798 #if defined(ENABLE_THREADS)
3799 if (threads_get_current_threadobject() == NULL) {
3800 vm_aargs = (JavaVMAttachArgs *) thr_args;
3802 if (vm_aargs != NULL) {
3803 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3804 (vm_aargs->version != JNI_VERSION_1_4))
3805 return JNI_EVERSION;
3808 if (!threads_attach_current_thread(vm_aargs, false))
3811 if (!localref_table_init())
3822 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3824 STATISTICS(jniinvokation());
3826 return jni_attach_current_thread(p_env, thr_args, false);
3830 /* DetachCurrentThread *********************************************************
3832 Detaches the current thread from a Java VM. All Java monitors held
3833 by this thread are released. All Java threads waiting for this
3834 thread to die are notified.
3836 In JDK 1.1, the main thread cannot be detached from the VM. It must
3837 call DestroyJavaVM to unload the entire VM.
3839 In the JDK, the main thread can be detached from the VM.
3841 The main thread, which is the thread that created the Java VM,
3842 cannot be detached from the VM. Instead, the main thread must call
3843 JNI_DestroyJavaVM() to unload the entire VM.
3845 *******************************************************************************/
3847 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3849 #if defined(ENABLE_THREADS)
3850 threadobject *thread;
3852 STATISTICS(jniinvokation());
3854 thread = threads_get_current_threadobject();
3859 /* We need to pop all frames before we can destroy the table. */
3861 localref_frame_pop_all();
3863 if (!localref_table_destroy())
3866 if (!threads_detach_thread(thread))
3874 /* GetEnv **********************************************************************
3876 If the current thread is not attached to the VM, sets *env to NULL,
3877 and returns JNI_EDETACHED. If the specified version is not
3878 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3879 sets *env to the appropriate interface, and returns JNI_OK.
3881 *******************************************************************************/
3883 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3885 TRACEJNICALLS("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version);
3887 #if defined(ENABLE_THREADS)
3888 if (threads_get_current_threadobject() == NULL) {
3891 return JNI_EDETACHED;
3895 /* Check the JNI version. */
3897 if (jni_version_check(version) == true) {
3902 #if defined(ENABLE_JVMTI)
3903 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3904 == JVMTI_VERSION_INTERFACE_JVMTI) {
3906 *env = (void *) jvmti_new_environment();
3915 return JNI_EVERSION;
3919 /* AttachCurrentThreadAsDaemon *************************************************
3921 Same semantics as AttachCurrentThread, but the newly-created
3922 java.lang.Thread instance is a daemon.
3924 If the thread has already been attached via either
3925 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3926 simply sets the value pointed to by penv to the JNIEnv of the
3927 current thread. In this case neither AttachCurrentThread nor this
3928 routine have any effect on the daemon status of the thread.
3930 *******************************************************************************/
3932 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3934 STATISTICS(jniinvokation());
3936 return jni_attach_current_thread(penv, args, true);
3940 /* JNI invocation table *******************************************************/
3942 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3947 _Jv_JNI_DestroyJavaVM,
3948 _Jv_JNI_AttachCurrentThread,
3949 _Jv_JNI_DetachCurrentThread,
3951 _Jv_JNI_AttachCurrentThreadAsDaemon
3955 /* JNI function table *********************************************************/
3957 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3964 _Jv_JNI_DefineClass,
3966 _Jv_JNI_FromReflectedMethod,
3967 _Jv_JNI_FromReflectedField,
3968 _Jv_JNI_ToReflectedMethod,
3969 _Jv_JNI_GetSuperclass,
3970 _Jv_JNI_IsAssignableFrom,
3971 _Jv_JNI_ToReflectedField,
3975 _Jv_JNI_ExceptionOccurred,
3976 _Jv_JNI_ExceptionDescribe,
3977 _Jv_JNI_ExceptionClear,
3979 _Jv_JNI_PushLocalFrame,
3980 _Jv_JNI_PopLocalFrame,
3982 _Jv_JNI_NewGlobalRef,
3983 _Jv_JNI_DeleteGlobalRef,
3984 _Jv_JNI_DeleteLocalRef,
3985 _Jv_JNI_IsSameObject,
3986 _Jv_JNI_NewLocalRef,
3987 _Jv_JNI_EnsureLocalCapacity,
3989 _Jv_JNI_AllocObject,
3994 _Jv_JNI_GetObjectClass,
3995 _Jv_JNI_IsInstanceOf,
3997 _Jv_JNI_GetMethodID,
3999 _Jv_JNI_CallObjectMethod,
4000 _Jv_JNI_CallObjectMethodV,
4001 _Jv_JNI_CallObjectMethodA,
4002 _Jv_JNI_CallBooleanMethod,
4003 _Jv_JNI_CallBooleanMethodV,
4004 _Jv_JNI_CallBooleanMethodA,
4005 _Jv_JNI_CallByteMethod,
4006 _Jv_JNI_CallByteMethodV,
4007 _Jv_JNI_CallByteMethodA,
4008 _Jv_JNI_CallCharMethod,
4009 _Jv_JNI_CallCharMethodV,
4010 _Jv_JNI_CallCharMethodA,
4011 _Jv_JNI_CallShortMethod,
4012 _Jv_JNI_CallShortMethodV,
4013 _Jv_JNI_CallShortMethodA,
4014 _Jv_JNI_CallIntMethod,
4015 _Jv_JNI_CallIntMethodV,
4016 _Jv_JNI_CallIntMethodA,
4017 _Jv_JNI_CallLongMethod,
4018 _Jv_JNI_CallLongMethodV,
4019 _Jv_JNI_CallLongMethodA,
4020 _Jv_JNI_CallFloatMethod,
4021 _Jv_JNI_CallFloatMethodV,
4022 _Jv_JNI_CallFloatMethodA,
4023 _Jv_JNI_CallDoubleMethod,
4024 _Jv_JNI_CallDoubleMethodV,
4025 _Jv_JNI_CallDoubleMethodA,
4026 _Jv_JNI_CallVoidMethod,
4027 _Jv_JNI_CallVoidMethodV,
4028 _Jv_JNI_CallVoidMethodA,
4030 _Jv_JNI_CallNonvirtualObjectMethod,
4031 _Jv_JNI_CallNonvirtualObjectMethodV,
4032 _Jv_JNI_CallNonvirtualObjectMethodA,
4033 _Jv_JNI_CallNonvirtualBooleanMethod,
4034 _Jv_JNI_CallNonvirtualBooleanMethodV,
4035 _Jv_JNI_CallNonvirtualBooleanMethodA,
4036 _Jv_JNI_CallNonvirtualByteMethod,
4037 _Jv_JNI_CallNonvirtualByteMethodV,
4038 _Jv_JNI_CallNonvirtualByteMethodA,
4039 _Jv_JNI_CallNonvirtualCharMethod,
4040 _Jv_JNI_CallNonvirtualCharMethodV,
4041 _Jv_JNI_CallNonvirtualCharMethodA,
4042 _Jv_JNI_CallNonvirtualShortMethod,
4043 _Jv_JNI_CallNonvirtualShortMethodV,
4044 _Jv_JNI_CallNonvirtualShortMethodA,
4045 _Jv_JNI_CallNonvirtualIntMethod,
4046 _Jv_JNI_CallNonvirtualIntMethodV,
4047 _Jv_JNI_CallNonvirtualIntMethodA,
4048 _Jv_JNI_CallNonvirtualLongMethod,
4049 _Jv_JNI_CallNonvirtualLongMethodV,
4050 _Jv_JNI_CallNonvirtualLongMethodA,
4051 _Jv_JNI_CallNonvirtualFloatMethod,
4052 _Jv_JNI_CallNonvirtualFloatMethodV,
4053 _Jv_JNI_CallNonvirtualFloatMethodA,
4054 _Jv_JNI_CallNonvirtualDoubleMethod,
4055 _Jv_JNI_CallNonvirtualDoubleMethodV,
4056 _Jv_JNI_CallNonvirtualDoubleMethodA,
4057 _Jv_JNI_CallNonvirtualVoidMethod,
4058 _Jv_JNI_CallNonvirtualVoidMethodV,
4059 _Jv_JNI_CallNonvirtualVoidMethodA,
4063 _Jv_JNI_GetObjectField,
4064 _Jv_JNI_GetBooleanField,
4065 _Jv_JNI_GetByteField,
4066 _Jv_JNI_GetCharField,
4067 _Jv_JNI_GetShortField,
4068 _Jv_JNI_GetIntField,
4069 _Jv_JNI_GetLongField,
4070 _Jv_JNI_GetFloatField,
4071 _Jv_JNI_GetDoubleField,
4072 _Jv_JNI_SetObjectField,
4073 _Jv_JNI_SetBooleanField,
4074 _Jv_JNI_SetByteField,
4075 _Jv_JNI_SetCharField,
4076 _Jv_JNI_SetShortField,
4077 _Jv_JNI_SetIntField,
4078 _Jv_JNI_SetLongField,
4079 _Jv_JNI_SetFloatField,
4080 _Jv_JNI_SetDoubleField,
4082 _Jv_JNI_GetStaticMethodID,
4084 _Jv_JNI_CallStaticObjectMethod,
4085 _Jv_JNI_CallStaticObjectMethodV,
4086 _Jv_JNI_CallStaticObjectMethodA,
4087 _Jv_JNI_CallStaticBooleanMethod,
4088 _Jv_JNI_CallStaticBooleanMethodV,
4089 _Jv_JNI_CallStaticBooleanMethodA,
4090 _Jv_JNI_CallStaticByteMethod,
4091 _Jv_JNI_CallStaticByteMethodV,
4092 _Jv_JNI_CallStaticByteMethodA,
4093 _Jv_JNI_CallStaticCharMethod,
4094 _Jv_JNI_CallStaticCharMethodV,
4095 _Jv_JNI_CallStaticCharMethodA,
4096 _Jv_JNI_CallStaticShortMethod,
4097 _Jv_JNI_CallStaticShortMethodV,
4098 _Jv_JNI_CallStaticShortMethodA,
4099 _Jv_JNI_CallStaticIntMethod,
4100 _Jv_JNI_CallStaticIntMethodV,
4101 _Jv_JNI_CallStaticIntMethodA,
4102 _Jv_JNI_CallStaticLongMethod,
4103 _Jv_JNI_CallStaticLongMethodV,
4104 _Jv_JNI_CallStaticLongMethodA,
4105 _Jv_JNI_CallStaticFloatMethod,
4106 _Jv_JNI_CallStaticFloatMethodV,
4107 _Jv_JNI_CallStaticFloatMethodA,
4108 _Jv_JNI_CallStaticDoubleMethod,
4109 _Jv_JNI_CallStaticDoubleMethodV,
4110 _Jv_JNI_CallStaticDoubleMethodA,
4111 _Jv_JNI_CallStaticVoidMethod,
4112 _Jv_JNI_CallStaticVoidMethodV,
4113 _Jv_JNI_CallStaticVoidMethodA,
4115 _Jv_JNI_GetStaticFieldID,
4117 _Jv_JNI_GetStaticObjectField,
4118 _Jv_JNI_GetStaticBooleanField,
4119 _Jv_JNI_GetStaticByteField,
4120 _Jv_JNI_GetStaticCharField,
4121 _Jv_JNI_GetStaticShortField,
4122 _Jv_JNI_GetStaticIntField,
4123 _Jv_JNI_GetStaticLongField,
4124 _Jv_JNI_GetStaticFloatField,
4125 _Jv_JNI_GetStaticDoubleField,
4126 _Jv_JNI_SetStaticObjectField,
4127 _Jv_JNI_SetStaticBooleanField,
4128 _Jv_JNI_SetStaticByteField,
4129 _Jv_JNI_SetStaticCharField,
4130 _Jv_JNI_SetStaticShortField,
4131 _Jv_JNI_SetStaticIntField,
4132 _Jv_JNI_SetStaticLongField,
4133 _Jv_JNI_SetStaticFloatField,
4134 _Jv_JNI_SetStaticDoubleField,
4137 _Jv_JNI_GetStringLength,
4138 _Jv_JNI_GetStringChars,
4139 _Jv_JNI_ReleaseStringChars,
4141 _Jv_JNI_NewStringUTF,
4142 _Jv_JNI_GetStringUTFLength,
4143 _Jv_JNI_GetStringUTFChars,
4144 _Jv_JNI_ReleaseStringUTFChars,
4146 _Jv_JNI_GetArrayLength,
4148 _Jv_JNI_NewObjectArray,
4149 _Jv_JNI_GetObjectArrayElement,
4150 _Jv_JNI_SetObjectArrayElement,
4152 _Jv_JNI_NewBooleanArray,
4153 _Jv_JNI_NewByteArray,
4154 _Jv_JNI_NewCharArray,
4155 _Jv_JNI_NewShortArray,
4156 _Jv_JNI_NewIntArray,
4157 _Jv_JNI_NewLongArray,
4158 _Jv_JNI_NewFloatArray,
4159 _Jv_JNI_NewDoubleArray,
4161 _Jv_JNI_GetBooleanArrayElements,
4162 _Jv_JNI_GetByteArrayElements,
4163 _Jv_JNI_GetCharArrayElements,
4164 _Jv_JNI_GetShortArrayElements,
4165 _Jv_JNI_GetIntArrayElements,
4166 _Jv_JNI_GetLongArrayElements,
4167 _Jv_JNI_GetFloatArrayElements,
4168 _Jv_JNI_GetDoubleArrayElements,
4170 _Jv_JNI_ReleaseBooleanArrayElements,
4171 _Jv_JNI_ReleaseByteArrayElements,
4172 _Jv_JNI_ReleaseCharArrayElements,
4173 _Jv_JNI_ReleaseShortArrayElements,
4174 _Jv_JNI_ReleaseIntArrayElements,
4175 _Jv_JNI_ReleaseLongArrayElements,
4176 _Jv_JNI_ReleaseFloatArrayElements,
4177 _Jv_JNI_ReleaseDoubleArrayElements,
4179 _Jv_JNI_GetBooleanArrayRegion,
4180 _Jv_JNI_GetByteArrayRegion,
4181 _Jv_JNI_GetCharArrayRegion,
4182 _Jv_JNI_GetShortArrayRegion,
4183 _Jv_JNI_GetIntArrayRegion,
4184 _Jv_JNI_GetLongArrayRegion,
4185 _Jv_JNI_GetFloatArrayRegion,
4186 _Jv_JNI_GetDoubleArrayRegion,
4187 _Jv_JNI_SetBooleanArrayRegion,
4188 _Jv_JNI_SetByteArrayRegion,
4189 _Jv_JNI_SetCharArrayRegion,
4190 _Jv_JNI_SetShortArrayRegion,
4191 _Jv_JNI_SetIntArrayRegion,
4192 _Jv_JNI_SetLongArrayRegion,
4193 _Jv_JNI_SetFloatArrayRegion,
4194 _Jv_JNI_SetDoubleArrayRegion,
4196 _Jv_JNI_RegisterNatives,
4197 _Jv_JNI_UnregisterNatives,
4199 _Jv_JNI_MonitorEnter,
4200 _Jv_JNI_MonitorExit,
4204 /* New JNI 1.2 functions. */
4206 _Jv_JNI_GetStringRegion,
4207 _Jv_JNI_GetStringUTFRegion,
4209 _Jv_JNI_GetPrimitiveArrayCritical,
4210 _Jv_JNI_ReleasePrimitiveArrayCritical,
4212 _Jv_JNI_GetStringCritical,
4213 _Jv_JNI_ReleaseStringCritical,
4215 _Jv_JNI_NewWeakGlobalRef,
4216 _Jv_JNI_DeleteWeakGlobalRef,
4218 _Jv_JNI_ExceptionCheck,
4220 /* New JNI 1.4 functions. */
4222 _Jv_JNI_NewDirectByteBuffer,
4223 _Jv_JNI_GetDirectBufferAddress,
4224 _Jv_JNI_GetDirectBufferCapacity,
4226 /* New JNI 1.6 functions. */
4228 jni_GetObjectRefType
4232 /* Invocation API Functions ***************************************************/
4234 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4236 Returns a default configuration for the Java VM.
4238 *******************************************************************************/
4240 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4242 JavaVMInitArgs *_vm_args;
4244 _vm_args = (JavaVMInitArgs *) vm_args;
4246 /* GNU classpath currently supports JNI 1.2 */
4248 switch (_vm_args->version) {
4249 case JNI_VERSION_1_1:
4250 _vm_args->version = JNI_VERSION_1_1;
4253 case JNI_VERSION_1_2:
4254 case JNI_VERSION_1_4:
4255 _vm_args->ignoreUnrecognized = JNI_FALSE;
4256 _vm_args->options = NULL;
4257 _vm_args->nOptions = 0;
4268 /* JNI_GetCreatedJavaVMs *******************************************************
4270 Returns all Java VMs that have been created. Pointers to VMs are written in
4271 the buffer vmBuf in the order they are created. At most bufLen number of
4272 entries will be written. The total number of created VMs is returned in
4275 *******************************************************************************/
4277 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4279 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4284 /* We currently only support 1 VM running. */
4286 vmBuf[0] = (JavaVM *) _Jv_jvm;
4293 /* JNI_CreateJavaVM ************************************************************
4295 Loads and initializes a Java VM. The current thread becomes the main thread.
4296 Sets the env argument to the JNI interface pointer of the main thread.
4298 *******************************************************************************/
4300 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4302 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4304 /* actually create the JVM */
4306 if (!vm_createjvm(p_vm, p_env, vm_args))
4314 * These are local overrides for various environment variables in Emacs.
4315 * Please do not remove this and leave it at the end of the file, where
4316 * Emacs will automagically detect them.
4317 * ---------------------------------------------------------------------
4320 * indent-tabs-mode: t
4324 * vim:noexpandtab:sw=4:ts=4: