1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/gc-common.h"
35 #include "mm/memory.h"
37 #include "native/jni.h"
38 #include "native/llni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
42 #if defined(ENABLE_JAVASE)
43 # if defined(WITH_CLASSPATH_GNU)
44 # include "native/include/gnu_classpath_Pointer.h"
46 # if SIZEOF_VOID_P == 8
47 # include "native/include/gnu_classpath_Pointer64.h"
49 # include "native/include/gnu_classpath_Pointer32.h"
54 #include "native/include/java_lang_Object.h"
55 #include "native/include/java_lang_String.h"
56 #include "native/include/java_lang_Throwable.h"
58 #if defined(ENABLE_JAVASE)
59 # if defined(WITH_CLASSPATH_SUN)
60 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
63 /* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
64 we pre-define it here to prevent a compiler warning for Sun
67 struct java_lang_ClassLoader;
69 # include "native/include/java_lang_Class.h"
70 # include "native/include/java_lang_ClassLoader.h"
72 # include "native/include/java_lang_reflect_Constructor.h"
73 # include "native/include/java_lang_reflect_Field.h"
74 # include "native/include/java_lang_reflect_Method.h"
76 # include "native/include/java_nio_Buffer.h"
78 # if defined(WITH_CLASSPATH_GNU)
79 # include "native/include/java_nio_DirectByteBufferImpl.h"
83 #if defined(ENABLE_JVMTI)
84 # include "native/jvmti/cacaodbg.h"
87 #include "native/vm/java_lang_Class.h"
89 #if defined(ENABLE_JAVASE)
90 # include "native/vm/reflect.h"
93 #include "threads/lock-common.h"
94 #include "threads/threads-common.h"
96 #include "toolbox/logging.h"
99 #include "vm/builtin.h"
100 #include "vm/exceptions.h"
101 #include "vm/global.h"
102 #include "vm/initialize.h"
103 #include "vm/primitive.h"
104 #include "vm/resolve.h"
105 #include "vm/stringlocal.h"
108 #include "vm/jit/argument.h"
109 #include "vm/jit/asmpart.h"
110 #include "vm/jit/jit.h"
111 #include "vm/jit/stacktrace.h"
113 #include "vmcore/loader.h"
114 #include "vmcore/options.h"
115 #include "vmcore/statistics.h"
118 /* debug **********************************************************************/
121 # define TRACEJNICALLS(text) \
123 if (opt_TraceJNICalls) { \
128 # define TRACEJNICALLS(text)
132 /* global variables ***********************************************************/
134 /* global reference table *****************************************************/
136 /* hashsize must be power of 2 */
138 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
140 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
143 /* direct buffer stuff ********************************************************/
145 #if defined(ENABLE_JAVASE)
146 static classinfo *class_java_nio_Buffer;
148 # if defined(WITH_CLASSPATH_GNU)
150 static classinfo *class_java_nio_DirectByteBufferImpl;
151 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
153 # if SIZEOF_VOID_P == 8
154 static classinfo *class_gnu_classpath_Pointer64;
156 static classinfo *class_gnu_classpath_Pointer32;
159 static methodinfo *dbbirw_init;
161 # elif defined(WITH_CLASSPATH_SUN)
163 static classinfo *class_sun_nio_ch_DirectBuffer;
164 static classinfo *class_java_nio_DirectByteBuffer;
166 static methodinfo *dbb_init;
172 /* some forward declarations **************************************************/
174 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
177 /* jni_init ********************************************************************
179 Initialize the JNI subsystem.
181 *******************************************************************************/
185 TRACESUBSYSTEMINITIALIZATION("jni_init");
187 /* create global ref hashtable */
189 hashtable_global_ref = NEW(hashtable);
191 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
194 #if defined(ENABLE_JAVASE)
195 /* Direct buffer stuff. */
197 if (!(class_java_nio_Buffer =
198 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
199 !link_class(class_java_nio_Buffer))
202 # if defined(WITH_CLASSPATH_GNU)
204 if (!(class_java_nio_DirectByteBufferImpl =
205 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
206 !link_class(class_java_nio_DirectByteBufferImpl))
209 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
210 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
211 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
215 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
217 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
220 # if SIZEOF_VOID_P == 8
221 if (!(class_gnu_classpath_Pointer64 =
222 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
223 !link_class(class_gnu_classpath_Pointer64))
226 if (!(class_gnu_classpath_Pointer32 =
227 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
228 !link_class(class_gnu_classpath_Pointer32))
232 # elif defined(WITH_CLASSPATH_SUN)
234 if (!(class_sun_nio_ch_DirectBuffer =
235 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
236 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
238 if (!link_class(class_sun_nio_ch_DirectBuffer))
239 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
241 if (!(class_java_nio_DirectByteBuffer =
242 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
243 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
245 if (!link_class(class_java_nio_DirectByteBuffer))
246 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
249 class_resolvemethod(class_java_nio_DirectByteBuffer,
251 utf_new_char("(JI)V"))))
252 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
256 #endif /* defined(ENABLE_JAVASE) */
262 /* jni_version_check ***********************************************************
264 Check if the given JNI version is supported.
267 version....JNI version to check
271 false......not supported
273 *******************************************************************************/
275 bool jni_version_check(int version)
278 case JNI_VERSION_1_1:
279 case JNI_VERSION_1_2:
280 case JNI_VERSION_1_4:
281 case JNI_VERSION_1_6:
289 /* _Jv_jni_CallObjectMethod ****************************************************
291 Internal function to call Java Object methods.
293 *******************************************************************************/
295 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
297 methodinfo *m, va_list ap)
302 STATISTICS(jniinvokation());
305 exceptions_throw_nullpointerexception();
309 /* Class initialization is done by the JIT compiler. This is ok
310 since a static method always belongs to the declaring class. */
312 if (m->flags & ACC_STATIC) {
313 /* For static methods we reset the object. */
318 /* for convenience */
323 /* For instance methods we make a virtual function table lookup. */
325 resm = method_vftbl_lookup(vftbl, m);
328 STATISTICS(jnicallXmethodnvokation());
330 ro = vm_call_method_valist(resm, o, ap);
336 /* _Jv_jni_CallObjectMethodA ***************************************************
338 Internal function to call Java Object methods.
340 *******************************************************************************/
342 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
350 STATISTICS(jniinvokation());
353 exceptions_throw_nullpointerexception();
357 /* Class initialization is done by the JIT compiler. This is ok
358 since a static method always belongs to the declaring class. */
360 if (m->flags & ACC_STATIC) {
361 /* For static methods we reset the object. */
366 /* for convenience */
371 /* For instance methods we make a virtual function table lookup. */
373 resm = method_vftbl_lookup(vftbl, m);
376 STATISTICS(jnicallXmethodnvokation());
378 ro = vm_call_method_jvalue(resm, o, args);
384 /* _Jv_jni_CallIntMethod *******************************************************
386 Internal function to call Java integer class methods (boolean,
387 byte, char, short, int).
389 *******************************************************************************/
391 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
392 methodinfo *m, va_list ap)
397 STATISTICS(jniinvokation());
400 exceptions_throw_nullpointerexception();
404 /* Class initialization is done by the JIT compiler. This is ok
405 since a static method always belongs to the declaring class. */
407 if (m->flags & ACC_STATIC) {
408 /* For static methods we reset the object. */
413 /* for convenience */
418 /* For instance methods we make a virtual function table lookup. */
420 resm = method_vftbl_lookup(vftbl, m);
423 STATISTICS(jnicallXmethodnvokation());
425 i = vm_call_method_int_valist(resm, o, ap);
431 /* _Jv_jni_CallIntMethodA ******************************************************
433 Internal function to call Java integer class methods (boolean,
434 byte, char, short, int).
436 *******************************************************************************/
438 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
439 methodinfo *m, const jvalue *args)
444 STATISTICS(jniinvokation());
447 exceptions_throw_nullpointerexception();
451 /* Class initialization is done by the JIT compiler. This is ok
452 since a static method always belongs to the declaring class. */
454 if (m->flags & ACC_STATIC) {
455 /* For static methods we reset the object. */
460 /* for convenience */
465 /* For instance methods we make a virtual function table lookup. */
467 resm = method_vftbl_lookup(vftbl, m);
470 STATISTICS(jnicallXmethodnvokation());
472 i = vm_call_method_int_jvalue(resm, o, args);
478 /* _Jv_jni_CallLongMethod ******************************************************
480 Internal function to call Java long methods.
482 *******************************************************************************/
484 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
485 methodinfo *m, va_list ap)
490 STATISTICS(jniinvokation());
493 exceptions_throw_nullpointerexception();
497 /* Class initialization is done by the JIT compiler. This is ok
498 since a static method always belongs to the declaring class. */
500 if (m->flags & ACC_STATIC) {
501 /* For static methods we reset the object. */
506 /* for convenience */
511 /* For instance methods we make a virtual function table lookup. */
513 resm = method_vftbl_lookup(vftbl, m);
516 STATISTICS(jnicallXmethodnvokation());
518 l = vm_call_method_long_valist(resm, o, ap);
524 /* _Jv_jni_CallLongMethodA *****************************************************
526 Internal function to call Java long methods.
528 *******************************************************************************/
530 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
531 methodinfo *m, const jvalue *args)
536 STATISTICS(jniinvokation());
539 exceptions_throw_nullpointerexception();
543 /* Class initialization is done by the JIT compiler. This is ok
544 since a static method always belongs to the declaring class. */
546 if (m->flags & ACC_STATIC) {
547 /* For static methods we reset the object. */
552 /* for convenience */
557 /* For instance methods we make a virtual function table lookup. */
559 resm = method_vftbl_lookup(vftbl, m);
562 STATISTICS(jnicallXmethodnvokation());
564 l = vm_call_method_long_jvalue(resm, o, args);
570 /* _Jv_jni_CallFloatMethod *****************************************************
572 Internal function to call Java float methods.
574 *******************************************************************************/
576 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
577 methodinfo *m, va_list ap)
582 /* Class initialization is done by the JIT compiler. This is ok
583 since a static method always belongs to the declaring class. */
585 if (m->flags & ACC_STATIC) {
586 /* For static methods we reset the object. */
591 /* for convenience */
596 /* For instance methods we make a virtual function table lookup. */
598 resm = method_vftbl_lookup(vftbl, m);
601 STATISTICS(jnicallXmethodnvokation());
603 f = vm_call_method_float_valist(resm, o, ap);
609 /* _Jv_jni_CallFloatMethodA ****************************************************
611 Internal function to call Java float methods.
613 *******************************************************************************/
615 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
616 methodinfo *m, const jvalue *args)
621 /* Class initialization is done by the JIT compiler. This is ok
622 since a static method always belongs to the declaring class. */
624 if (m->flags & ACC_STATIC) {
625 /* For static methods we reset the object. */
630 /* for convenience */
635 /* For instance methods we make a virtual function table lookup. */
637 resm = method_vftbl_lookup(vftbl, m);
640 STATISTICS(jnicallXmethodnvokation());
642 f = vm_call_method_float_jvalue(resm, o, args);
648 /* _Jv_jni_CallDoubleMethod ****************************************************
650 Internal function to call Java double methods.
652 *******************************************************************************/
654 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
655 methodinfo *m, va_list ap)
660 /* Class initialization is done by the JIT compiler. This is ok
661 since a static method always belongs to the declaring class. */
663 if (m->flags & ACC_STATIC) {
664 /* For static methods we reset the object. */
669 /* for convenience */
674 /* For instance methods we make a virtual function table lookup. */
676 resm = method_vftbl_lookup(vftbl, m);
679 d = vm_call_method_double_valist(resm, o, ap);
685 /* _Jv_jni_CallDoubleMethodA ***************************************************
687 Internal function to call Java double methods.
689 *******************************************************************************/
691 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
692 methodinfo *m, const jvalue *args)
697 /* Class initialization is done by the JIT compiler. This is ok
698 since a static method always belongs to the declaring class. */
700 if (m->flags & ACC_STATIC) {
701 /* For static methods we reset the object. */
706 /* for convenience */
711 /* For instance methods we make a virtual function table lookup. */
713 resm = method_vftbl_lookup(vftbl, m);
716 d = vm_call_method_double_jvalue(resm, o, args);
722 /* _Jv_jni_CallVoidMethod ******************************************************
724 Internal function to call Java void methods.
726 *******************************************************************************/
728 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
729 methodinfo *m, va_list ap)
734 exceptions_throw_nullpointerexception();
738 /* Class initialization is done by the JIT compiler. This is ok
739 since a static method always belongs to the declaring class. */
741 if (m->flags & ACC_STATIC) {
742 /* For static methods we reset the object. */
747 /* for convenience */
752 /* For instance methods we make a virtual function table lookup. */
754 resm = method_vftbl_lookup(vftbl, m);
757 STATISTICS(jnicallXmethodnvokation());
759 (void) vm_call_method_valist(resm, o, ap);
763 /* _Jv_jni_CallVoidMethodA *****************************************************
765 Internal function to call Java void methods.
767 *******************************************************************************/
769 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
770 methodinfo *m, const jvalue *args)
775 exceptions_throw_nullpointerexception();
779 /* Class initialization is done by the JIT compiler. This is ok
780 since a static method always belongs to the declaring class. */
782 if (m->flags & ACC_STATIC) {
783 /* For static methods we reset the object. */
788 /* for convenience */
793 /* For instance methods we make a virtual function table lookup. */
795 resm = method_vftbl_lookup(vftbl, m);
798 STATISTICS(jnicallXmethodnvokation());
800 (void) vm_call_method_jvalue(resm, o, args);
804 /* _Jv_jni_invokeNative ********************************************************
806 Invoke a method on the given object with the given arguments.
808 For instance methods OBJ must be != NULL and the method is looked up
809 in the vftbl of the object.
811 For static methods, OBJ is ignored.
813 *******************************************************************************/
815 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
816 java_handle_objectarray_t *params)
824 exceptions_throw_nullpointerexception();
828 argcount = m->parseddesc->paramcount;
829 paramcount = argcount;
831 /* if method is non-static, remove the `this' pointer */
833 if (!(m->flags & ACC_STATIC))
836 /* For instance methods the object has to be an instance of the
837 class the method belongs to. For static methods the obj
838 parameter is ignored. */
840 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
841 exceptions_throw_illegalargumentexception();
845 /* check if we got the right number of arguments */
847 if (((params == NULL) && (paramcount != 0)) ||
848 (params && (LLNI_array_size(params) != paramcount)))
850 exceptions_throw_illegalargumentexception();
854 /* for instance methods we need an object */
856 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
857 /* XXX not sure if that is the correct exception */
858 exceptions_throw_nullpointerexception();
862 /* for static methods, zero object to make subsequent code simpler */
863 if (m->flags & ACC_STATIC)
867 /* for instance methods we must do a vftbl lookup */
868 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
871 /* for static methods, just for convenience */
875 ro = vm_call_method_objectarray(resm, o, params);
881 /* GetVersion ******************************************************************
883 Returns the major version number in the higher 16 bits and the
884 minor version number in the lower 16 bits.
886 *******************************************************************************/
888 jint _Jv_JNI_GetVersion(JNIEnv *env)
890 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
892 /* We support JNI 1.6. */
894 return JNI_VERSION_1_6;
898 /* Class Operations ***********************************************************/
900 /* DefineClass *****************************************************************
902 Loads a class from a buffer of raw class data. The buffer
903 containing the raw class data is not referenced by the VM after the
904 DefineClass call returns, and it may be discarded if desired.
906 *******************************************************************************/
908 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
909 const jbyte *buf, jsize bufLen)
911 #if defined(ENABLE_JAVASE)
917 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
919 u = utf_new_char(name);
920 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
922 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
924 co = LLNI_classinfo_wrap(c);
926 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
928 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
930 /* keep compiler happy */
937 /* FindClass *******************************************************************
939 This function loads a locally-defined class. It searches the
940 directories and zip files specified by the CLASSPATH environment
941 variable for the class with the specified name.
943 *******************************************************************************/
945 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
947 #if defined(ENABLE_JAVASE)
954 TRACEJNICALLS(("_Jv_JNI_FindClass(env=%p, name=%s)", env, name));
956 u = utf_new_char_classname((char *) name);
958 /* Check stacktrace for classloader, if one found use it,
959 otherwise use the system classloader. */
961 /* Quote from the JNI documentation:
963 In the Java 2 Platform, FindClass locates the class loader
964 associated with the current native method. If the native code
965 belongs to a system class, no class loader will be
966 involved. Otherwise, the proper class loader will be invoked to
967 load and link the named class. When FindClass is called through
968 the Invocation Interface, there is no current native method or
969 its associated class loader. In that case, the result of
970 ClassLoader.getBaseClassLoader is used." */
972 cc = stacktrace_get_current_class();
975 c = load_class_from_sysloader(u);
977 c = load_class_from_classloader(u, cc->classloader);
985 co = LLNI_classinfo_wrap(c);
987 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
989 #elif defined(ENABLE_JAVAME_CLDC1_1)
994 TRACEJNICALLS(("_Jv_JNI_FindClass(env=%p, name=%s)", env, name));
996 u = utf_new_char_classname((char *) name);
997 c = load_class_bootstrap(u);
1005 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1008 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1010 /* keep compiler happy */
1017 /* GetSuperclass ***************************************************************
1019 If clazz represents any class other than the class Object, then
1020 this function returns the object that represents the superclass of
1021 the class specified by clazz.
1023 *******************************************************************************/
1025 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1029 java_lang_Class *co;
1031 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
1033 c = LLNI_classinfo_unwrap(sub);
1038 super = class_get_superclass(c);
1040 co = LLNI_classinfo_wrap(super);
1042 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1046 /* IsAssignableFrom ************************************************************
1048 Determines whether an object of sub can be safely cast to sup.
1050 *******************************************************************************/
1052 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1054 java_lang_Class *csup;
1055 java_lang_Class *csub;
1057 csup = (java_lang_Class *) sup;
1058 csub = (java_lang_Class *) sub;
1060 STATISTICS(jniinvokation());
1062 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1066 /* Throw ***********************************************************************
1068 Causes a java.lang.Throwable object to be thrown.
1070 *******************************************************************************/
1072 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1076 STATISTICS(jniinvokation());
1078 o = (java_handle_t *) obj;
1080 exceptions_set_exception(o);
1086 /* ThrowNew ********************************************************************
1088 Constructs an exception object from the specified class with the
1089 message specified by message and causes that exception to be
1092 *******************************************************************************/
1094 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1100 STATISTICS(jniinvokation());
1102 c = LLNI_classinfo_unwrap(clazz);
1105 s = javastring_new_from_utf_string(msg);
1107 /* instantiate exception object */
1109 o = native_new_and_init_string(c, s);
1114 exceptions_set_exception(o);
1120 /* ExceptionOccurred ***********************************************************
1122 Determines if an exception is being thrown. The exception stays
1123 being thrown until either the native code calls ExceptionClear(),
1124 or the Java code handles the exception.
1126 *******************************************************************************/
1128 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1132 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1134 o = exceptions_get_exception();
1136 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1140 /* ExceptionDescribe ***********************************************************
1142 Prints an exception and a backtrace of the stack to a system
1143 error-reporting channel, such as stderr. This is a convenience
1144 routine provided for debugging.
1146 *******************************************************************************/
1148 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1154 TRACEJNICALLS(("_Jv_JNI_ExceptionDescribe(env=%p)", env));
1156 /* Clear exception, because we are probably calling Java code
1159 o = exceptions_get_and_clear_exception();
1162 /* get printStackTrace method from exception class */
1164 LLNI_class_get(o, c);
1166 m = class_resolveclassmethod(c,
1167 utf_printStackTrace,
1173 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1175 /* Print the stacktrace. */
1177 (void) vm_call_method(m, o);
1182 /* ExceptionClear **************************************************************
1184 Clears any exception that is currently being thrown. If no
1185 exception is currently being thrown, this routine has no effect.
1187 *******************************************************************************/
1189 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1191 STATISTICS(jniinvokation());
1193 exceptions_clear_exception();
1197 /* FatalError ******************************************************************
1199 Raises a fatal error and does not expect the VM to recover. This
1200 function does not return.
1202 *******************************************************************************/
1204 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1206 STATISTICS(jniinvokation());
1208 /* this seems to be the best way */
1210 vm_abort("JNI Fatal error: %s", msg);
1214 /* PushLocalFrame **************************************************************
1216 Creates a new local reference frame, in which at least a given
1217 number of local references can be created.
1219 *******************************************************************************/
1221 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1223 STATISTICS(jniinvokation());
1228 /* add new local reference frame to current table */
1230 if (!localref_frame_push(capacity))
1237 /* PopLocalFrame ***************************************************************
1239 Pops off the current local reference frame, frees all the local
1240 references, and returns a local reference in the previous local
1241 reference frame for the given result object.
1243 *******************************************************************************/
1245 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1247 STATISTICS(jniinvokation());
1249 /* release all current local frames */
1251 localref_frame_pop_all();
1253 /* add local reference and return the value */
1255 return _Jv_JNI_NewLocalRef(env, result);
1259 /* DeleteLocalRef **************************************************************
1261 Deletes the local reference pointed to by localRef.
1263 *******************************************************************************/
1265 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1269 STATISTICS(jniinvokation());
1271 o = (java_handle_t *) localRef;
1276 /* delete the reference */
1282 /* IsSameObject ****************************************************************
1284 Tests whether two references refer to the same Java object.
1286 *******************************************************************************/
1288 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1294 STATISTICS(jniinvokation());
1296 o1 = (java_handle_t *) ref1;
1297 o2 = (java_handle_t *) ref2;
1299 LLNI_CRITICAL_START;
1301 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1312 /* NewLocalRef *****************************************************************
1314 Creates a new local reference that refers to the same object as ref.
1316 *******************************************************************************/
1318 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1321 java_handle_t *localref;
1323 STATISTICS(jniinvokation());
1325 o = (java_handle_t *) ref;
1330 /* insert the reference */
1332 localref = localref_add(LLNI_DIRECT(o));
1334 return (jobject) localref;
1338 /* EnsureLocalCapacity *********************************************************
1340 Ensures that at least a given number of local references can be
1341 created in the current thread
1343 *******************************************************************************/
1345 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1347 localref_table *lrt;
1349 STATISTICS(jniinvokation());
1351 /* get local reference table (thread specific) */
1353 lrt = LOCALREFTABLE;
1355 /* check if capacity elements are available in the local references table */
1357 if ((lrt->used + capacity) > lrt->capacity)
1358 return _Jv_JNI_PushLocalFrame(env, capacity);
1364 /* AllocObject *****************************************************************
1366 Allocates a new Java object without invoking any of the
1367 constructors for the object. Returns a reference to the object.
1369 *******************************************************************************/
1371 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1376 STATISTICS(jniinvokation());
1378 c = LLNI_classinfo_unwrap(clazz);
1380 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1381 exceptions_throw_instantiationexception(c);
1387 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1391 /* NewObject *******************************************************************
1393 Programmers place all arguments that are to be passed to the
1394 constructor immediately following the methodID
1395 argument. NewObject() accepts these arguments and passes them to
1396 the Java method that the programmer wishes to invoke.
1398 *******************************************************************************/
1400 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1407 STATISTICS(jniinvokation());
1409 c = LLNI_classinfo_unwrap(clazz);
1410 m = (methodinfo *) methodID;
1419 /* call constructor */
1421 va_start(ap, methodID);
1422 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1425 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1429 /* NewObjectV ******************************************************************
1431 Programmers place all arguments that are to be passed to the
1432 constructor in an args argument of type va_list that immediately
1433 follows the methodID argument. NewObjectV() accepts these
1434 arguments, and, in turn, passes them to the Java method that the
1435 programmer wishes to invoke.
1437 *******************************************************************************/
1439 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1446 STATISTICS(jniinvokation());
1448 c = LLNI_classinfo_unwrap(clazz);
1449 m = (methodinfo *) methodID;
1458 /* call constructor */
1460 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1462 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1466 /* NewObjectA *****************************************************************
1468 Programmers place all arguments that are to be passed to the
1469 constructor in an args array of jvalues that immediately follows
1470 the methodID argument. NewObjectA() accepts the arguments in this
1471 array, and, in turn, passes them to the Java method that the
1472 programmer wishes to invoke.
1474 *******************************************************************************/
1476 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1483 STATISTICS(jniinvokation());
1485 c = LLNI_classinfo_unwrap(clazz);
1486 m = (methodinfo *) methodID;
1495 /* call constructor */
1497 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1499 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1503 /* GetObjectClass **************************************************************
1505 Returns the class of an object.
1507 *******************************************************************************/
1509 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1513 java_lang_Class *co;
1515 STATISTICS(jniinvokation());
1517 o = (java_handle_t *) obj;
1519 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1522 LLNI_class_get(o, c);
1524 co = LLNI_classinfo_wrap(c);
1526 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1530 /* IsInstanceOf ****************************************************************
1532 Tests whether an object is an instance of a class.
1534 *******************************************************************************/
1536 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1539 java_lang_Object *o;
1541 STATISTICS(jniinvokation());
1543 c = (java_lang_Class *) clazz;
1544 o = (java_lang_Object *) obj;
1546 return _Jv_java_lang_Class_isInstance(c, o);
1550 /* Reflection Support *********************************************************/
1552 /* FromReflectedMethod *********************************************************
1554 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1555 object to a method ID.
1557 *******************************************************************************/
1559 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1561 #if defined(ENABLE_JAVASE)
1567 STATISTICS(jniinvokation());
1569 o = (java_handle_t *) method;
1574 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1575 java_lang_reflect_Method *rm;
1577 rm = (java_lang_reflect_Method *) method;
1578 LLNI_field_get_cls(rm, clazz, c);
1579 LLNI_field_get_val(rm, slot , slot);
1581 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1582 java_lang_reflect_Constructor *rc;
1584 rc = (java_lang_reflect_Constructor *) method;
1585 LLNI_field_get_cls(rc, clazz, c);
1586 LLNI_field_get_val(rc, slot , slot);
1591 m = &(c->methods[slot]);
1593 return (jmethodID) m;
1595 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1597 /* keep compiler happy */
1604 /* FromReflectedField **********************************************************
1606 Converts a java.lang.reflect.Field to a field ID.
1608 *******************************************************************************/
1610 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1612 #if defined(ENABLE_JAVASE)
1613 java_lang_reflect_Field *rf;
1618 STATISTICS(jniinvokation());
1620 rf = (java_lang_reflect_Field *) field;
1625 LLNI_field_get_cls(rf, clazz, c);
1626 LLNI_field_get_val(rf, slot , slot);
1627 f = &(c->fields[slot]);
1629 return (jfieldID) f;
1631 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1633 /* keep compiler happy */
1640 /* ToReflectedMethod ***********************************************************
1642 Converts a method ID derived from cls to an instance of the
1643 java.lang.reflect.Method class or to an instance of the
1644 java.lang.reflect.Constructor class.
1646 *******************************************************************************/
1648 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1651 #if defined(ENABLE_JAVASE)
1653 java_lang_reflect_Constructor *rc;
1654 java_lang_reflect_Method *rm;
1656 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1658 m = (methodinfo *) methodID;
1660 /* HotSpot does the same assert. */
1662 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1664 if (m->name == utf_init) {
1665 rc = reflect_constructor_new(m);
1667 return (jobject) rc;
1670 rm = reflect_method_new(m);
1672 return (jobject) rm;
1675 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1677 /* keep compiler happy */
1684 /* ToReflectedField ************************************************************
1686 Converts a field ID derived from cls to an instance of the
1687 java.lang.reflect.Field class.
1689 *******************************************************************************/
1691 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1694 STATISTICS(jniinvokation());
1696 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1702 /* Calling Instance Methods ***************************************************/
1704 /* GetMethodID *****************************************************************
1706 Returns the method ID for an instance (nonstatic) method of a class
1707 or interface. The method may be defined in one of the clazz's
1708 superclasses and inherited by clazz. The method is determined by
1709 its name and signature.
1711 GetMethodID() causes an uninitialized class to be initialized.
1713 *******************************************************************************/
1715 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1723 STATISTICS(jniinvokation());
1725 c = LLNI_classinfo_unwrap(clazz);
1730 if (!(c->state & CLASS_INITIALIZED))
1731 if (!initialize_class(c))
1734 /* try to get the method of the class or one of it's superclasses */
1736 uname = utf_new_char((char *) name);
1737 udesc = utf_new_char((char *) sig);
1739 m = class_resolvemethod(c, uname, udesc);
1741 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1742 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1747 return (jmethodID) m;
1751 /* JNI-functions for calling instance methods *********************************/
1753 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1754 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1755 jmethodID methodID, ...) \
1762 o = (java_handle_t *) obj; \
1763 m = (methodinfo *) methodID; \
1765 va_start(ap, methodID); \
1766 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1772 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1773 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1774 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1775 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1776 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1777 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1778 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1779 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1782 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1783 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1784 jmethodID methodID, va_list args) \
1790 o = (java_handle_t *) obj; \
1791 m = (methodinfo *) methodID; \
1793 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1798 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1799 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1800 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1801 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1802 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1803 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1804 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1805 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1808 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1809 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1810 jmethodID methodID, \
1811 const jvalue *args) \
1817 o = (java_handle_t *) obj; \
1818 m = (methodinfo *) methodID; \
1820 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1825 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1826 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1827 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1828 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1829 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1830 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1831 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1832 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1835 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1843 o = (java_handle_t *) obj;
1844 m = (methodinfo *) methodID;
1846 va_start(ap, methodID);
1847 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1850 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1854 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1861 o = (java_handle_t *) obj;
1862 m = (methodinfo *) methodID;
1864 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1866 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1870 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1877 o = (java_handle_t *) obj;
1878 m = (methodinfo *) methodID;
1880 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1882 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1887 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1893 o = (java_handle_t *) obj;
1894 m = (methodinfo *) methodID;
1896 va_start(ap, methodID);
1897 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1902 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1908 o = (java_handle_t *) obj;
1909 m = (methodinfo *) methodID;
1911 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1915 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1921 o = (java_handle_t *) obj;
1922 m = (methodinfo *) methodID;
1924 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1929 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1930 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1931 jclass clazz, jmethodID methodID, \
1940 o = (java_handle_t *) obj; \
1941 c = LLNI_classinfo_unwrap(clazz); \
1942 m = (methodinfo *) methodID; \
1944 va_start(ap, methodID); \
1945 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1951 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1952 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1953 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1954 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1955 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1956 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1957 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1958 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1961 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1962 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1963 jclass clazz, jmethodID methodID, \
1971 o = (java_handle_t *) obj; \
1972 c = LLNI_classinfo_unwrap(clazz); \
1973 m = (methodinfo *) methodID; \
1975 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1980 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1981 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1982 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1983 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1984 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1985 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1986 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1987 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1990 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1991 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1992 jclass clazz, jmethodID methodID, \
1993 const jvalue *args) \
1995 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2000 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2001 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2002 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2003 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2004 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2005 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2006 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2007 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2009 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2010 jclass clazz, jmethodID methodID,
2019 o = (java_handle_t *) obj;
2020 c = LLNI_classinfo_unwrap(clazz);
2021 m = (methodinfo *) methodID;
2023 va_start(ap, methodID);
2024 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2027 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2031 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2032 jclass clazz, jmethodID methodID,
2040 o = (java_handle_t *) obj;
2041 c = LLNI_classinfo_unwrap(clazz);
2042 m = (methodinfo *) methodID;
2044 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2046 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2050 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2051 jclass clazz, jmethodID methodID,
2054 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2056 return _Jv_JNI_NewLocalRef(env, NULL);
2060 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2061 jmethodID methodID, ...)
2068 o = (java_handle_t *) obj;
2069 c = LLNI_classinfo_unwrap(clazz);
2070 m = (methodinfo *) methodID;
2072 va_start(ap, methodID);
2073 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2078 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2079 jmethodID methodID, va_list args)
2085 o = (java_handle_t *) obj;
2086 c = LLNI_classinfo_unwrap(clazz);
2087 m = (methodinfo *) methodID;
2089 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2093 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2094 jmethodID methodID, const jvalue * args)
2100 o = (java_handle_t *) obj;
2101 c = LLNI_classinfo_unwrap(clazz);
2102 m = (methodinfo *) methodID;
2104 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2108 /* Accessing Fields of Objects ************************************************/
2110 /* GetFieldID ******************************************************************
2112 Returns the field ID for an instance (nonstatic) field of a
2113 class. The field is specified by its name and signature. The
2114 Get<type>Field and Set<type>Field families of accessor functions
2115 use field IDs to retrieve object fields.
2117 *******************************************************************************/
2119 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2127 STATISTICS(jniinvokation());
2129 c = LLNI_classinfo_unwrap(clazz);
2131 /* XXX NPE check? */
2133 uname = utf_new_char((char *) name);
2134 udesc = utf_new_char((char *) sig);
2136 f = class_findfield(c, uname, udesc);
2139 exceptions_throw_nosuchfielderror(c, uname);
2141 return (jfieldID) f;
2145 /* Get<type>Field Routines *****************************************************
2147 This family of accessor routines returns the value of an instance
2148 (nonstatic) field of an object. The field to access is specified by
2149 a field ID obtained by calling GetFieldID().
2151 *******************************************************************************/
2153 #define GET_FIELD(o,type,f) \
2154 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2156 #define JNI_GET_FIELD(name, type, intern) \
2157 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2161 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2163 LLNI_CRITICAL_START; \
2165 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2167 LLNI_CRITICAL_END; \
2169 return (type) ret; \
2172 JNI_GET_FIELD(Boolean, jboolean, s4)
2173 JNI_GET_FIELD(Byte, jbyte, s4)
2174 JNI_GET_FIELD(Char, jchar, s4)
2175 JNI_GET_FIELD(Short, jshort, s4)
2176 JNI_GET_FIELD(Int, jint, s4)
2177 JNI_GET_FIELD(Long, jlong, s8)
2178 JNI_GET_FIELD(Float, jfloat, float)
2179 JNI_GET_FIELD(Double, jdouble, double)
2182 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2186 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2188 LLNI_CRITICAL_START;
2190 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2194 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2198 /* Set<type>Field Routines *****************************************************
2200 This family of accessor routines sets the value of an instance
2201 (nonstatic) field of an object. The field to access is specified by
2202 a field ID obtained by calling GetFieldID().
2204 *******************************************************************************/
2206 #define SET_FIELD(o,type,f,value) \
2207 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2209 #define JNI_SET_FIELD(name, type, intern) \
2210 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2213 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2215 LLNI_CRITICAL_START; \
2217 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2219 LLNI_CRITICAL_START; \
2222 JNI_SET_FIELD(Boolean, jboolean, s4)
2223 JNI_SET_FIELD(Byte, jbyte, s4)
2224 JNI_SET_FIELD(Char, jchar, s4)
2225 JNI_SET_FIELD(Short, jshort, s4)
2226 JNI_SET_FIELD(Int, jint, s4)
2227 JNI_SET_FIELD(Long, jlong, s8)
2228 JNI_SET_FIELD(Float, jfloat, float)
2229 JNI_SET_FIELD(Double, jdouble, double)
2232 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2235 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2237 LLNI_CRITICAL_START;
2239 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2245 /* Calling Static Methods *****************************************************/
2247 /* GetStaticMethodID ***********************************************************
2249 Returns the method ID for a static method of a class. The method is
2250 specified by its name and signature.
2252 GetStaticMethodID() causes an uninitialized class to be
2255 *******************************************************************************/
2257 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2265 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2267 c = LLNI_classinfo_unwrap(clazz);
2272 if (!(c->state & CLASS_INITIALIZED))
2273 if (!initialize_class(c))
2276 /* try to get the static method of the class */
2278 uname = utf_new_char((char *) name);
2279 udesc = utf_new_char((char *) sig);
2281 m = class_resolvemethod(c, uname, udesc);
2283 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2284 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2289 return (jmethodID) m;
2293 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2294 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2295 jmethodID methodID, ...) \
2301 m = (methodinfo *) methodID; \
2303 va_start(ap, methodID); \
2304 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2310 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2311 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2312 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2313 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2314 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2315 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2316 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2317 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2320 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2321 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2322 jmethodID methodID, va_list args) \
2327 m = (methodinfo *) methodID; \
2329 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2334 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2335 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2336 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2337 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2338 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2339 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2340 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2341 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2344 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2345 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2346 jmethodID methodID, const jvalue *args) \
2351 m = (methodinfo *) methodID; \
2353 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2358 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2359 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2360 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2361 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2362 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2363 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2364 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2365 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2368 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2369 jmethodID methodID, ...)
2375 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2377 m = (methodinfo *) methodID;
2379 va_start(ap, methodID);
2380 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2383 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2387 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2388 jmethodID methodID, va_list args)
2393 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2395 m = (methodinfo *) methodID;
2397 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2399 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2403 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2404 jmethodID methodID, const jvalue *args)
2409 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2411 m = (methodinfo *) methodID;
2413 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2415 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2419 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2420 jmethodID methodID, ...)
2425 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2427 m = (methodinfo *) methodID;
2429 va_start(ap, methodID);
2430 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2435 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2436 jmethodID methodID, va_list args)
2440 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2442 m = (methodinfo *) methodID;
2444 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2448 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2449 jmethodID methodID, const jvalue * args)
2453 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2455 m = (methodinfo *) methodID;
2457 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2461 /* Accessing Static Fields ****************************************************/
2463 /* GetStaticFieldID ************************************************************
2465 Returns the field ID for a static field of a class. The field is
2466 specified by its name and signature. The GetStatic<type>Field and
2467 SetStatic<type>Field families of accessor functions use field IDs
2468 to retrieve static fields.
2470 *******************************************************************************/
2472 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2480 STATISTICS(jniinvokation());
2482 c = LLNI_classinfo_unwrap(clazz);
2484 uname = utf_new_char((char *) name);
2485 usig = utf_new_char((char *) sig);
2487 f = class_findfield(c, uname, usig);
2490 exceptions_throw_nosuchfielderror(c, uname);
2492 return (jfieldID) f;
2496 /* GetStatic<type>Field ********************************************************
2498 This family of accessor routines returns the value of a static
2501 *******************************************************************************/
2503 #define JNI_GET_STATIC_FIELD(name, type, field) \
2504 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2510 STATISTICS(jniinvokation()); \
2512 c = LLNI_classinfo_unwrap(clazz); \
2513 f = (fieldinfo *) fieldID; \
2515 if (!(c->state & CLASS_INITIALIZED)) \
2516 if (!initialize_class(c)) \
2519 return f->value->field; \
2522 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2523 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2524 JNI_GET_STATIC_FIELD(Char, jchar, i)
2525 JNI_GET_STATIC_FIELD(Short, jshort, i)
2526 JNI_GET_STATIC_FIELD(Int, jint, i)
2527 JNI_GET_STATIC_FIELD(Long, jlong, l)
2528 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2529 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2532 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2539 STATISTICS(jniinvokation());
2541 c = LLNI_classinfo_unwrap(clazz);
2542 f = (fieldinfo *) fieldID;
2544 if (!(c->state & CLASS_INITIALIZED))
2545 if (!initialize_class(c))
2548 h = LLNI_WRAP(f->value->a);
2550 return _Jv_JNI_NewLocalRef(env, (jobject) h);
2554 /* SetStatic<type>Field *******************************************************
2556 This family of accessor routines sets the value of a static field
2559 *******************************************************************************/
2561 #define JNI_SET_STATIC_FIELD(name, type, field) \
2562 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2569 STATISTICS(jniinvokation()); \
2571 c = LLNI_classinfo_unwrap(clazz); \
2572 f = (fieldinfo *) fieldID; \
2574 if (!(c->state & CLASS_INITIALIZED)) \
2575 if (!initialize_class(c)) \
2578 f->value->field = value; \
2581 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2582 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2583 JNI_SET_STATIC_FIELD(Char, jchar, i)
2584 JNI_SET_STATIC_FIELD(Short, jshort, i)
2585 JNI_SET_STATIC_FIELD(Int, jint, i)
2586 JNI_SET_STATIC_FIELD(Long, jlong, l)
2587 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2588 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2591 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2597 STATISTICS(jniinvokation());
2599 c = LLNI_classinfo_unwrap(clazz);
2600 f = (fieldinfo *) fieldID;
2602 if (!(c->state & CLASS_INITIALIZED))
2603 if (!initialize_class(c))
2606 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2610 /* String Operations **********************************************************/
2612 /* NewString *******************************************************************
2614 Create new java.lang.String object from an array of Unicode
2617 *******************************************************************************/
2619 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2621 java_lang_String *s;
2622 java_handle_chararray_t *a;
2625 STATISTICS(jniinvokation());
2627 s = (java_lang_String *) builtin_new(class_java_lang_String);
2628 a = builtin_newarray_char(len);
2630 /* javastring or characterarray could not be created */
2631 if ((a == NULL) || (s == NULL))
2635 for (i = 0; i < len; i++)
2636 LLNI_array_direct(a, i) = buf[i];
2638 LLNI_field_set_ref(s, value , a);
2639 LLNI_field_set_val(s, offset, 0);
2640 LLNI_field_set_val(s, count , len);
2642 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2646 static jchar emptyStringJ[]={0,0};
2648 /* GetStringLength *************************************************************
2650 Returns the length (the count of Unicode characters) of a Java
2653 *******************************************************************************/
2655 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2657 java_lang_String *s;
2660 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2662 s = (java_lang_String *) str;
2664 LLNI_field_get_val(s, count, len);
2670 /******************** convertes javastring to u2-array ****************************/
2672 u2 *javastring_tou2(jstring so)
2674 java_lang_String *s;
2675 java_handle_chararray_t *a;
2681 STATISTICS(jniinvokation());
2683 s = (java_lang_String *) so;
2688 LLNI_field_get_ref(s, value, a);
2693 LLNI_field_get_val(s, count, count);
2694 LLNI_field_get_val(s, offset, offset);
2696 /* allocate memory */
2698 stringbuffer = MNEW(u2, count + 1);
2702 for (i = 0; i < count; i++)
2703 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2705 /* terminate string */
2707 stringbuffer[i] = '\0';
2709 return stringbuffer;
2713 /* GetStringChars **************************************************************
2715 Returns a pointer to the array of Unicode characters of the
2716 string. This pointer is valid until ReleaseStringChars() is called.
2718 *******************************************************************************/
2720 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2724 STATISTICS(jniinvokation());
2726 jc = javastring_tou2(str);
2738 return emptyStringJ;
2742 /* ReleaseStringChars **********************************************************
2744 Informs the VM that the native code no longer needs access to
2745 chars. The chars argument is a pointer obtained from string using
2748 *******************************************************************************/
2750 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2752 java_lang_String *s;
2754 STATISTICS(jniinvokation());
2756 if (chars == emptyStringJ)
2759 s = (java_lang_String *) str;
2761 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2765 /* NewStringUTF ****************************************************************
2767 Constructs a new java.lang.String object from an array of UTF-8
2770 *******************************************************************************/
2772 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2774 java_lang_String *s;
2776 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2778 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2780 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2784 /****************** returns the utf8 length in bytes of a string *******************/
2786 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2788 java_lang_String *s;
2791 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2793 s = (java_lang_String *) string;
2795 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2801 /* GetStringUTFChars ***********************************************************
2803 Returns a pointer to an array of UTF-8 characters of the
2804 string. This array is valid until it is released by
2805 ReleaseStringUTFChars().
2807 *******************************************************************************/
2809 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2814 STATISTICS(jniinvokation());
2822 u = javastring_toutf((java_handle_t *) string, false);
2831 /* ReleaseStringUTFChars *******************************************************
2833 Informs the VM that the native code no longer needs access to
2834 utf. The utf argument is a pointer derived from string using
2835 GetStringUTFChars().
2837 *******************************************************************************/
2839 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2841 STATISTICS(jniinvokation());
2843 /* XXX we don't release utf chars right now, perhaps that should be done
2844 later. Since there is always one reference the garbage collector will
2849 /* Array Operations ***********************************************************/
2851 /* GetArrayLength **************************************************************
2853 Returns the number of elements in the array.
2855 *******************************************************************************/
2857 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2862 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2864 a = (java_handle_t *) array;
2866 size = LLNI_array_size(a);
2872 /* NewObjectArray **************************************************************
2874 Constructs a new array holding objects in class elementClass. All
2875 elements are initially set to initialElement.
2877 *******************************************************************************/
2879 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2880 jclass elementClass, jobject initialElement)
2884 java_handle_objectarray_t *oa;
2887 STATISTICS(jniinvokation());
2889 c = LLNI_classinfo_unwrap(elementClass);
2890 o = (java_handle_t *) initialElement;
2893 exceptions_throw_negativearraysizeexception();
2897 oa = builtin_anewarray(length, c);
2902 /* set all elements to initialElement */
2904 for (i = 0; i < length; i++)
2905 array_objectarray_element_set(oa, i, o);
2907 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2911 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2914 java_handle_objectarray_t *oa;
2917 STATISTICS(jniinvokation());
2919 oa = (java_handle_objectarray_t *) array;
2921 if (index >= LLNI_array_size(oa)) {
2922 exceptions_throw_arrayindexoutofboundsexception();
2926 o = array_objectarray_element_get(oa, index);
2928 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2932 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2933 jsize index, jobject val)
2935 java_handle_objectarray_t *oa;
2938 STATISTICS(jniinvokation());
2940 oa = (java_handle_objectarray_t *) array;
2941 o = (java_handle_t *) val;
2943 if (index >= LLNI_array_size(oa)) {
2944 exceptions_throw_arrayindexoutofboundsexception();
2948 /* check if the class of value is a subclass of the element class
2951 if (!builtin_canstore(oa, o))
2954 array_objectarray_element_set(oa, index, o);
2958 #define JNI_NEW_ARRAY(name, type, intern) \
2959 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2961 java_handle_##intern##array_t *a; \
2963 STATISTICS(jniinvokation()); \
2966 exceptions_throw_negativearraysizeexception(); \
2970 a = builtin_newarray_##intern(len); \
2972 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2975 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2976 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2977 JNI_NEW_ARRAY(Char, jcharArray, char)
2978 JNI_NEW_ARRAY(Short, jshortArray, byte)
2979 JNI_NEW_ARRAY(Int, jintArray, int)
2980 JNI_NEW_ARRAY(Long, jlongArray, long)
2981 JNI_NEW_ARRAY(Float, jfloatArray, float)
2982 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2985 /* Get<PrimitiveType>ArrayElements *********************************************
2987 A family of functions that returns the body of the primitive array.
2989 *******************************************************************************/
2991 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2992 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2995 java_handle_##intern##array_t *a; \
2997 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2999 a = (java_handle_##intern##array_t *) array; \
3002 *isCopy = JNI_FALSE; \
3004 return (type *) LLNI_array_data(a); \
3007 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3008 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3009 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3010 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3011 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3012 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3013 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3014 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3017 /* Release<PrimitiveType>ArrayElements *****************************************
3019 A family of functions that informs the VM that the native code no
3020 longer needs access to elems. The elems argument is a pointer
3021 derived from array using the corresponding
3022 Get<PrimitiveType>ArrayElements() function. If necessary, this
3023 function copies back all changes made to elems to the original
3026 *******************************************************************************/
3028 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3029 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3030 type *elems, jint mode) \
3032 java_handle_##intern##array_t *a; \
3034 STATISTICS(jniinvokation()); \
3036 a = (java_handle_##intern##array_t *) array; \
3038 if (elems != (type *) LLNI_array_data(a)) { \
3041 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3044 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3045 /* XXX TWISTI how should it be freed? */ \
3048 /* XXX TWISTI how should it be freed? */ \
3054 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3055 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3056 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3057 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3058 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3059 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3060 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3061 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3064 /* Get<PrimitiveType>ArrayRegion **********************************************
3066 A family of functions that copies a region of a primitive array
3069 *******************************************************************************/
3071 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3072 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3073 jsize start, jsize len, type *buf) \
3075 java_handle_##intern##array_t *a; \
3077 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3079 a = (java_handle_##intern##array_t *) array; \
3081 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3082 exceptions_throw_arrayindexoutofboundsexception(); \
3084 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3087 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3088 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3089 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3090 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3091 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3092 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3093 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3094 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3097 /* Set<PrimitiveType>ArrayRegion **********************************************
3099 A family of functions that copies back a region of a primitive
3100 array from a buffer.
3102 *******************************************************************************/
3104 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3105 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3106 jsize start, jsize len, const type *buf) \
3108 java_handle_##intern##array_t *a; \
3110 STATISTICS(jniinvokation()); \
3112 a = (java_handle_##intern##array_t *) array; \
3114 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3115 exceptions_throw_arrayindexoutofboundsexception(); \
3117 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3120 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3121 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3122 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3123 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3124 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3125 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3126 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3127 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3130 /* Registering Native Methods *************************************************/
3132 /* RegisterNatives *************************************************************
3134 Registers native methods with the class specified by the clazz
3135 argument. The methods parameter specifies an array of
3136 JNINativeMethod structures that contain the names, signatures, and
3137 function pointers of the native methods. The nMethods parameter
3138 specifies the number of native methods in the array.
3140 *******************************************************************************/
3142 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3143 const JNINativeMethod *methods, jint nMethods)
3147 STATISTICS(jniinvokation());
3149 c = LLNI_classinfo_unwrap(clazz);
3151 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3152 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3155 native_method_register(c->name, methods, nMethods);
3161 /* UnregisterNatives ***********************************************************
3163 Unregisters native methods of a class. The class goes back to the
3164 state before it was linked or registered with its native method
3167 This function should not be used in normal native code. Instead, it
3168 provides special programs a way to reload and relink native
3171 *******************************************************************************/
3173 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3175 STATISTICS(jniinvokation());
3177 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3179 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3185 /* Monitor Operations *********************************************************/
3187 /* MonitorEnter ****************************************************************
3189 Enters the monitor associated with the underlying Java object
3192 *******************************************************************************/
3194 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3196 STATISTICS(jniinvokation());
3199 exceptions_throw_nullpointerexception();
3203 LOCK_MONITOR_ENTER(obj);
3209 /* MonitorExit *****************************************************************
3211 The current thread must be the owner of the monitor associated with
3212 the underlying Java object referred to by obj. The thread
3213 decrements the counter indicating the number of times it has
3214 entered this monitor. If the value of the counter becomes zero, the
3215 current thread releases the monitor.
3217 *******************************************************************************/
3219 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3221 STATISTICS(jniinvokation());
3224 exceptions_throw_nullpointerexception();
3228 LOCK_MONITOR_EXIT(obj);
3234 /* JavaVM Interface ***********************************************************/
3236 /* GetJavaVM *******************************************************************
3238 Returns the Java VM interface (used in the Invocation API)
3239 associated with the current thread. The result is placed at the
3240 location pointed to by the second argument, vm.
3242 *******************************************************************************/
3244 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3246 STATISTICS(jniinvokation());
3248 *vm = (JavaVM *) _Jv_jvm;
3254 /* GetStringRegion *************************************************************
3256 Copies len number of Unicode characters beginning at offset start
3257 to the given buffer buf.
3259 Throws StringIndexOutOfBoundsException on index overflow.
3261 *******************************************************************************/
3263 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3266 java_lang_String *s;
3267 java_handle_chararray_t *ca;
3269 STATISTICS(jniinvokation());
3271 s = (java_lang_String *) str;
3272 LLNI_field_get_ref(s, value, ca);
3274 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3275 (start + len > LLNI_field_direct(s, count))) {
3276 exceptions_throw_stringindexoutofboundsexception();
3280 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3284 /* GetStringUTFRegion **********************************************************
3286 Translates len number of Unicode characters beginning at offset
3287 start into UTF-8 format and place the result in the given buffer
3290 Throws StringIndexOutOfBoundsException on index overflow.
3292 *******************************************************************************/
3294 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3295 jsize len, char *buf)
3297 java_lang_String *s;
3298 java_handle_chararray_t *ca;
3303 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3305 s = (java_lang_String *) str;
3306 LLNI_field_get_ref(s, value, ca);
3307 LLNI_field_get_val(s, count, count);
3308 LLNI_field_get_val(s, offset, offset);
3310 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3311 exceptions_throw_stringindexoutofboundsexception();
3315 for (i = 0; i < len; i++)
3316 buf[i] = LLNI_array_direct(ca, offset + start + i);
3322 /* GetPrimitiveArrayCritical ***************************************************
3324 Obtain a direct pointer to array elements.
3326 *******************************************************************************/
3328 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3331 java_handle_bytearray_t *ba;
3334 ba = (java_handle_bytearray_t *) array;
3336 /* do the same as Kaffe does */
3338 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3344 /* ReleasePrimitiveArrayCritical ***********************************************
3346 No specific documentation.
3348 *******************************************************************************/
3350 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3351 void *carray, jint mode)
3353 STATISTICS(jniinvokation());
3355 /* do the same as Kaffe does */
3357 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3362 /* GetStringCritical ***********************************************************
3364 The semantics of these two functions are similar to the existing
3365 Get/ReleaseStringChars functions.
3367 *******************************************************************************/
3369 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3372 STATISTICS(jniinvokation());
3374 return _Jv_JNI_GetStringChars(env, string, isCopy);
3378 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3379 const jchar *cstring)
3381 STATISTICS(jniinvokation());
3383 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3387 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3389 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3395 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3397 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3401 /* NewGlobalRef ****************************************************************
3403 Creates a new global reference to the object referred to by the obj
3406 *******************************************************************************/
3408 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3410 hashtable_global_ref_entry *gre;
3411 u4 key; /* hashkey */
3412 u4 slot; /* slot in hashtable */
3415 STATISTICS(jniinvokation());
3417 o = (java_handle_t *) obj;
3419 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3421 LLNI_CRITICAL_START;
3423 /* normally addresses are aligned to 4, 8 or 16 bytes */
3425 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3426 slot = key & (hashtable_global_ref->size - 1);
3427 gre = hashtable_global_ref->ptr[slot];
3429 /* search external hash chain for the entry */
3432 if (gre->o == LLNI_DIRECT(o)) {
3433 /* global object found, increment the reference */
3440 gre = gre->hashlink; /* next element in external chain */
3445 /* global ref not found, create a new one */
3448 gre = NEW(hashtable_global_ref_entry);
3450 #if defined(ENABLE_GC_CACAO)
3451 /* register global ref with the GC */
3453 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3456 LLNI_CRITICAL_START;
3458 gre->o = LLNI_DIRECT(o);
3463 /* insert entry into hashtable */
3465 gre->hashlink = hashtable_global_ref->ptr[slot];
3467 hashtable_global_ref->ptr[slot] = gre;
3469 /* update number of hashtable-entries */
3471 hashtable_global_ref->entries++;
3474 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3476 #if defined(ENABLE_HANDLES)
3484 /* DeleteGlobalRef *************************************************************
3486 Deletes the global reference pointed to by globalRef.
3488 *******************************************************************************/
3490 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3492 hashtable_global_ref_entry *gre;
3493 hashtable_global_ref_entry *prevgre;
3494 u4 key; /* hashkey */
3495 u4 slot; /* slot in hashtable */
3498 STATISTICS(jniinvokation());
3500 o = (java_handle_t *) globalRef;
3502 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3504 LLNI_CRITICAL_START;
3506 /* normally addresses are aligned to 4, 8 or 16 bytes */
3508 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3509 slot = key & (hashtable_global_ref->size - 1);
3510 gre = hashtable_global_ref->ptr[slot];
3512 /* initialize prevgre */
3516 /* search external hash chain for the entry */
3519 if (gre->o == LLNI_DIRECT(o)) {
3520 /* global object found, decrement the reference count */
3524 /* if reference count is 0, remove the entry */
3526 if (gre->refs == 0) {
3527 /* special handling if it's the first in the chain */
3529 if (prevgre == NULL)
3530 hashtable_global_ref->ptr[slot] = gre->hashlink;
3532 prevgre->hashlink = gre->hashlink;
3534 #if defined(ENABLE_GC_CACAO)
3535 /* unregister global ref with the GC */
3537 gc_reference_unregister(&(gre->o));
3540 FREE(gre, hashtable_global_ref_entry);
3545 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3550 prevgre = gre; /* save current pointer for removal */
3551 gre = gre->hashlink; /* next element in external chain */
3554 log_println("JNI-DeleteGlobalRef: global reference not found");
3558 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3562 /* ExceptionCheck **************************************************************
3564 Returns JNI_TRUE when there is a pending exception; otherwise,
3567 *******************************************************************************/
3569 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3573 STATISTICS(jniinvokation());
3575 o = exceptions_get_exception();
3577 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3581 /* New JNI 1.4 functions ******************************************************/
3583 /* NewDirectByteBuffer *********************************************************
3585 Allocates and returns a direct java.nio.ByteBuffer referring to the
3586 block of memory starting at the memory address address and
3587 extending capacity bytes.
3589 *******************************************************************************/
3591 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3593 #if defined(ENABLE_JAVASE)
3594 # if defined(WITH_CLASSPATH_GNU)
3595 java_handle_t *nbuf;
3597 # if SIZEOF_VOID_P == 8
3598 gnu_classpath_Pointer64 *paddress;
3600 gnu_classpath_Pointer32 *paddress;
3603 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3605 /* alocate a gnu.classpath.Pointer{32,64} object */
3607 # if SIZEOF_VOID_P == 8
3608 if (!(paddress = (gnu_classpath_Pointer64 *)
3609 builtin_new(class_gnu_classpath_Pointer64)))
3611 if (!(paddress = (gnu_classpath_Pointer32 *)
3612 builtin_new(class_gnu_classpath_Pointer32)))
3616 /* fill gnu.classpath.Pointer{32,64} with address */
3618 LLNI_field_set_val(paddress, data, (ptrint) address);
3620 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3622 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3623 (jmethodID) dbbirw_init, NULL, paddress,
3624 (jint) capacity, (jint) capacity, (jint) 0);
3626 /* add local reference and return the value */
3628 return _Jv_JNI_NewLocalRef(env, nbuf);
3630 # elif defined(WITH_CLASSPATH_SUN)
3636 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3638 /* Be paranoid about address sign-extension. */
3640 addr = (int64_t) ((uintptr_t) address);
3641 cap = (int32_t) capacity;
3643 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3644 (jmethodID) dbb_init, addr, cap);
3646 /* Add local reference and return the value. */
3648 return _Jv_JNI_NewLocalRef(env, o);
3651 # error unknown classpath configuration
3655 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3657 /* keep compiler happy */
3664 /* GetDirectBufferAddress ******************************************************
3666 Fetches and returns the starting address of the memory region
3667 referenced by the given direct java.nio.Buffer.
3669 *******************************************************************************/
3671 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3673 #if defined(ENABLE_JAVASE)
3676 # if defined(WITH_CLASSPATH_GNU)
3678 java_nio_DirectByteBufferImpl *nbuf;
3679 gnu_classpath_Pointer *po;
3680 # if SIZEOF_VOID_P == 8
3681 gnu_classpath_Pointer64 *paddress;
3684 gnu_classpath_Pointer32 *paddress;
3689 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3691 /* Prevent compiler warning. */
3693 h = (java_handle_t *) buf;
3695 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3698 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3700 LLNI_field_get_ref(nbuf, address, po);
3702 # if SIZEOF_VOID_P == 8
3703 paddress = (gnu_classpath_Pointer64 *) po;
3705 paddress = (gnu_classpath_Pointer32 *) po;
3708 if (paddress == NULL)
3711 LLNI_field_get_val(paddress, data, address);
3713 p = (void *) (intptr_t) address;
3717 # elif defined(WITH_CLASSPATH_SUN)
3723 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3725 /* Prevent compiler warning. */
3727 h = (java_handle_t *) buf;
3729 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3732 o = (java_nio_Buffer *) buf;
3734 LLNI_field_get_val(o, address, address);
3736 p = (void *) (intptr_t) address;
3741 # error unknown classpath configuration
3746 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3748 /* keep compiler happy */
3756 /* GetDirectBufferCapacity *****************************************************
3758 Fetches and returns the capacity in bytes of the memory region
3759 referenced by the given direct java.nio.Buffer.
3761 *******************************************************************************/
3763 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3765 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3767 java_nio_Buffer *nbuf;
3770 STATISTICS(jniinvokation());
3772 o = (java_handle_t *) buf;
3774 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3777 nbuf = (java_nio_Buffer *) o;
3779 LLNI_field_get_val(nbuf, cap, capacity);
3783 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3785 /* keep compiler happy */
3792 /* GetObjectRefType ************************************************************
3794 Returns the type of the object referred to by the obj argument. The
3795 argument obj can either be a local, global or weak global
3798 *******************************************************************************/
3800 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3802 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3808 /* DestroyJavaVM ***************************************************************
3810 Unloads a Java VM and reclaims its resources. Only the main thread
3811 can unload the VM. The system waits until the main thread is only
3812 remaining user thread before it destroys the VM.
3814 *******************************************************************************/
3816 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3820 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3822 if (vm_created == false)
3825 status = vm_destroy(vm);
3831 /* AttachCurrentThread *********************************************************
3833 Attaches the current thread to a Java VM. Returns a JNI interface
3834 pointer in the JNIEnv argument.
3836 Trying to attach a thread that is already attached is a no-op.
3838 A native thread cannot be attached simultaneously to two Java VMs.
3840 When a thread is attached to the VM, the context class loader is
3841 the bootstrap loader.
3843 *******************************************************************************/
3845 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3847 #if defined(ENABLE_THREADS)
3848 JavaVMAttachArgs *vm_aargs;
3851 /* If the current thread has already been attached, this operation
3854 result = thread_current_is_attached();
3856 if (result == true) {
3862 vm_aargs = (JavaVMAttachArgs *) thr_args;
3864 if (vm_aargs != NULL) {
3865 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3866 (vm_aargs->version != JNI_VERSION_1_4))
3867 return JNI_EVERSION;
3870 if (!threads_attach_current_thread(vm_aargs, false))
3873 if (!localref_table_init())
3883 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3887 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3889 if (vm_created == false)
3892 result = jni_attach_current_thread(p_env, thr_args, false);
3898 /* DetachCurrentThread *********************************************************
3900 Detaches the current thread from a Java VM. All Java monitors held
3901 by this thread are released. All Java threads waiting for this
3902 thread to die are notified.
3904 In JDK 1.1, the main thread cannot be detached from the VM. It must
3905 call DestroyJavaVM to unload the entire VM.
3907 In the JDK, the main thread can be detached from the VM.
3909 The main thread, which is the thread that created the Java VM,
3910 cannot be detached from the VM. Instead, the main thread must call
3911 JNI_DestroyJavaVM() to unload the entire VM.
3913 *******************************************************************************/
3915 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3917 #if defined(ENABLE_THREADS)
3921 TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
3923 t = thread_get_current();
3929 /* If the given thread has already been detached, this operation
3932 result = thread_is_attached(t);
3934 if (result == false)
3937 /* We need to pop all frames before we can destroy the table. */
3939 localref_frame_pop_all();
3941 if (!localref_table_destroy())
3944 if (!threads_detach_thread(t))
3952 /* GetEnv **********************************************************************
3954 If the current thread is not attached to the VM, sets *env to NULL,
3955 and returns JNI_EDETACHED. If the specified version is not
3956 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3957 sets *env to the appropriate interface, and returns JNI_OK.
3959 *******************************************************************************/
3961 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3963 TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
3965 if (vm_created == false) {
3967 return JNI_EDETACHED;
3970 #if defined(ENABLE_THREADS)
3971 if (thread_get_current() == NULL) {
3974 return JNI_EDETACHED;
3978 /* Check the JNI version. */
3980 if (jni_version_check(version) == true) {
3985 #if defined(ENABLE_JVMTI)
3986 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3987 == JVMTI_VERSION_INTERFACE_JVMTI) {
3989 *env = (void *) jvmti_new_environment();
3998 return JNI_EVERSION;
4002 /* AttachCurrentThreadAsDaemon *************************************************
4004 Same semantics as AttachCurrentThread, but the newly-created
4005 java.lang.Thread instance is a daemon.
4007 If the thread has already been attached via either
4008 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
4009 simply sets the value pointed to by penv to the JNIEnv of the
4010 current thread. In this case neither AttachCurrentThread nor this
4011 routine have any effect on the daemon status of the thread.
4013 *******************************************************************************/
4015 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
4019 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
4021 if (vm_created == false)
4024 result = jni_attach_current_thread(penv, args, true);
4030 /* JNI invocation table *******************************************************/
4032 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4037 _Jv_JNI_DestroyJavaVM,
4038 _Jv_JNI_AttachCurrentThread,
4039 _Jv_JNI_DetachCurrentThread,
4041 _Jv_JNI_AttachCurrentThreadAsDaemon
4045 /* JNI function table *********************************************************/
4047 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4054 _Jv_JNI_DefineClass,
4056 _Jv_JNI_FromReflectedMethod,
4057 _Jv_JNI_FromReflectedField,
4058 _Jv_JNI_ToReflectedMethod,
4059 _Jv_JNI_GetSuperclass,
4060 _Jv_JNI_IsAssignableFrom,
4061 _Jv_JNI_ToReflectedField,
4065 _Jv_JNI_ExceptionOccurred,
4066 _Jv_JNI_ExceptionDescribe,
4067 _Jv_JNI_ExceptionClear,
4069 _Jv_JNI_PushLocalFrame,
4070 _Jv_JNI_PopLocalFrame,
4072 _Jv_JNI_NewGlobalRef,
4073 _Jv_JNI_DeleteGlobalRef,
4074 _Jv_JNI_DeleteLocalRef,
4075 _Jv_JNI_IsSameObject,
4076 _Jv_JNI_NewLocalRef,
4077 _Jv_JNI_EnsureLocalCapacity,
4079 _Jv_JNI_AllocObject,
4084 _Jv_JNI_GetObjectClass,
4085 _Jv_JNI_IsInstanceOf,
4087 _Jv_JNI_GetMethodID,
4089 _Jv_JNI_CallObjectMethod,
4090 _Jv_JNI_CallObjectMethodV,
4091 _Jv_JNI_CallObjectMethodA,
4092 _Jv_JNI_CallBooleanMethod,
4093 _Jv_JNI_CallBooleanMethodV,
4094 _Jv_JNI_CallBooleanMethodA,
4095 _Jv_JNI_CallByteMethod,
4096 _Jv_JNI_CallByteMethodV,
4097 _Jv_JNI_CallByteMethodA,
4098 _Jv_JNI_CallCharMethod,
4099 _Jv_JNI_CallCharMethodV,
4100 _Jv_JNI_CallCharMethodA,
4101 _Jv_JNI_CallShortMethod,
4102 _Jv_JNI_CallShortMethodV,
4103 _Jv_JNI_CallShortMethodA,
4104 _Jv_JNI_CallIntMethod,
4105 _Jv_JNI_CallIntMethodV,
4106 _Jv_JNI_CallIntMethodA,
4107 _Jv_JNI_CallLongMethod,
4108 _Jv_JNI_CallLongMethodV,
4109 _Jv_JNI_CallLongMethodA,
4110 _Jv_JNI_CallFloatMethod,
4111 _Jv_JNI_CallFloatMethodV,
4112 _Jv_JNI_CallFloatMethodA,
4113 _Jv_JNI_CallDoubleMethod,
4114 _Jv_JNI_CallDoubleMethodV,
4115 _Jv_JNI_CallDoubleMethodA,
4116 _Jv_JNI_CallVoidMethod,
4117 _Jv_JNI_CallVoidMethodV,
4118 _Jv_JNI_CallVoidMethodA,
4120 _Jv_JNI_CallNonvirtualObjectMethod,
4121 _Jv_JNI_CallNonvirtualObjectMethodV,
4122 _Jv_JNI_CallNonvirtualObjectMethodA,
4123 _Jv_JNI_CallNonvirtualBooleanMethod,
4124 _Jv_JNI_CallNonvirtualBooleanMethodV,
4125 _Jv_JNI_CallNonvirtualBooleanMethodA,
4126 _Jv_JNI_CallNonvirtualByteMethod,
4127 _Jv_JNI_CallNonvirtualByteMethodV,
4128 _Jv_JNI_CallNonvirtualByteMethodA,
4129 _Jv_JNI_CallNonvirtualCharMethod,
4130 _Jv_JNI_CallNonvirtualCharMethodV,
4131 _Jv_JNI_CallNonvirtualCharMethodA,
4132 _Jv_JNI_CallNonvirtualShortMethod,
4133 _Jv_JNI_CallNonvirtualShortMethodV,
4134 _Jv_JNI_CallNonvirtualShortMethodA,
4135 _Jv_JNI_CallNonvirtualIntMethod,
4136 _Jv_JNI_CallNonvirtualIntMethodV,
4137 _Jv_JNI_CallNonvirtualIntMethodA,
4138 _Jv_JNI_CallNonvirtualLongMethod,
4139 _Jv_JNI_CallNonvirtualLongMethodV,
4140 _Jv_JNI_CallNonvirtualLongMethodA,
4141 _Jv_JNI_CallNonvirtualFloatMethod,
4142 _Jv_JNI_CallNonvirtualFloatMethodV,
4143 _Jv_JNI_CallNonvirtualFloatMethodA,
4144 _Jv_JNI_CallNonvirtualDoubleMethod,
4145 _Jv_JNI_CallNonvirtualDoubleMethodV,
4146 _Jv_JNI_CallNonvirtualDoubleMethodA,
4147 _Jv_JNI_CallNonvirtualVoidMethod,
4148 _Jv_JNI_CallNonvirtualVoidMethodV,
4149 _Jv_JNI_CallNonvirtualVoidMethodA,
4153 _Jv_JNI_GetObjectField,
4154 _Jv_JNI_GetBooleanField,
4155 _Jv_JNI_GetByteField,
4156 _Jv_JNI_GetCharField,
4157 _Jv_JNI_GetShortField,
4158 _Jv_JNI_GetIntField,
4159 _Jv_JNI_GetLongField,
4160 _Jv_JNI_GetFloatField,
4161 _Jv_JNI_GetDoubleField,
4162 _Jv_JNI_SetObjectField,
4163 _Jv_JNI_SetBooleanField,
4164 _Jv_JNI_SetByteField,
4165 _Jv_JNI_SetCharField,
4166 _Jv_JNI_SetShortField,
4167 _Jv_JNI_SetIntField,
4168 _Jv_JNI_SetLongField,
4169 _Jv_JNI_SetFloatField,
4170 _Jv_JNI_SetDoubleField,
4172 _Jv_JNI_GetStaticMethodID,
4174 _Jv_JNI_CallStaticObjectMethod,
4175 _Jv_JNI_CallStaticObjectMethodV,
4176 _Jv_JNI_CallStaticObjectMethodA,
4177 _Jv_JNI_CallStaticBooleanMethod,
4178 _Jv_JNI_CallStaticBooleanMethodV,
4179 _Jv_JNI_CallStaticBooleanMethodA,
4180 _Jv_JNI_CallStaticByteMethod,
4181 _Jv_JNI_CallStaticByteMethodV,
4182 _Jv_JNI_CallStaticByteMethodA,
4183 _Jv_JNI_CallStaticCharMethod,
4184 _Jv_JNI_CallStaticCharMethodV,
4185 _Jv_JNI_CallStaticCharMethodA,
4186 _Jv_JNI_CallStaticShortMethod,
4187 _Jv_JNI_CallStaticShortMethodV,
4188 _Jv_JNI_CallStaticShortMethodA,
4189 _Jv_JNI_CallStaticIntMethod,
4190 _Jv_JNI_CallStaticIntMethodV,
4191 _Jv_JNI_CallStaticIntMethodA,
4192 _Jv_JNI_CallStaticLongMethod,
4193 _Jv_JNI_CallStaticLongMethodV,
4194 _Jv_JNI_CallStaticLongMethodA,
4195 _Jv_JNI_CallStaticFloatMethod,
4196 _Jv_JNI_CallStaticFloatMethodV,
4197 _Jv_JNI_CallStaticFloatMethodA,
4198 _Jv_JNI_CallStaticDoubleMethod,
4199 _Jv_JNI_CallStaticDoubleMethodV,
4200 _Jv_JNI_CallStaticDoubleMethodA,
4201 _Jv_JNI_CallStaticVoidMethod,
4202 _Jv_JNI_CallStaticVoidMethodV,
4203 _Jv_JNI_CallStaticVoidMethodA,
4205 _Jv_JNI_GetStaticFieldID,
4207 _Jv_JNI_GetStaticObjectField,
4208 _Jv_JNI_GetStaticBooleanField,
4209 _Jv_JNI_GetStaticByteField,
4210 _Jv_JNI_GetStaticCharField,
4211 _Jv_JNI_GetStaticShortField,
4212 _Jv_JNI_GetStaticIntField,
4213 _Jv_JNI_GetStaticLongField,
4214 _Jv_JNI_GetStaticFloatField,
4215 _Jv_JNI_GetStaticDoubleField,
4216 _Jv_JNI_SetStaticObjectField,
4217 _Jv_JNI_SetStaticBooleanField,
4218 _Jv_JNI_SetStaticByteField,
4219 _Jv_JNI_SetStaticCharField,
4220 _Jv_JNI_SetStaticShortField,
4221 _Jv_JNI_SetStaticIntField,
4222 _Jv_JNI_SetStaticLongField,
4223 _Jv_JNI_SetStaticFloatField,
4224 _Jv_JNI_SetStaticDoubleField,
4227 _Jv_JNI_GetStringLength,
4228 _Jv_JNI_GetStringChars,
4229 _Jv_JNI_ReleaseStringChars,
4231 _Jv_JNI_NewStringUTF,
4232 _Jv_JNI_GetStringUTFLength,
4233 _Jv_JNI_GetStringUTFChars,
4234 _Jv_JNI_ReleaseStringUTFChars,
4236 _Jv_JNI_GetArrayLength,
4238 _Jv_JNI_NewObjectArray,
4239 _Jv_JNI_GetObjectArrayElement,
4240 _Jv_JNI_SetObjectArrayElement,
4242 _Jv_JNI_NewBooleanArray,
4243 _Jv_JNI_NewByteArray,
4244 _Jv_JNI_NewCharArray,
4245 _Jv_JNI_NewShortArray,
4246 _Jv_JNI_NewIntArray,
4247 _Jv_JNI_NewLongArray,
4248 _Jv_JNI_NewFloatArray,
4249 _Jv_JNI_NewDoubleArray,
4251 _Jv_JNI_GetBooleanArrayElements,
4252 _Jv_JNI_GetByteArrayElements,
4253 _Jv_JNI_GetCharArrayElements,
4254 _Jv_JNI_GetShortArrayElements,
4255 _Jv_JNI_GetIntArrayElements,
4256 _Jv_JNI_GetLongArrayElements,
4257 _Jv_JNI_GetFloatArrayElements,
4258 _Jv_JNI_GetDoubleArrayElements,
4260 _Jv_JNI_ReleaseBooleanArrayElements,
4261 _Jv_JNI_ReleaseByteArrayElements,
4262 _Jv_JNI_ReleaseCharArrayElements,
4263 _Jv_JNI_ReleaseShortArrayElements,
4264 _Jv_JNI_ReleaseIntArrayElements,
4265 _Jv_JNI_ReleaseLongArrayElements,
4266 _Jv_JNI_ReleaseFloatArrayElements,
4267 _Jv_JNI_ReleaseDoubleArrayElements,
4269 _Jv_JNI_GetBooleanArrayRegion,
4270 _Jv_JNI_GetByteArrayRegion,
4271 _Jv_JNI_GetCharArrayRegion,
4272 _Jv_JNI_GetShortArrayRegion,
4273 _Jv_JNI_GetIntArrayRegion,
4274 _Jv_JNI_GetLongArrayRegion,
4275 _Jv_JNI_GetFloatArrayRegion,
4276 _Jv_JNI_GetDoubleArrayRegion,
4277 _Jv_JNI_SetBooleanArrayRegion,
4278 _Jv_JNI_SetByteArrayRegion,
4279 _Jv_JNI_SetCharArrayRegion,
4280 _Jv_JNI_SetShortArrayRegion,
4281 _Jv_JNI_SetIntArrayRegion,
4282 _Jv_JNI_SetLongArrayRegion,
4283 _Jv_JNI_SetFloatArrayRegion,
4284 _Jv_JNI_SetDoubleArrayRegion,
4286 _Jv_JNI_RegisterNatives,
4287 _Jv_JNI_UnregisterNatives,
4289 _Jv_JNI_MonitorEnter,
4290 _Jv_JNI_MonitorExit,
4294 /* New JNI 1.2 functions. */
4296 _Jv_JNI_GetStringRegion,
4297 _Jv_JNI_GetStringUTFRegion,
4299 _Jv_JNI_GetPrimitiveArrayCritical,
4300 _Jv_JNI_ReleasePrimitiveArrayCritical,
4302 _Jv_JNI_GetStringCritical,
4303 _Jv_JNI_ReleaseStringCritical,
4305 _Jv_JNI_NewWeakGlobalRef,
4306 _Jv_JNI_DeleteWeakGlobalRef,
4308 _Jv_JNI_ExceptionCheck,
4310 /* New JNI 1.4 functions. */
4312 _Jv_JNI_NewDirectByteBuffer,
4313 _Jv_JNI_GetDirectBufferAddress,
4314 _Jv_JNI_GetDirectBufferCapacity,
4316 /* New JNI 1.6 functions. */
4318 jni_GetObjectRefType
4322 /* Invocation API Functions ***************************************************/
4324 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4326 Returns a default configuration for the Java VM.
4328 *******************************************************************************/
4330 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4332 JavaVMInitArgs *_vm_args;
4334 _vm_args = (JavaVMInitArgs *) vm_args;
4336 /* GNU classpath currently supports JNI 1.2 */
4338 switch (_vm_args->version) {
4339 case JNI_VERSION_1_1:
4340 _vm_args->version = JNI_VERSION_1_1;
4343 case JNI_VERSION_1_2:
4344 case JNI_VERSION_1_4:
4345 _vm_args->ignoreUnrecognized = JNI_FALSE;
4346 _vm_args->options = NULL;
4347 _vm_args->nOptions = 0;
4358 /* JNI_GetCreatedJavaVMs *******************************************************
4360 Returns all Java VMs that have been created. Pointers to VMs are written in
4361 the buffer vmBuf in the order they are created. At most bufLen number of
4362 entries will be written. The total number of created VMs is returned in
4365 *******************************************************************************/
4367 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4369 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4374 /* We currently only support 1 VM running. */
4376 vmBuf[0] = (JavaVM *) _Jv_jvm;
4383 /* JNI_CreateJavaVM ************************************************************
4385 Loads and initializes a Java VM. The current thread becomes the main thread.
4386 Sets the env argument to the JNI interface pointer of the main thread.
4388 *******************************************************************************/
4390 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4392 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4394 /* actually create the JVM */
4396 if (!vm_createjvm(p_vm, p_env, vm_args))
4404 * These are local overrides for various environment variables in Emacs.
4405 * Please do not remove this and leave it at the end of the file, where
4406 * Emacs will automagically detect them.
4407 * ---------------------------------------------------------------------
4410 * indent-tabs-mode: t
4414 * vim:noexpandtab:sw=4:ts=4: