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;
1278 /* delete the reference */
1284 /* IsSameObject ****************************************************************
1286 Tests whether two references refer to the same Java object.
1288 *******************************************************************************/
1290 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1296 STATISTICS(jniinvokation());
1298 o1 = (java_handle_t *) ref1;
1299 o2 = (java_handle_t *) ref2;
1301 LLNI_CRITICAL_START;
1303 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1314 /* NewLocalRef *****************************************************************
1316 Creates a new local reference that refers to the same object as ref.
1318 *******************************************************************************/
1320 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1323 java_handle_t *localref;
1325 STATISTICS(jniinvokation());
1327 o = (java_handle_t *) ref;
1332 /* insert the reference */
1334 localref = localref_add(LLNI_DIRECT(o));
1340 /* EnsureLocalCapacity *********************************************************
1342 Ensures that at least a given number of local references can be
1343 created in the current thread
1345 *******************************************************************************/
1347 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1349 localref_table *lrt;
1351 STATISTICS(jniinvokation());
1353 /* get local reference table (thread specific) */
1355 lrt = LOCALREFTABLE;
1357 /* check if capacity elements are available in the local references table */
1359 if ((lrt->used + capacity) > lrt->capacity)
1360 return _Jv_JNI_PushLocalFrame(env, capacity);
1366 /* AllocObject *****************************************************************
1368 Allocates a new Java object without invoking any of the
1369 constructors for the object. Returns a reference to the object.
1371 *******************************************************************************/
1373 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1378 STATISTICS(jniinvokation());
1380 c = LLNI_classinfo_unwrap(clazz);
1382 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1383 exceptions_throw_instantiationexception(c);
1389 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1393 /* NewObject *******************************************************************
1395 Programmers place all arguments that are to be passed to the
1396 constructor immediately following the methodID
1397 argument. NewObject() accepts these arguments and passes them to
1398 the Java method that the programmer wishes to invoke.
1400 *******************************************************************************/
1402 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1409 STATISTICS(jniinvokation());
1411 c = LLNI_classinfo_unwrap(clazz);
1412 m = (methodinfo *) methodID;
1421 /* call constructor */
1423 va_start(ap, methodID);
1424 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1427 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1431 /* NewObjectV ******************************************************************
1433 Programmers place all arguments that are to be passed to the
1434 constructor in an args argument of type va_list that immediately
1435 follows the methodID argument. NewObjectV() accepts these
1436 arguments, and, in turn, passes them to the Java method that the
1437 programmer wishes to invoke.
1439 *******************************************************************************/
1441 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1448 STATISTICS(jniinvokation());
1450 c = LLNI_classinfo_unwrap(clazz);
1451 m = (methodinfo *) methodID;
1460 /* call constructor */
1462 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1464 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1468 /* NewObjectA *****************************************************************
1470 Programmers place all arguments that are to be passed to the
1471 constructor in an args array of jvalues that immediately follows
1472 the methodID argument. NewObjectA() accepts the arguments in this
1473 array, and, in turn, passes them to the Java method that the
1474 programmer wishes to invoke.
1476 *******************************************************************************/
1478 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1485 STATISTICS(jniinvokation());
1487 c = LLNI_classinfo_unwrap(clazz);
1488 m = (methodinfo *) methodID;
1497 /* call constructor */
1499 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1501 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1505 /* GetObjectClass **************************************************************
1507 Returns the class of an object.
1509 *******************************************************************************/
1511 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1515 java_lang_Class *co;
1517 STATISTICS(jniinvokation());
1519 o = (java_handle_t *) obj;
1521 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1524 LLNI_class_get(o, c);
1526 co = LLNI_classinfo_wrap(c);
1528 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1532 /* IsInstanceOf ****************************************************************
1534 Tests whether an object is an instance of a class.
1536 *******************************************************************************/
1538 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1541 java_lang_Object *o;
1543 STATISTICS(jniinvokation());
1545 c = (java_lang_Class *) clazz;
1546 o = (java_lang_Object *) obj;
1548 return _Jv_java_lang_Class_isInstance(c, o);
1552 /* Reflection Support *********************************************************/
1554 /* FromReflectedMethod *********************************************************
1556 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1557 object to a method ID.
1559 *******************************************************************************/
1561 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1563 #if defined(ENABLE_JAVASE)
1569 STATISTICS(jniinvokation());
1571 o = (java_handle_t *) method;
1576 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1577 java_lang_reflect_Method *rm;
1579 rm = (java_lang_reflect_Method *) method;
1580 LLNI_field_get_cls(rm, clazz, c);
1581 LLNI_field_get_val(rm, slot , slot);
1583 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1584 java_lang_reflect_Constructor *rc;
1586 rc = (java_lang_reflect_Constructor *) method;
1587 LLNI_field_get_cls(rc, clazz, c);
1588 LLNI_field_get_val(rc, slot , slot);
1593 m = &(c->methods[slot]);
1595 return (jmethodID) m;
1597 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1599 /* keep compiler happy */
1606 /* FromReflectedField **********************************************************
1608 Converts a java.lang.reflect.Field to a field ID.
1610 *******************************************************************************/
1612 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1614 #if defined(ENABLE_JAVASE)
1615 java_lang_reflect_Field *rf;
1620 STATISTICS(jniinvokation());
1622 rf = (java_lang_reflect_Field *) field;
1627 LLNI_field_get_cls(rf, clazz, c);
1628 LLNI_field_get_val(rf, slot , slot);
1629 f = &(c->fields[slot]);
1631 return (jfieldID) f;
1633 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1635 /* keep compiler happy */
1642 /* ToReflectedMethod ***********************************************************
1644 Converts a method ID derived from cls to an instance of the
1645 java.lang.reflect.Method class or to an instance of the
1646 java.lang.reflect.Constructor class.
1648 *******************************************************************************/
1650 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1653 #if defined(ENABLE_JAVASE)
1655 java_lang_reflect_Constructor *rc;
1656 java_lang_reflect_Method *rm;
1658 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1660 m = (methodinfo *) methodID;
1662 /* HotSpot does the same assert. */
1664 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1666 if (m->name == utf_init) {
1667 rc = reflect_constructor_new(m);
1669 return (jobject) rc;
1672 rm = reflect_method_new(m);
1674 return (jobject) rm;
1677 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1679 /* keep compiler happy */
1686 /* ToReflectedField ************************************************************
1688 Converts a field ID derived from cls to an instance of the
1689 java.lang.reflect.Field class.
1691 *******************************************************************************/
1693 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1696 STATISTICS(jniinvokation());
1698 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1704 /* Calling Instance Methods ***************************************************/
1706 /* GetMethodID *****************************************************************
1708 Returns the method ID for an instance (nonstatic) method of a class
1709 or interface. The method may be defined in one of the clazz's
1710 superclasses and inherited by clazz. The method is determined by
1711 its name and signature.
1713 GetMethodID() causes an uninitialized class to be initialized.
1715 *******************************************************************************/
1717 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1725 STATISTICS(jniinvokation());
1727 c = LLNI_classinfo_unwrap(clazz);
1732 if (!(c->state & CLASS_INITIALIZED))
1733 if (!initialize_class(c))
1736 /* try to get the method of the class or one of it's superclasses */
1738 uname = utf_new_char((char *) name);
1739 udesc = utf_new_char((char *) sig);
1741 m = class_resolvemethod(c, uname, udesc);
1743 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1744 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1749 return (jmethodID) m;
1753 /* JNI-functions for calling instance methods *********************************/
1755 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1756 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1757 jmethodID methodID, ...) \
1764 o = (java_handle_t *) obj; \
1765 m = (methodinfo *) methodID; \
1767 va_start(ap, methodID); \
1768 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1774 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1775 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1776 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1777 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1778 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1779 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1780 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1781 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1784 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1785 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1786 jmethodID methodID, va_list args) \
1792 o = (java_handle_t *) obj; \
1793 m = (methodinfo *) methodID; \
1795 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1800 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1801 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1802 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1803 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1804 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1805 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1806 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1807 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1810 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1811 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1812 jmethodID methodID, \
1813 const jvalue *args) \
1819 o = (java_handle_t *) obj; \
1820 m = (methodinfo *) methodID; \
1822 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1827 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1828 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1829 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1830 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1831 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1832 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1833 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1834 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1837 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1845 o = (java_handle_t *) obj;
1846 m = (methodinfo *) methodID;
1848 va_start(ap, methodID);
1849 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1852 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1856 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1863 o = (java_handle_t *) obj;
1864 m = (methodinfo *) methodID;
1866 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1868 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1872 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1879 o = (java_handle_t *) obj;
1880 m = (methodinfo *) methodID;
1882 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1884 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1889 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1895 o = (java_handle_t *) obj;
1896 m = (methodinfo *) methodID;
1898 va_start(ap, methodID);
1899 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1904 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1910 o = (java_handle_t *) obj;
1911 m = (methodinfo *) methodID;
1913 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1917 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1923 o = (java_handle_t *) obj;
1924 m = (methodinfo *) methodID;
1926 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1931 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1932 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1933 jclass clazz, jmethodID methodID, \
1942 o = (java_handle_t *) obj; \
1943 c = LLNI_classinfo_unwrap(clazz); \
1944 m = (methodinfo *) methodID; \
1946 va_start(ap, methodID); \
1947 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1953 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1954 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1955 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1956 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1957 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1958 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1959 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1960 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1963 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1964 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1965 jclass clazz, jmethodID methodID, \
1973 o = (java_handle_t *) obj; \
1974 c = LLNI_classinfo_unwrap(clazz); \
1975 m = (methodinfo *) methodID; \
1977 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1982 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1983 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1984 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1985 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1986 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1987 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1988 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1989 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1992 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1993 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1994 jclass clazz, jmethodID methodID, \
1995 const jvalue *args) \
1997 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2002 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2003 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2004 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2005 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2006 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2008 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2009 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2011 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2012 jclass clazz, jmethodID methodID,
2021 o = (java_handle_t *) obj;
2022 c = LLNI_classinfo_unwrap(clazz);
2023 m = (methodinfo *) methodID;
2025 va_start(ap, methodID);
2026 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2029 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2033 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2034 jclass clazz, jmethodID methodID,
2042 o = (java_handle_t *) obj;
2043 c = LLNI_classinfo_unwrap(clazz);
2044 m = (methodinfo *) methodID;
2046 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2048 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2052 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2053 jclass clazz, jmethodID methodID,
2056 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2058 return _Jv_JNI_NewLocalRef(env, NULL);
2062 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2063 jmethodID methodID, ...)
2070 o = (java_handle_t *) obj;
2071 c = LLNI_classinfo_unwrap(clazz);
2072 m = (methodinfo *) methodID;
2074 va_start(ap, methodID);
2075 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2080 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2081 jmethodID methodID, va_list args)
2087 o = (java_handle_t *) obj;
2088 c = LLNI_classinfo_unwrap(clazz);
2089 m = (methodinfo *) methodID;
2091 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2095 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2096 jmethodID methodID, const jvalue * args)
2102 o = (java_handle_t *) obj;
2103 c = LLNI_classinfo_unwrap(clazz);
2104 m = (methodinfo *) methodID;
2106 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2110 /* Accessing Fields of Objects ************************************************/
2112 /* GetFieldID ******************************************************************
2114 Returns the field ID for an instance (nonstatic) field of a
2115 class. The field is specified by its name and signature. The
2116 Get<type>Field and Set<type>Field families of accessor functions
2117 use field IDs to retrieve object fields.
2119 *******************************************************************************/
2121 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2129 STATISTICS(jniinvokation());
2131 c = LLNI_classinfo_unwrap(clazz);
2133 /* XXX NPE check? */
2135 uname = utf_new_char((char *) name);
2136 udesc = utf_new_char((char *) sig);
2138 f = class_findfield(c, uname, udesc);
2141 exceptions_throw_nosuchfielderror(c, uname);
2143 return (jfieldID) f;
2147 /* Get<type>Field Routines *****************************************************
2149 This family of accessor routines returns the value of an instance
2150 (nonstatic) field of an object. The field to access is specified by
2151 a field ID obtained by calling GetFieldID().
2153 *******************************************************************************/
2155 #define JNI_GET_FIELD(name, type, intern) \
2156 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2160 STATISTICS(jniinvokation()); \
2162 ret = GET_FIELD(obj, intern, fieldID); \
2164 return (type) ret; \
2167 JNI_GET_FIELD(Boolean, jboolean, s4)
2168 JNI_GET_FIELD(Byte, jbyte, s4)
2169 JNI_GET_FIELD(Char, jchar, s4)
2170 JNI_GET_FIELD(Short, jshort, s4)
2171 JNI_GET_FIELD(Int, jint, s4)
2172 JNI_GET_FIELD(Long, jlong, s8)
2173 JNI_GET_FIELD(Float, jfloat, float)
2174 JNI_GET_FIELD(Double, jdouble, double)
2177 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2181 TRACEJNICALLS("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID);
2183 LLNI_CRITICAL_START;
2185 o = LLNI_WRAP(GET_FIELD(obj, java_handle_t*, fieldID));
2189 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2193 /* Set<type>Field Routines *****************************************************
2195 This family of accessor routines sets the value of an instance
2196 (nonstatic) field of an object. The field to access is specified by
2197 a field ID obtained by calling GetFieldID().
2199 *******************************************************************************/
2201 #define JNI_SET_FIELD(name, type, intern) \
2202 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2205 STATISTICS(jniinvokation()); \
2207 SET_FIELD(obj, intern, fieldID, value); \
2210 JNI_SET_FIELD(Boolean, jboolean, s4)
2211 JNI_SET_FIELD(Byte, jbyte, s4)
2212 JNI_SET_FIELD(Char, jchar, s4)
2213 JNI_SET_FIELD(Short, jshort, s4)
2214 JNI_SET_FIELD(Int, jint, s4)
2215 JNI_SET_FIELD(Long, jlong, s8)
2216 JNI_SET_FIELD(Float, jfloat, float)
2217 JNI_SET_FIELD(Double, jdouble, double)
2220 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2223 TRACEJNICALLS("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value);
2225 LLNI_CRITICAL_START;
2227 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP(value));
2233 /* Calling Static Methods *****************************************************/
2235 /* GetStaticMethodID ***********************************************************
2237 Returns the method ID for a static method of a class. The method is
2238 specified by its name and signature.
2240 GetStaticMethodID() causes an uninitialized class to be
2243 *******************************************************************************/
2245 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2253 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2255 c = LLNI_classinfo_unwrap(clazz);
2260 if (!(c->state & CLASS_INITIALIZED))
2261 if (!initialize_class(c))
2264 /* try to get the static method of the class */
2266 uname = utf_new_char((char *) name);
2267 udesc = utf_new_char((char *) sig);
2269 m = class_resolvemethod(c, uname, udesc);
2271 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2272 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2277 return (jmethodID) m;
2281 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2282 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2283 jmethodID methodID, ...) \
2289 m = (methodinfo *) methodID; \
2291 va_start(ap, methodID); \
2292 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2298 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2299 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2300 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2301 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2302 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2303 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2304 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2305 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2308 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2309 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2310 jmethodID methodID, va_list args) \
2315 m = (methodinfo *) methodID; \
2317 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2322 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2323 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2324 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2325 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2326 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2327 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2328 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2329 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2332 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2333 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2334 jmethodID methodID, const jvalue *args) \
2339 m = (methodinfo *) methodID; \
2341 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2346 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2347 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2348 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2349 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2350 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2351 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2352 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2353 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2356 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2357 jmethodID methodID, ...)
2363 m = (methodinfo *) methodID;
2365 va_start(ap, methodID);
2366 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2369 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2373 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2374 jmethodID methodID, va_list args)
2379 m = (methodinfo *) methodID;
2381 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2383 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2387 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2388 jmethodID methodID, const jvalue *args)
2393 m = (methodinfo *) methodID;
2395 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2397 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2401 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2402 jmethodID methodID, ...)
2407 m = (methodinfo *) methodID;
2409 va_start(ap, methodID);
2410 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2415 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2416 jmethodID methodID, va_list args)
2420 m = (methodinfo *) methodID;
2422 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2426 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2427 jmethodID methodID, const jvalue * args)
2431 m = (methodinfo *) methodID;
2433 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2437 /* Accessing Static Fields ****************************************************/
2439 /* GetStaticFieldID ************************************************************
2441 Returns the field ID for a static field of a class. The field is
2442 specified by its name and signature. The GetStatic<type>Field and
2443 SetStatic<type>Field families of accessor functions use field IDs
2444 to retrieve static fields.
2446 *******************************************************************************/
2448 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2456 STATISTICS(jniinvokation());
2458 c = LLNI_classinfo_unwrap(clazz);
2460 uname = utf_new_char((char *) name);
2461 usig = utf_new_char((char *) sig);
2463 f = class_findfield(c, uname, usig);
2466 exceptions_throw_nosuchfielderror(c, uname);
2468 return (jfieldID) f;
2472 /* GetStatic<type>Field ********************************************************
2474 This family of accessor routines returns the value of a static
2477 *******************************************************************************/
2479 #define JNI_GET_STATIC_FIELD(name, type, field) \
2480 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2486 STATISTICS(jniinvokation()); \
2488 c = LLNI_classinfo_unwrap(clazz); \
2489 f = (fieldinfo *) fieldID; \
2491 if (!(c->state & CLASS_INITIALIZED)) \
2492 if (!initialize_class(c)) \
2495 return f->value->field; \
2498 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2499 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2500 JNI_GET_STATIC_FIELD(Char, jchar, i)
2501 JNI_GET_STATIC_FIELD(Short, jshort, i)
2502 JNI_GET_STATIC_FIELD(Int, jint, i)
2503 JNI_GET_STATIC_FIELD(Long, jlong, l)
2504 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2505 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2508 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2514 STATISTICS(jniinvokation());
2516 c = LLNI_classinfo_unwrap(clazz);
2517 f = (fieldinfo *) fieldID;
2519 if (!(c->state & CLASS_INITIALIZED))
2520 if (!initialize_class(c))
2523 return _Jv_JNI_NewLocalRef(env, f->value->a);
2527 /* SetStatic<type>Field *******************************************************
2529 This family of accessor routines sets the value of a static field
2532 *******************************************************************************/
2534 #define JNI_SET_STATIC_FIELD(name, type, field) \
2535 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2542 STATISTICS(jniinvokation()); \
2544 c = LLNI_classinfo_unwrap(clazz); \
2545 f = (fieldinfo *) fieldID; \
2547 if (!(c->state & CLASS_INITIALIZED)) \
2548 if (!initialize_class(c)) \
2551 f->value->field = value; \
2554 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2555 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2556 JNI_SET_STATIC_FIELD(Char, jchar, i)
2557 JNI_SET_STATIC_FIELD(Short, jshort, i)
2558 JNI_SET_STATIC_FIELD(Int, jint, i)
2559 JNI_SET_STATIC_FIELD(Long, jlong, l)
2560 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2561 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2564 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2570 STATISTICS(jniinvokation());
2572 c = LLNI_classinfo_unwrap(clazz);
2573 f = (fieldinfo *) fieldID;
2575 if (!(c->state & CLASS_INITIALIZED))
2576 if (!initialize_class(c))
2579 f->value->a = value;
2583 /* String Operations **********************************************************/
2585 /* NewString *******************************************************************
2587 Create new java.lang.String object from an array of Unicode
2590 *******************************************************************************/
2592 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2594 java_lang_String *s;
2595 java_handle_chararray_t *a;
2598 STATISTICS(jniinvokation());
2600 s = (java_lang_String *) builtin_new(class_java_lang_String);
2601 a = builtin_newarray_char(len);
2603 /* javastring or characterarray could not be created */
2604 if ((a == NULL) || (s == NULL))
2608 for (i = 0; i < len; i++)
2609 LLNI_array_direct(a, i) = buf[i];
2611 LLNI_field_set_ref(s, value , a);
2612 LLNI_field_set_val(s, offset, 0);
2613 LLNI_field_set_val(s, count , len);
2615 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2619 static jchar emptyStringJ[]={0,0};
2621 /* GetStringLength *************************************************************
2623 Returns the length (the count of Unicode characters) of a Java
2626 *******************************************************************************/
2628 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2630 java_lang_String *s;
2633 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2635 s = (java_lang_String *) str;
2637 LLNI_field_get_val(s, count, len);
2643 /******************** convertes javastring to u2-array ****************************/
2645 u2 *javastring_tou2(jstring so)
2647 java_lang_String *s;
2648 java_handle_chararray_t *a;
2654 STATISTICS(jniinvokation());
2656 s = (java_lang_String *) so;
2661 LLNI_field_get_ref(s, value, a);
2666 LLNI_field_get_val(s, count, count);
2667 LLNI_field_get_val(s, offset, offset);
2669 /* allocate memory */
2671 stringbuffer = MNEW(u2, count + 1);
2675 for (i = 0; i < count; i++)
2676 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2678 /* terminate string */
2680 stringbuffer[i] = '\0';
2682 return stringbuffer;
2686 /* GetStringChars **************************************************************
2688 Returns a pointer to the array of Unicode characters of the
2689 string. This pointer is valid until ReleaseStringChars() is called.
2691 *******************************************************************************/
2693 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2697 STATISTICS(jniinvokation());
2699 jc = javastring_tou2(str);
2711 return emptyStringJ;
2715 /* ReleaseStringChars **********************************************************
2717 Informs the VM that the native code no longer needs access to
2718 chars. The chars argument is a pointer obtained from string using
2721 *******************************************************************************/
2723 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2725 java_lang_String *s;
2727 STATISTICS(jniinvokation());
2729 if (chars == emptyStringJ)
2732 s = (java_lang_String *) str;
2734 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2738 /* NewStringUTF ****************************************************************
2740 Constructs a new java.lang.String object from an array of UTF-8
2743 *******************************************************************************/
2745 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2747 java_lang_String *s;
2749 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2751 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2753 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2757 /****************** returns the utf8 length in bytes of a string *******************/
2759 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2761 java_lang_String *s;
2764 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2766 s = (java_lang_String *) string;
2768 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2774 /* GetStringUTFChars ***********************************************************
2776 Returns a pointer to an array of UTF-8 characters of the
2777 string. This array is valid until it is released by
2778 ReleaseStringUTFChars().
2780 *******************************************************************************/
2782 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2787 STATISTICS(jniinvokation());
2795 u = javastring_toutf((java_handle_t *) string, false);
2804 /* ReleaseStringUTFChars *******************************************************
2806 Informs the VM that the native code no longer needs access to
2807 utf. The utf argument is a pointer derived from string using
2808 GetStringUTFChars().
2810 *******************************************************************************/
2812 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2814 STATISTICS(jniinvokation());
2816 /* XXX we don't release utf chars right now, perhaps that should be done
2817 later. Since there is always one reference the garbage collector will
2822 /* Array Operations ***********************************************************/
2824 /* GetArrayLength **************************************************************
2826 Returns the number of elements in the array.
2828 *******************************************************************************/
2830 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2835 STATISTICS(jniinvokation());
2837 a = (java_handle_t *) array;
2839 size = LLNI_array_size(a);
2845 /* NewObjectArray **************************************************************
2847 Constructs a new array holding objects in class elementClass. All
2848 elements are initially set to initialElement.
2850 *******************************************************************************/
2852 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2853 jclass elementClass, jobject initialElement)
2857 java_handle_objectarray_t *oa;
2860 STATISTICS(jniinvokation());
2862 c = LLNI_classinfo_unwrap(elementClass);
2863 o = (java_handle_t *) initialElement;
2866 exceptions_throw_negativearraysizeexception();
2870 oa = builtin_anewarray(length, c);
2875 /* set all elements to initialElement */
2877 for (i = 0; i < length; i++)
2878 LLNI_objectarray_element_set(oa, i, o);
2880 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2884 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2887 java_handle_objectarray_t *oa;
2890 STATISTICS(jniinvokation());
2892 oa = (java_handle_objectarray_t *) array;
2894 if (index >= LLNI_array_size(oa)) {
2895 exceptions_throw_arrayindexoutofboundsexception();
2899 LLNI_objectarray_element_get(oa, index, o);
2901 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2905 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2906 jsize index, jobject val)
2908 java_handle_objectarray_t *oa;
2911 STATISTICS(jniinvokation());
2913 oa = (java_handle_objectarray_t *) array;
2914 o = (java_handle_t *) val;
2916 if (index >= LLNI_array_size(oa)) {
2917 exceptions_throw_arrayindexoutofboundsexception();
2921 /* check if the class of value is a subclass of the element class
2924 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2927 LLNI_objectarray_element_set(oa, index, o);
2931 #define JNI_NEW_ARRAY(name, type, intern) \
2932 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2934 java_handle_##intern##array_t *a; \
2936 STATISTICS(jniinvokation()); \
2939 exceptions_throw_negativearraysizeexception(); \
2943 a = builtin_newarray_##intern(len); \
2945 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2948 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2949 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2950 JNI_NEW_ARRAY(Char, jcharArray, char)
2951 JNI_NEW_ARRAY(Short, jshortArray, byte)
2952 JNI_NEW_ARRAY(Int, jintArray, int)
2953 JNI_NEW_ARRAY(Long, jlongArray, long)
2954 JNI_NEW_ARRAY(Float, jfloatArray, float)
2955 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2958 /* Get<PrimitiveType>ArrayElements *********************************************
2960 A family of functions that returns the body of the primitive array.
2962 *******************************************************************************/
2964 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2965 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2968 java_handle_##intern##array_t *a; \
2970 STATISTICS(jniinvokation()); \
2972 a = (java_handle_##intern##array_t *) array; \
2975 *isCopy = JNI_FALSE; \
2977 return LLNI_array_data(a); \
2980 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2981 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2982 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2983 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2984 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2985 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2986 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2987 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2990 /* Release<PrimitiveType>ArrayElements *****************************************
2992 A family of functions that informs the VM that the native code no
2993 longer needs access to elems. The elems argument is a pointer
2994 derived from array using the corresponding
2995 Get<PrimitiveType>ArrayElements() function. If necessary, this
2996 function copies back all changes made to elems to the original
2999 *******************************************************************************/
3001 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3002 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3003 type *elems, jint mode) \
3005 java_handle_##intern##array_t *a; \
3007 STATISTICS(jniinvokation()); \
3009 a = (java_handle_##intern##array_t *) array; \
3011 if (elems != LLNI_array_data(a)) { \
3014 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3017 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3018 /* XXX TWISTI how should it be freed? */ \
3021 /* XXX TWISTI how should it be freed? */ \
3027 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3028 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3029 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3030 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3031 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3032 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3033 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3034 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3037 /* Get<PrimitiveType>ArrayRegion **********************************************
3039 A family of functions that copies a region of a primitive array
3042 *******************************************************************************/
3044 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3045 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3046 jsize start, jsize len, type *buf) \
3048 java_handle_##intern##array_t *a; \
3050 STATISTICS(jniinvokation()); \
3052 a = (java_handle_##intern##array_t *) array; \
3054 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3055 exceptions_throw_arrayindexoutofboundsexception(); \
3057 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3060 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3061 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3062 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3063 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3064 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3065 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3066 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3067 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3070 /* Set<PrimitiveType>ArrayRegion **********************************************
3072 A family of functions that copies back a region of a primitive
3073 array from a buffer.
3075 *******************************************************************************/
3077 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3078 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3079 jsize start, jsize len, const type *buf) \
3081 java_handle_##intern##array_t *a; \
3083 STATISTICS(jniinvokation()); \
3085 a = (java_handle_##intern##array_t *) array; \
3087 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3088 exceptions_throw_arrayindexoutofboundsexception(); \
3090 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3093 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3094 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3095 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3096 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3097 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3098 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3099 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3100 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3103 /* Registering Native Methods *************************************************/
3105 /* RegisterNatives *************************************************************
3107 Registers native methods with the class specified by the clazz
3108 argument. The methods parameter specifies an array of
3109 JNINativeMethod structures that contain the names, signatures, and
3110 function pointers of the native methods. The nMethods parameter
3111 specifies the number of native methods in the array.
3113 *******************************************************************************/
3115 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3116 const JNINativeMethod *methods, jint nMethods)
3120 STATISTICS(jniinvokation());
3122 c = LLNI_classinfo_unwrap(clazz);
3124 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3125 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3128 native_method_register(c->name, methods, nMethods);
3134 /* UnregisterNatives ***********************************************************
3136 Unregisters native methods of a class. The class goes back to the
3137 state before it was linked or registered with its native method
3140 This function should not be used in normal native code. Instead, it
3141 provides special programs a way to reload and relink native
3144 *******************************************************************************/
3146 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3148 STATISTICS(jniinvokation());
3150 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3152 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3158 /* Monitor Operations *********************************************************/
3160 /* MonitorEnter ****************************************************************
3162 Enters the monitor associated with the underlying Java object
3165 *******************************************************************************/
3167 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3169 STATISTICS(jniinvokation());
3172 exceptions_throw_nullpointerexception();
3176 LOCK_MONITOR_ENTER(obj);
3182 /* MonitorExit *****************************************************************
3184 The current thread must be the owner of the monitor associated with
3185 the underlying Java object referred to by obj. The thread
3186 decrements the counter indicating the number of times it has
3187 entered this monitor. If the value of the counter becomes zero, the
3188 current thread releases the monitor.
3190 *******************************************************************************/
3192 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3194 STATISTICS(jniinvokation());
3197 exceptions_throw_nullpointerexception();
3201 LOCK_MONITOR_EXIT(obj);
3207 /* JavaVM Interface ***********************************************************/
3209 /* GetJavaVM *******************************************************************
3211 Returns the Java VM interface (used in the Invocation API)
3212 associated with the current thread. The result is placed at the
3213 location pointed to by the second argument, vm.
3215 *******************************************************************************/
3217 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3219 STATISTICS(jniinvokation());
3221 *vm = (JavaVM *) _Jv_jvm;
3227 /* GetStringRegion *************************************************************
3229 Copies len number of Unicode characters beginning at offset start
3230 to the given buffer buf.
3232 Throws StringIndexOutOfBoundsException on index overflow.
3234 *******************************************************************************/
3236 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3239 java_lang_String *s;
3240 java_handle_chararray_t *ca;
3242 STATISTICS(jniinvokation());
3244 s = (java_lang_String *) str;
3245 LLNI_field_get_ref(s, value, ca);
3247 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3248 (start + len > LLNI_field_direct(s, count))) {
3249 exceptions_throw_stringindexoutofboundsexception();
3253 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3257 /* GetStringUTFRegion **********************************************************
3259 Translates len number of Unicode characters beginning at offset
3260 start into UTF-8 format and place the result in the given buffer
3263 Throws StringIndexOutOfBoundsException on index overflow.
3265 *******************************************************************************/
3267 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3268 jsize len, char *buf)
3270 java_lang_String *s;
3271 java_handle_chararray_t *ca;
3276 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3278 s = (java_lang_String *) str;
3279 LLNI_field_get_ref(s, value, ca);
3280 LLNI_field_get_val(s, count, count);
3281 LLNI_field_get_val(s, offset, offset);
3283 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3284 exceptions_throw_stringindexoutofboundsexception();
3288 for (i = 0; i < len; i++)
3289 buf[i] = LLNI_array_direct(ca, offset + start + i);
3295 /* GetPrimitiveArrayCritical ***************************************************
3297 Obtain a direct pointer to array elements.
3299 *******************************************************************************/
3301 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3304 java_handle_bytearray_t *ba;
3307 ba = (java_handle_bytearray_t *) array;
3309 /* do the same as Kaffe does */
3311 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3317 /* ReleasePrimitiveArrayCritical ***********************************************
3319 No specific documentation.
3321 *******************************************************************************/
3323 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3324 void *carray, jint mode)
3326 STATISTICS(jniinvokation());
3328 /* do the same as Kaffe does */
3330 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3335 /* GetStringCritical ***********************************************************
3337 The semantics of these two functions are similar to the existing
3338 Get/ReleaseStringChars functions.
3340 *******************************************************************************/
3342 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3345 STATISTICS(jniinvokation());
3347 return _Jv_JNI_GetStringChars(env, string, isCopy);
3351 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3352 const jchar *cstring)
3354 STATISTICS(jniinvokation());
3356 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3360 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3362 TRACEJNICALLS("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj);
3368 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3370 TRACEJNICALLS("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref);
3374 /* NewGlobalRef ****************************************************************
3376 Creates a new global reference to the object referred to by the obj
3379 *******************************************************************************/
3381 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3383 hashtable_global_ref_entry *gre;
3384 u4 key; /* hashkey */
3385 u4 slot; /* slot in hashtable */
3388 STATISTICS(jniinvokation());
3390 o = (java_handle_t *) obj;
3392 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3394 LLNI_CRITICAL_START;
3396 /* normally addresses are aligned to 4, 8 or 16 bytes */
3398 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3399 slot = key & (hashtable_global_ref->size - 1);
3400 gre = hashtable_global_ref->ptr[slot];
3402 /* search external hash chain for the entry */
3405 if (gre->o == LLNI_DIRECT(o)) {
3406 /* global object found, increment the reference */
3413 gre = gre->hashlink; /* next element in external chain */
3416 /* global ref not found, create a new one */
3419 gre = NEW(hashtable_global_ref_entry);
3421 #if defined(ENABLE_GC_CACAO)
3422 /* register global ref with the GC */
3424 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3427 gre->o = LLNI_DIRECT(o);
3430 /* insert entry into hashtable */
3432 gre->hashlink = hashtable_global_ref->ptr[slot];
3434 hashtable_global_ref->ptr[slot] = gre;
3436 /* update number of hashtable-entries */
3438 hashtable_global_ref->entries++;
3443 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3445 #if defined(ENABLE_HANDLES)
3453 /* DeleteGlobalRef *************************************************************
3455 Deletes the global reference pointed to by globalRef.
3457 *******************************************************************************/
3459 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3461 hashtable_global_ref_entry *gre;
3462 hashtable_global_ref_entry *prevgre;
3463 u4 key; /* hashkey */
3464 u4 slot; /* slot in hashtable */
3467 STATISTICS(jniinvokation());
3469 o = (java_handle_t *) globalRef;
3471 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3473 LLNI_CRITICAL_START;
3475 /* normally addresses are aligned to 4, 8 or 16 bytes */
3477 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3478 slot = key & (hashtable_global_ref->size - 1);
3479 gre = hashtable_global_ref->ptr[slot];
3481 /* initialize prevgre */
3485 /* search external hash chain for the entry */
3488 if (gre->o == LLNI_DIRECT(o)) {
3489 /* global object found, decrement the reference count */
3493 /* if reference count is 0, remove the entry */
3495 if (gre->refs == 0) {
3496 /* special handling if it's the first in the chain */
3498 if (prevgre == NULL)
3499 hashtable_global_ref->ptr[slot] = gre->hashlink;
3501 prevgre->hashlink = gre->hashlink;
3503 #if defined(ENABLE_GC_CACAO)
3504 /* unregister global ref with the GC */
3506 gc_reference_unregister(&(gre->o));
3509 FREE(gre, hashtable_global_ref_entry);
3514 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3519 prevgre = gre; /* save current pointer for removal */
3520 gre = gre->hashlink; /* next element in external chain */
3523 log_println("JNI-DeleteGlobalRef: global reference not found");
3527 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3531 /* ExceptionCheck **************************************************************
3533 Returns JNI_TRUE when there is a pending exception; otherwise,
3536 *******************************************************************************/
3538 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3542 STATISTICS(jniinvokation());
3544 o = exceptions_get_exception();
3546 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3550 /* New JNI 1.4 functions ******************************************************/
3552 /* NewDirectByteBuffer *********************************************************
3554 Allocates and returns a direct java.nio.ByteBuffer referring to the
3555 block of memory starting at the memory address address and
3556 extending capacity bytes.
3558 *******************************************************************************/
3560 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3562 #if defined(ENABLE_JAVASE)
3563 # if defined(WITH_CLASSPATH_GNU)
3564 java_handle_t *nbuf;
3566 # if SIZEOF_VOID_P == 8
3567 gnu_classpath_Pointer64 *paddress;
3569 gnu_classpath_Pointer32 *paddress;
3572 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3574 /* alocate a gnu.classpath.Pointer{32,64} object */
3576 # if SIZEOF_VOID_P == 8
3577 if (!(paddress = (gnu_classpath_Pointer64 *)
3578 builtin_new(class_gnu_classpath_Pointer64)))
3580 if (!(paddress = (gnu_classpath_Pointer32 *)
3581 builtin_new(class_gnu_classpath_Pointer32)))
3585 /* fill gnu.classpath.Pointer{32,64} with address */
3587 LLNI_field_set_val(paddress, data, (ptrint) address);
3589 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3591 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3592 (jmethodID) dbbirw_init, NULL, paddress,
3593 (jint) capacity, (jint) capacity, (jint) 0);
3595 /* add local reference and return the value */
3597 return _Jv_JNI_NewLocalRef(env, nbuf);
3599 # elif defined(WITH_CLASSPATH_SUN)
3605 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3607 /* Be paranoid about address sign-extension. */
3609 addr = (int64_t) ((uintptr_t) address);
3610 cap = (int32_t) capacity;
3612 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3613 (jmethodID) dbb_init, addr, cap);
3615 /* Add local reference and return the value. */
3617 return _Jv_JNI_NewLocalRef(env, o);
3620 # error unknown classpath configuration
3624 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3626 /* keep compiler happy */
3633 /* GetDirectBufferAddress ******************************************************
3635 Fetches and returns the starting address of the memory region
3636 referenced by the given direct java.nio.Buffer.
3638 *******************************************************************************/
3640 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3642 #if defined(ENABLE_JAVASE)
3643 # if defined(WITH_CLASSPATH_GNU)
3645 java_nio_DirectByteBufferImpl *nbuf;
3646 # if SIZEOF_VOID_P == 8
3647 gnu_classpath_Pointer64 *paddress;
3649 gnu_classpath_Pointer32 *paddress;
3653 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3655 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3658 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3660 # if SIZEOF_VOID_P == 8
3661 LLNI_field_get_ref(nbuf, address, paddress);
3662 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3664 LLNI_field_get_ref(nbuf, address, paddress);
3665 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3668 if (paddress == NULL)
3671 LLNI_field_get_val(paddress, data, address);
3672 /* this was the cast to avaoid warning: (void *) paddress->data */
3676 # elif defined(WITH_CLASSPATH_SUN)
3682 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3684 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3687 o = (java_nio_Buffer *) buf;
3689 LLNI_field_get_val(o, address, address);
3691 p = (void *) (intptr_t) address;
3696 # error unknown classpath configuration
3701 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3703 /* keep compiler happy */
3711 /* GetDirectBufferCapacity *****************************************************
3713 Fetches and returns the capacity in bytes of the memory region
3714 referenced by the given direct java.nio.Buffer.
3716 *******************************************************************************/
3718 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3720 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3722 java_nio_Buffer *nbuf;
3725 STATISTICS(jniinvokation());
3727 o = (java_handle_t *) buf;
3729 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3732 nbuf = (java_nio_Buffer *) o;
3734 LLNI_field_get_val(nbuf, cap, capacity);
3738 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3740 /* keep compiler happy */
3747 /* GetObjectRefType ************************************************************
3749 Returns the type of the object referred to by the obj argument. The
3750 argument obj can either be a local, global or weak global
3753 *******************************************************************************/
3755 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3757 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3763 /* DestroyJavaVM ***************************************************************
3765 Unloads a Java VM and reclaims its resources. Only the main thread
3766 can unload the VM. The system waits until the main thread is only
3767 remaining user thread before it destroys the VM.
3769 *******************************************************************************/
3771 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3775 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3777 status = vm_destroy(vm);
3783 /* AttachCurrentThread *********************************************************
3785 Attaches the current thread to a Java VM. Returns a JNI interface
3786 pointer in the JNIEnv argument.
3788 Trying to attach a thread that is already attached is a no-op.
3790 A native thread cannot be attached simultaneously to two Java VMs.
3792 When a thread is attached to the VM, the context class loader is
3793 the bootstrap loader.
3795 *******************************************************************************/
3797 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3799 JavaVMAttachArgs *vm_aargs;
3801 #if defined(ENABLE_THREADS)
3802 if (threads_get_current_threadobject() == NULL) {
3803 vm_aargs = (JavaVMAttachArgs *) thr_args;
3805 if (vm_aargs != NULL) {
3806 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3807 (vm_aargs->version != JNI_VERSION_1_4))
3808 return JNI_EVERSION;
3811 if (!threads_attach_current_thread(vm_aargs, false))
3814 if (!localref_table_init())
3825 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3827 STATISTICS(jniinvokation());
3829 return jni_attach_current_thread(p_env, thr_args, false);
3833 /* DetachCurrentThread *********************************************************
3835 Detaches the current thread from a Java VM. All Java monitors held
3836 by this thread are released. All Java threads waiting for this
3837 thread to die are notified.
3839 In JDK 1.1, the main thread cannot be detached from the VM. It must
3840 call DestroyJavaVM to unload the entire VM.
3842 In the JDK, the main thread can be detached from the VM.
3844 The main thread, which is the thread that created the Java VM,
3845 cannot be detached from the VM. Instead, the main thread must call
3846 JNI_DestroyJavaVM() to unload the entire VM.
3848 *******************************************************************************/
3850 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3852 #if defined(ENABLE_THREADS)
3853 threadobject *thread;
3855 STATISTICS(jniinvokation());
3857 thread = threads_get_current_threadobject();
3862 /* We need to pop all frames before we can destroy the table. */
3864 localref_frame_pop_all();
3866 if (!localref_table_destroy())
3869 if (!threads_detach_thread(thread))
3877 /* GetEnv **********************************************************************
3879 If the current thread is not attached to the VM, sets *env to NULL,
3880 and returns JNI_EDETACHED. If the specified version is not
3881 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3882 sets *env to the appropriate interface, and returns JNI_OK.
3884 *******************************************************************************/
3886 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3888 TRACEJNICALLS("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version);
3890 #if defined(ENABLE_THREADS)
3891 if (threads_get_current_threadobject() == NULL) {
3894 return JNI_EDETACHED;
3898 /* Check the JNI version. */
3900 if (jni_version_check(version) == true) {
3905 #if defined(ENABLE_JVMTI)
3906 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3907 == JVMTI_VERSION_INTERFACE_JVMTI) {
3909 *env = (void *) jvmti_new_environment();
3918 return JNI_EVERSION;
3922 /* AttachCurrentThreadAsDaemon *************************************************
3924 Same semantics as AttachCurrentThread, but the newly-created
3925 java.lang.Thread instance is a daemon.
3927 If the thread has already been attached via either
3928 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3929 simply sets the value pointed to by penv to the JNIEnv of the
3930 current thread. In this case neither AttachCurrentThread nor this
3931 routine have any effect on the daemon status of the thread.
3933 *******************************************************************************/
3935 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3937 STATISTICS(jniinvokation());
3939 return jni_attach_current_thread(penv, args, true);
3943 /* JNI invocation table *******************************************************/
3945 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3950 _Jv_JNI_DestroyJavaVM,
3951 _Jv_JNI_AttachCurrentThread,
3952 _Jv_JNI_DetachCurrentThread,
3954 _Jv_JNI_AttachCurrentThreadAsDaemon
3958 /* JNI function table *********************************************************/
3960 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3967 _Jv_JNI_DefineClass,
3969 _Jv_JNI_FromReflectedMethod,
3970 _Jv_JNI_FromReflectedField,
3971 _Jv_JNI_ToReflectedMethod,
3972 _Jv_JNI_GetSuperclass,
3973 _Jv_JNI_IsAssignableFrom,
3974 _Jv_JNI_ToReflectedField,
3978 _Jv_JNI_ExceptionOccurred,
3979 _Jv_JNI_ExceptionDescribe,
3980 _Jv_JNI_ExceptionClear,
3982 _Jv_JNI_PushLocalFrame,
3983 _Jv_JNI_PopLocalFrame,
3985 _Jv_JNI_NewGlobalRef,
3986 _Jv_JNI_DeleteGlobalRef,
3987 _Jv_JNI_DeleteLocalRef,
3988 _Jv_JNI_IsSameObject,
3989 _Jv_JNI_NewLocalRef,
3990 _Jv_JNI_EnsureLocalCapacity,
3992 _Jv_JNI_AllocObject,
3997 _Jv_JNI_GetObjectClass,
3998 _Jv_JNI_IsInstanceOf,
4000 _Jv_JNI_GetMethodID,
4002 _Jv_JNI_CallObjectMethod,
4003 _Jv_JNI_CallObjectMethodV,
4004 _Jv_JNI_CallObjectMethodA,
4005 _Jv_JNI_CallBooleanMethod,
4006 _Jv_JNI_CallBooleanMethodV,
4007 _Jv_JNI_CallBooleanMethodA,
4008 _Jv_JNI_CallByteMethod,
4009 _Jv_JNI_CallByteMethodV,
4010 _Jv_JNI_CallByteMethodA,
4011 _Jv_JNI_CallCharMethod,
4012 _Jv_JNI_CallCharMethodV,
4013 _Jv_JNI_CallCharMethodA,
4014 _Jv_JNI_CallShortMethod,
4015 _Jv_JNI_CallShortMethodV,
4016 _Jv_JNI_CallShortMethodA,
4017 _Jv_JNI_CallIntMethod,
4018 _Jv_JNI_CallIntMethodV,
4019 _Jv_JNI_CallIntMethodA,
4020 _Jv_JNI_CallLongMethod,
4021 _Jv_JNI_CallLongMethodV,
4022 _Jv_JNI_CallLongMethodA,
4023 _Jv_JNI_CallFloatMethod,
4024 _Jv_JNI_CallFloatMethodV,
4025 _Jv_JNI_CallFloatMethodA,
4026 _Jv_JNI_CallDoubleMethod,
4027 _Jv_JNI_CallDoubleMethodV,
4028 _Jv_JNI_CallDoubleMethodA,
4029 _Jv_JNI_CallVoidMethod,
4030 _Jv_JNI_CallVoidMethodV,
4031 _Jv_JNI_CallVoidMethodA,
4033 _Jv_JNI_CallNonvirtualObjectMethod,
4034 _Jv_JNI_CallNonvirtualObjectMethodV,
4035 _Jv_JNI_CallNonvirtualObjectMethodA,
4036 _Jv_JNI_CallNonvirtualBooleanMethod,
4037 _Jv_JNI_CallNonvirtualBooleanMethodV,
4038 _Jv_JNI_CallNonvirtualBooleanMethodA,
4039 _Jv_JNI_CallNonvirtualByteMethod,
4040 _Jv_JNI_CallNonvirtualByteMethodV,
4041 _Jv_JNI_CallNonvirtualByteMethodA,
4042 _Jv_JNI_CallNonvirtualCharMethod,
4043 _Jv_JNI_CallNonvirtualCharMethodV,
4044 _Jv_JNI_CallNonvirtualCharMethodA,
4045 _Jv_JNI_CallNonvirtualShortMethod,
4046 _Jv_JNI_CallNonvirtualShortMethodV,
4047 _Jv_JNI_CallNonvirtualShortMethodA,
4048 _Jv_JNI_CallNonvirtualIntMethod,
4049 _Jv_JNI_CallNonvirtualIntMethodV,
4050 _Jv_JNI_CallNonvirtualIntMethodA,
4051 _Jv_JNI_CallNonvirtualLongMethod,
4052 _Jv_JNI_CallNonvirtualLongMethodV,
4053 _Jv_JNI_CallNonvirtualLongMethodA,
4054 _Jv_JNI_CallNonvirtualFloatMethod,
4055 _Jv_JNI_CallNonvirtualFloatMethodV,
4056 _Jv_JNI_CallNonvirtualFloatMethodA,
4057 _Jv_JNI_CallNonvirtualDoubleMethod,
4058 _Jv_JNI_CallNonvirtualDoubleMethodV,
4059 _Jv_JNI_CallNonvirtualDoubleMethodA,
4060 _Jv_JNI_CallNonvirtualVoidMethod,
4061 _Jv_JNI_CallNonvirtualVoidMethodV,
4062 _Jv_JNI_CallNonvirtualVoidMethodA,
4066 _Jv_JNI_GetObjectField,
4067 _Jv_JNI_GetBooleanField,
4068 _Jv_JNI_GetByteField,
4069 _Jv_JNI_GetCharField,
4070 _Jv_JNI_GetShortField,
4071 _Jv_JNI_GetIntField,
4072 _Jv_JNI_GetLongField,
4073 _Jv_JNI_GetFloatField,
4074 _Jv_JNI_GetDoubleField,
4075 _Jv_JNI_SetObjectField,
4076 _Jv_JNI_SetBooleanField,
4077 _Jv_JNI_SetByteField,
4078 _Jv_JNI_SetCharField,
4079 _Jv_JNI_SetShortField,
4080 _Jv_JNI_SetIntField,
4081 _Jv_JNI_SetLongField,
4082 _Jv_JNI_SetFloatField,
4083 _Jv_JNI_SetDoubleField,
4085 _Jv_JNI_GetStaticMethodID,
4087 _Jv_JNI_CallStaticObjectMethod,
4088 _Jv_JNI_CallStaticObjectMethodV,
4089 _Jv_JNI_CallStaticObjectMethodA,
4090 _Jv_JNI_CallStaticBooleanMethod,
4091 _Jv_JNI_CallStaticBooleanMethodV,
4092 _Jv_JNI_CallStaticBooleanMethodA,
4093 _Jv_JNI_CallStaticByteMethod,
4094 _Jv_JNI_CallStaticByteMethodV,
4095 _Jv_JNI_CallStaticByteMethodA,
4096 _Jv_JNI_CallStaticCharMethod,
4097 _Jv_JNI_CallStaticCharMethodV,
4098 _Jv_JNI_CallStaticCharMethodA,
4099 _Jv_JNI_CallStaticShortMethod,
4100 _Jv_JNI_CallStaticShortMethodV,
4101 _Jv_JNI_CallStaticShortMethodA,
4102 _Jv_JNI_CallStaticIntMethod,
4103 _Jv_JNI_CallStaticIntMethodV,
4104 _Jv_JNI_CallStaticIntMethodA,
4105 _Jv_JNI_CallStaticLongMethod,
4106 _Jv_JNI_CallStaticLongMethodV,
4107 _Jv_JNI_CallStaticLongMethodA,
4108 _Jv_JNI_CallStaticFloatMethod,
4109 _Jv_JNI_CallStaticFloatMethodV,
4110 _Jv_JNI_CallStaticFloatMethodA,
4111 _Jv_JNI_CallStaticDoubleMethod,
4112 _Jv_JNI_CallStaticDoubleMethodV,
4113 _Jv_JNI_CallStaticDoubleMethodA,
4114 _Jv_JNI_CallStaticVoidMethod,
4115 _Jv_JNI_CallStaticVoidMethodV,
4116 _Jv_JNI_CallStaticVoidMethodA,
4118 _Jv_JNI_GetStaticFieldID,
4120 _Jv_JNI_GetStaticObjectField,
4121 _Jv_JNI_GetStaticBooleanField,
4122 _Jv_JNI_GetStaticByteField,
4123 _Jv_JNI_GetStaticCharField,
4124 _Jv_JNI_GetStaticShortField,
4125 _Jv_JNI_GetStaticIntField,
4126 _Jv_JNI_GetStaticLongField,
4127 _Jv_JNI_GetStaticFloatField,
4128 _Jv_JNI_GetStaticDoubleField,
4129 _Jv_JNI_SetStaticObjectField,
4130 _Jv_JNI_SetStaticBooleanField,
4131 _Jv_JNI_SetStaticByteField,
4132 _Jv_JNI_SetStaticCharField,
4133 _Jv_JNI_SetStaticShortField,
4134 _Jv_JNI_SetStaticIntField,
4135 _Jv_JNI_SetStaticLongField,
4136 _Jv_JNI_SetStaticFloatField,
4137 _Jv_JNI_SetStaticDoubleField,
4140 _Jv_JNI_GetStringLength,
4141 _Jv_JNI_GetStringChars,
4142 _Jv_JNI_ReleaseStringChars,
4144 _Jv_JNI_NewStringUTF,
4145 _Jv_JNI_GetStringUTFLength,
4146 _Jv_JNI_GetStringUTFChars,
4147 _Jv_JNI_ReleaseStringUTFChars,
4149 _Jv_JNI_GetArrayLength,
4151 _Jv_JNI_NewObjectArray,
4152 _Jv_JNI_GetObjectArrayElement,
4153 _Jv_JNI_SetObjectArrayElement,
4155 _Jv_JNI_NewBooleanArray,
4156 _Jv_JNI_NewByteArray,
4157 _Jv_JNI_NewCharArray,
4158 _Jv_JNI_NewShortArray,
4159 _Jv_JNI_NewIntArray,
4160 _Jv_JNI_NewLongArray,
4161 _Jv_JNI_NewFloatArray,
4162 _Jv_JNI_NewDoubleArray,
4164 _Jv_JNI_GetBooleanArrayElements,
4165 _Jv_JNI_GetByteArrayElements,
4166 _Jv_JNI_GetCharArrayElements,
4167 _Jv_JNI_GetShortArrayElements,
4168 _Jv_JNI_GetIntArrayElements,
4169 _Jv_JNI_GetLongArrayElements,
4170 _Jv_JNI_GetFloatArrayElements,
4171 _Jv_JNI_GetDoubleArrayElements,
4173 _Jv_JNI_ReleaseBooleanArrayElements,
4174 _Jv_JNI_ReleaseByteArrayElements,
4175 _Jv_JNI_ReleaseCharArrayElements,
4176 _Jv_JNI_ReleaseShortArrayElements,
4177 _Jv_JNI_ReleaseIntArrayElements,
4178 _Jv_JNI_ReleaseLongArrayElements,
4179 _Jv_JNI_ReleaseFloatArrayElements,
4180 _Jv_JNI_ReleaseDoubleArrayElements,
4182 _Jv_JNI_GetBooleanArrayRegion,
4183 _Jv_JNI_GetByteArrayRegion,
4184 _Jv_JNI_GetCharArrayRegion,
4185 _Jv_JNI_GetShortArrayRegion,
4186 _Jv_JNI_GetIntArrayRegion,
4187 _Jv_JNI_GetLongArrayRegion,
4188 _Jv_JNI_GetFloatArrayRegion,
4189 _Jv_JNI_GetDoubleArrayRegion,
4190 _Jv_JNI_SetBooleanArrayRegion,
4191 _Jv_JNI_SetByteArrayRegion,
4192 _Jv_JNI_SetCharArrayRegion,
4193 _Jv_JNI_SetShortArrayRegion,
4194 _Jv_JNI_SetIntArrayRegion,
4195 _Jv_JNI_SetLongArrayRegion,
4196 _Jv_JNI_SetFloatArrayRegion,
4197 _Jv_JNI_SetDoubleArrayRegion,
4199 _Jv_JNI_RegisterNatives,
4200 _Jv_JNI_UnregisterNatives,
4202 _Jv_JNI_MonitorEnter,
4203 _Jv_JNI_MonitorExit,
4207 /* New JNI 1.2 functions. */
4209 _Jv_JNI_GetStringRegion,
4210 _Jv_JNI_GetStringUTFRegion,
4212 _Jv_JNI_GetPrimitiveArrayCritical,
4213 _Jv_JNI_ReleasePrimitiveArrayCritical,
4215 _Jv_JNI_GetStringCritical,
4216 _Jv_JNI_ReleaseStringCritical,
4218 _Jv_JNI_NewWeakGlobalRef,
4219 _Jv_JNI_DeleteWeakGlobalRef,
4221 _Jv_JNI_ExceptionCheck,
4223 /* New JNI 1.4 functions. */
4225 _Jv_JNI_NewDirectByteBuffer,
4226 _Jv_JNI_GetDirectBufferAddress,
4227 _Jv_JNI_GetDirectBufferCapacity,
4229 /* New JNI 1.6 functions. */
4231 jni_GetObjectRefType
4235 /* Invocation API Functions ***************************************************/
4237 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4239 Returns a default configuration for the Java VM.
4241 *******************************************************************************/
4243 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4245 JavaVMInitArgs *_vm_args;
4247 _vm_args = (JavaVMInitArgs *) vm_args;
4249 /* GNU classpath currently supports JNI 1.2 */
4251 switch (_vm_args->version) {
4252 case JNI_VERSION_1_1:
4253 _vm_args->version = JNI_VERSION_1_1;
4256 case JNI_VERSION_1_2:
4257 case JNI_VERSION_1_4:
4258 _vm_args->ignoreUnrecognized = JNI_FALSE;
4259 _vm_args->options = NULL;
4260 _vm_args->nOptions = 0;
4271 /* JNI_GetCreatedJavaVMs *******************************************************
4273 Returns all Java VMs that have been created. Pointers to VMs are written in
4274 the buffer vmBuf in the order they are created. At most bufLen number of
4275 entries will be written. The total number of created VMs is returned in
4278 *******************************************************************************/
4280 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4282 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4287 /* We currently only support 1 VM running. */
4289 vmBuf[0] = (JavaVM *) _Jv_jvm;
4296 /* JNI_CreateJavaVM ************************************************************
4298 Loads and initializes a Java VM. The current thread becomes the main thread.
4299 Sets the env argument to the JNI interface pointer of the main thread.
4301 *******************************************************************************/
4303 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4305 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4307 /* actually create the JVM */
4309 if (!vm_createjvm(p_vm, p_env, vm_args))
4317 * These are local overrides for various environment variables in Emacs.
4318 * Please do not remove this and leave it at the end of the file, where
4319 * Emacs will automagically detect them.
4320 * ---------------------------------------------------------------------
4323 * indent-tabs-mode: t
4327 * vim:noexpandtab:sw=4:ts=4: