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/thread.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 jni_FindClass(JNIEnv *env, const char *name)
947 #if defined(ENABLE_JAVASE)
954 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
956 /* FIXME If name is NULL we have a problem here. */
958 u = utf_new_char_classname((char *) name);
960 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
961 exceptions_throw_noclassdeffounderror(u);
965 /* Check stacktrace for classloader, if one found use it,
966 otherwise use the system classloader. */
968 /* Quote from the JNI documentation:
970 In the Java 2 Platform, FindClass locates the class loader
971 associated with the current native method. If the native code
972 belongs to a system class, no class loader will be
973 involved. Otherwise, the proper class loader will be invoked to
974 load and link the named class. When FindClass is called through
975 the Invocation Interface, there is no current native method or
976 its associated class loader. In that case, the result of
977 ClassLoader.getBaseClassLoader is used." */
979 cc = stacktrace_get_current_class();
982 c = load_class_from_sysloader(u);
984 c = load_class_from_classloader(u, cc->classloader);
987 resolve_handle_pending_exception(true);
994 co = LLNI_classinfo_wrap(c);
996 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
998 #elif defined(ENABLE_JAVAME_CLDC1_1)
1003 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
1005 u = utf_new_char_classname((char *) name);
1006 c = load_class_bootstrap(u);
1009 resolve_handle_pending_exception(true);
1016 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1019 vm_abort("jni_FindClass: not implemented in this configuration");
1021 /* keep compiler happy */
1028 /* GetSuperclass ***************************************************************
1030 If clazz represents any class other than the class Object, then
1031 this function returns the object that represents the superclass of
1032 the class specified by clazz.
1034 *******************************************************************************/
1036 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1040 java_lang_Class *co;
1042 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
1044 c = LLNI_classinfo_unwrap(sub);
1049 super = class_get_superclass(c);
1051 co = LLNI_classinfo_wrap(super);
1053 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1057 /* IsAssignableFrom ************************************************************
1059 Determines whether an object of sub can be safely cast to sup.
1061 *******************************************************************************/
1063 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1065 java_lang_Class *csup;
1066 java_lang_Class *csub;
1068 csup = (java_lang_Class *) sup;
1069 csub = (java_lang_Class *) sub;
1071 STATISTICS(jniinvokation());
1073 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1077 /* Throw ***********************************************************************
1079 Causes a java.lang.Throwable object to be thrown.
1081 *******************************************************************************/
1083 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1087 STATISTICS(jniinvokation());
1089 o = (java_handle_t *) obj;
1091 exceptions_set_exception(o);
1097 /* ThrowNew ********************************************************************
1099 Constructs an exception object from the specified class with the
1100 message specified by message and causes that exception to be
1103 *******************************************************************************/
1105 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1111 STATISTICS(jniinvokation());
1113 c = LLNI_classinfo_unwrap(clazz);
1116 s = javastring_new_from_utf_string(msg);
1118 /* instantiate exception object */
1120 o = native_new_and_init_string(c, s);
1125 exceptions_set_exception(o);
1131 /* ExceptionOccurred ***********************************************************
1133 Determines if an exception is being thrown. The exception stays
1134 being thrown until either the native code calls ExceptionClear(),
1135 or the Java code handles the exception.
1137 *******************************************************************************/
1139 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1143 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1145 o = exceptions_get_exception();
1147 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1151 /* ExceptionDescribe ***********************************************************
1153 Prints an exception and a backtrace of the stack to a system
1154 error-reporting channel, such as stderr. This is a convenience
1155 routine provided for debugging.
1157 *******************************************************************************/
1159 void jni_ExceptionDescribe(JNIEnv *env)
1161 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1163 exceptions_print_stacktrace();
1167 /* ExceptionClear **************************************************************
1169 Clears any exception that is currently being thrown. If no
1170 exception is currently being thrown, this routine has no effect.
1172 *******************************************************************************/
1174 void jni_ExceptionClear(JNIEnv *env)
1176 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1178 exceptions_clear_exception();
1182 /* FatalError ******************************************************************
1184 Raises a fatal error and does not expect the VM to recover. This
1185 function does not return.
1187 *******************************************************************************/
1189 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1191 STATISTICS(jniinvokation());
1193 /* this seems to be the best way */
1195 vm_abort("JNI Fatal error: %s", msg);
1199 /* PushLocalFrame **************************************************************
1201 Creates a new local reference frame, in which at least a given
1202 number of local references can be created.
1204 *******************************************************************************/
1206 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1208 STATISTICS(jniinvokation());
1213 /* add new local reference frame to current table */
1215 if (!localref_frame_push(capacity))
1222 /* PopLocalFrame ***************************************************************
1224 Pops off the current local reference frame, frees all the local
1225 references, and returns a local reference in the previous local
1226 reference frame for the given result object.
1228 *******************************************************************************/
1230 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1232 STATISTICS(jniinvokation());
1234 /* release all current local frames */
1236 localref_frame_pop_all();
1238 /* add local reference and return the value */
1240 return _Jv_JNI_NewLocalRef(env, result);
1244 /* DeleteLocalRef **************************************************************
1246 Deletes the local reference pointed to by localRef.
1248 *******************************************************************************/
1250 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1254 STATISTICS(jniinvokation());
1256 o = (java_handle_t *) localRef;
1261 /* delete the reference */
1267 /* IsSameObject ****************************************************************
1269 Tests whether two references refer to the same Java object.
1271 *******************************************************************************/
1273 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1279 STATISTICS(jniinvokation());
1281 o1 = (java_handle_t *) ref1;
1282 o2 = (java_handle_t *) ref2;
1284 LLNI_CRITICAL_START;
1286 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1297 /* NewLocalRef *****************************************************************
1299 Creates a new local reference that refers to the same object as ref.
1301 *******************************************************************************/
1303 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1306 java_handle_t *localref;
1308 STATISTICS(jniinvokation());
1310 o = (java_handle_t *) ref;
1315 /* insert the reference */
1317 localref = localref_add(LLNI_DIRECT(o));
1319 return (jobject) localref;
1323 /* EnsureLocalCapacity *********************************************************
1325 Ensures that at least a given number of local references can be
1326 created in the current thread
1328 *******************************************************************************/
1330 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1332 localref_table *lrt;
1334 STATISTICS(jniinvokation());
1336 /* get local reference table (thread specific) */
1338 lrt = LOCALREFTABLE;
1340 /* check if capacity elements are available in the local references table */
1342 if ((lrt->used + capacity) > lrt->capacity)
1343 return _Jv_JNI_PushLocalFrame(env, capacity);
1349 /* AllocObject *****************************************************************
1351 Allocates a new Java object without invoking any of the
1352 constructors for the object. Returns a reference to the object.
1354 *******************************************************************************/
1356 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1361 STATISTICS(jniinvokation());
1363 c = LLNI_classinfo_unwrap(clazz);
1365 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1366 exceptions_throw_instantiationexception(c);
1372 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1376 /* NewObject *******************************************************************
1378 Programmers place all arguments that are to be passed to the
1379 constructor immediately following the methodID
1380 argument. NewObject() accepts these arguments and passes them to
1381 the Java method that the programmer wishes to invoke.
1383 *******************************************************************************/
1385 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1392 STATISTICS(jniinvokation());
1394 c = LLNI_classinfo_unwrap(clazz);
1395 m = (methodinfo *) methodID;
1404 /* call constructor */
1406 va_start(ap, methodID);
1407 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1410 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1414 /* NewObjectV ******************************************************************
1416 Programmers place all arguments that are to be passed to the
1417 constructor in an args argument of type va_list that immediately
1418 follows the methodID argument. NewObjectV() accepts these
1419 arguments, and, in turn, passes them to the Java method that the
1420 programmer wishes to invoke.
1422 *******************************************************************************/
1424 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1431 STATISTICS(jniinvokation());
1433 c = LLNI_classinfo_unwrap(clazz);
1434 m = (methodinfo *) methodID;
1443 /* call constructor */
1445 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1447 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1451 /* NewObjectA *****************************************************************
1453 Programmers place all arguments that are to be passed to the
1454 constructor in an args array of jvalues that immediately follows
1455 the methodID argument. NewObjectA() accepts the arguments in this
1456 array, and, in turn, passes them to the Java method that the
1457 programmer wishes to invoke.
1459 *******************************************************************************/
1461 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1468 STATISTICS(jniinvokation());
1470 c = LLNI_classinfo_unwrap(clazz);
1471 m = (methodinfo *) methodID;
1480 /* call constructor */
1482 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1484 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1488 /* GetObjectClass **************************************************************
1490 Returns the class of an object.
1492 *******************************************************************************/
1494 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1498 java_lang_Class *co;
1500 STATISTICS(jniinvokation());
1502 o = (java_handle_t *) obj;
1504 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1507 LLNI_class_get(o, c);
1509 co = LLNI_classinfo_wrap(c);
1511 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1515 /* IsInstanceOf ****************************************************************
1517 Tests whether an object is an instance of a class.
1519 *******************************************************************************/
1521 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1524 java_lang_Object *o;
1526 STATISTICS(jniinvokation());
1528 c = (java_lang_Class *) clazz;
1529 o = (java_lang_Object *) obj;
1531 return _Jv_java_lang_Class_isInstance(c, o);
1535 /* Reflection Support *********************************************************/
1537 /* FromReflectedMethod *********************************************************
1539 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1540 object to a method ID.
1542 *******************************************************************************/
1544 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1546 #if defined(ENABLE_JAVASE)
1552 STATISTICS(jniinvokation());
1554 o = (java_handle_t *) method;
1559 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1560 java_lang_reflect_Method *rm;
1562 rm = (java_lang_reflect_Method *) method;
1563 LLNI_field_get_cls(rm, clazz, c);
1564 LLNI_field_get_val(rm, slot , slot);
1566 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1567 java_lang_reflect_Constructor *rc;
1569 rc = (java_lang_reflect_Constructor *) method;
1570 LLNI_field_get_cls(rc, clazz, c);
1571 LLNI_field_get_val(rc, slot , slot);
1576 m = &(c->methods[slot]);
1578 return (jmethodID) m;
1580 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1582 /* keep compiler happy */
1589 /* FromReflectedField **********************************************************
1591 Converts a java.lang.reflect.Field to a field ID.
1593 *******************************************************************************/
1595 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1597 #if defined(ENABLE_JAVASE)
1598 java_lang_reflect_Field *rf;
1603 STATISTICS(jniinvokation());
1605 rf = (java_lang_reflect_Field *) field;
1610 LLNI_field_get_cls(rf, clazz, c);
1611 LLNI_field_get_val(rf, slot , slot);
1612 f = &(c->fields[slot]);
1614 return (jfieldID) f;
1616 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1618 /* keep compiler happy */
1625 /* ToReflectedMethod ***********************************************************
1627 Converts a method ID derived from cls to an instance of the
1628 java.lang.reflect.Method class or to an instance of the
1629 java.lang.reflect.Constructor class.
1631 *******************************************************************************/
1633 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1636 #if defined(ENABLE_JAVASE)
1638 java_lang_reflect_Constructor *rc;
1639 java_lang_reflect_Method *rm;
1641 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1643 m = (methodinfo *) methodID;
1645 /* HotSpot does the same assert. */
1647 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1649 if (m->name == utf_init) {
1650 rc = reflect_constructor_new(m);
1652 return (jobject) rc;
1655 rm = reflect_method_new(m);
1657 return (jobject) rm;
1660 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1662 /* keep compiler happy */
1669 /* ToReflectedField ************************************************************
1671 Converts a field ID derived from cls to an instance of the
1672 java.lang.reflect.Field class.
1674 *******************************************************************************/
1676 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1679 STATISTICS(jniinvokation());
1681 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1687 /* Calling Instance Methods ***************************************************/
1689 /* GetMethodID *****************************************************************
1691 Returns the method ID for an instance (nonstatic) method of a class
1692 or interface. The method may be defined in one of the clazz's
1693 superclasses and inherited by clazz. The method is determined by
1694 its name and signature.
1696 GetMethodID() causes an uninitialized class to be initialized.
1698 *******************************************************************************/
1700 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1708 STATISTICS(jniinvokation());
1710 c = LLNI_classinfo_unwrap(clazz);
1715 if (!(c->state & CLASS_INITIALIZED))
1716 if (!initialize_class(c))
1719 /* try to get the method of the class or one of it's superclasses */
1721 uname = utf_new_char((char *) name);
1722 udesc = utf_new_char((char *) sig);
1724 m = class_resolvemethod(c, uname, udesc);
1726 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1727 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1732 return (jmethodID) m;
1736 /* JNI-functions for calling instance methods *********************************/
1738 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1739 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1740 jmethodID methodID, ...) \
1747 o = (java_handle_t *) obj; \
1748 m = (methodinfo *) methodID; \
1750 va_start(ap, methodID); \
1751 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1757 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1758 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1759 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1760 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1761 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1762 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1763 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1764 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1767 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1768 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1769 jmethodID methodID, va_list args) \
1775 o = (java_handle_t *) obj; \
1776 m = (methodinfo *) methodID; \
1778 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1783 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1784 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1785 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1786 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1787 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1788 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1789 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1790 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1793 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1794 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1795 jmethodID methodID, \
1796 const jvalue *args) \
1802 o = (java_handle_t *) obj; \
1803 m = (methodinfo *) methodID; \
1805 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1810 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1811 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1812 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1813 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1814 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1815 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1816 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1817 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1820 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1828 o = (java_handle_t *) obj;
1829 m = (methodinfo *) methodID;
1831 va_start(ap, methodID);
1832 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1835 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1839 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1846 o = (java_handle_t *) obj;
1847 m = (methodinfo *) methodID;
1849 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1851 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1855 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1862 o = (java_handle_t *) obj;
1863 m = (methodinfo *) methodID;
1865 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1867 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1872 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1878 o = (java_handle_t *) obj;
1879 m = (methodinfo *) methodID;
1881 va_start(ap, methodID);
1882 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1887 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1893 o = (java_handle_t *) obj;
1894 m = (methodinfo *) methodID;
1896 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1900 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1906 o = (java_handle_t *) obj;
1907 m = (methodinfo *) methodID;
1909 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1914 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1915 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1916 jclass clazz, jmethodID methodID, \
1925 o = (java_handle_t *) obj; \
1926 c = LLNI_classinfo_unwrap(clazz); \
1927 m = (methodinfo *) methodID; \
1929 va_start(ap, methodID); \
1930 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1936 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1937 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1938 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1939 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1940 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1941 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1942 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1943 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1946 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1947 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1948 jclass clazz, jmethodID methodID, \
1956 o = (java_handle_t *) obj; \
1957 c = LLNI_classinfo_unwrap(clazz); \
1958 m = (methodinfo *) methodID; \
1960 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1965 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1966 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1967 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1968 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1969 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1970 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1971 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1972 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1975 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1976 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1977 jclass clazz, jmethodID methodID, \
1978 const jvalue *args) \
1980 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1985 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1986 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1987 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1988 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1989 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1990 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1991 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1992 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1994 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1995 jclass clazz, jmethodID methodID,
2004 o = (java_handle_t *) obj;
2005 c = LLNI_classinfo_unwrap(clazz);
2006 m = (methodinfo *) methodID;
2008 va_start(ap, methodID);
2009 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2012 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2016 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2017 jclass clazz, jmethodID methodID,
2025 o = (java_handle_t *) obj;
2026 c = LLNI_classinfo_unwrap(clazz);
2027 m = (methodinfo *) methodID;
2029 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2031 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2035 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2036 jclass clazz, jmethodID methodID,
2039 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2041 return _Jv_JNI_NewLocalRef(env, NULL);
2045 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2046 jmethodID methodID, ...)
2053 o = (java_handle_t *) obj;
2054 c = LLNI_classinfo_unwrap(clazz);
2055 m = (methodinfo *) methodID;
2057 va_start(ap, methodID);
2058 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2063 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2064 jmethodID methodID, va_list args)
2070 o = (java_handle_t *) obj;
2071 c = LLNI_classinfo_unwrap(clazz);
2072 m = (methodinfo *) methodID;
2074 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2078 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2079 jmethodID methodID, const jvalue * args)
2085 o = (java_handle_t *) obj;
2086 c = LLNI_classinfo_unwrap(clazz);
2087 m = (methodinfo *) methodID;
2089 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2093 /* Accessing Fields of Objects ************************************************/
2095 /* GetFieldID ******************************************************************
2097 Returns the field ID for an instance (nonstatic) field of a
2098 class. The field is specified by its name and signature. The
2099 Get<type>Field and Set<type>Field families of accessor functions
2100 use field IDs to retrieve object fields.
2102 *******************************************************************************/
2104 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2112 STATISTICS(jniinvokation());
2114 c = LLNI_classinfo_unwrap(clazz);
2116 /* XXX NPE check? */
2118 uname = utf_new_char((char *) name);
2119 udesc = utf_new_char((char *) sig);
2121 f = class_findfield(c, uname, udesc);
2124 exceptions_throw_nosuchfielderror(c, uname);
2126 return (jfieldID) f;
2130 /* Get<type>Field Routines *****************************************************
2132 This family of accessor routines returns the value of an instance
2133 (nonstatic) field of an object. The field to access is specified by
2134 a field ID obtained by calling GetFieldID().
2136 *******************************************************************************/
2138 #define GET_FIELD(o,type,f) \
2139 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2141 #define JNI_GET_FIELD(name, type, intern) \
2142 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2146 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2148 LLNI_CRITICAL_START; \
2150 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2152 LLNI_CRITICAL_END; \
2154 return (type) ret; \
2157 JNI_GET_FIELD(Boolean, jboolean, s4)
2158 JNI_GET_FIELD(Byte, jbyte, s4)
2159 JNI_GET_FIELD(Char, jchar, s4)
2160 JNI_GET_FIELD(Short, jshort, s4)
2161 JNI_GET_FIELD(Int, jint, s4)
2162 JNI_GET_FIELD(Long, jlong, s8)
2163 JNI_GET_FIELD(Float, jfloat, float)
2164 JNI_GET_FIELD(Double, jdouble, double)
2167 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2171 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2173 LLNI_CRITICAL_START;
2175 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2179 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2183 /* Set<type>Field Routines *****************************************************
2185 This family of accessor routines sets the value of an instance
2186 (nonstatic) field of an object. The field to access is specified by
2187 a field ID obtained by calling GetFieldID().
2189 *******************************************************************************/
2191 #define SET_FIELD(o,type,f,value) \
2192 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2194 #define JNI_SET_FIELD(name, type, intern) \
2195 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2198 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2200 LLNI_CRITICAL_START; \
2202 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2204 LLNI_CRITICAL_START; \
2207 JNI_SET_FIELD(Boolean, jboolean, s4)
2208 JNI_SET_FIELD(Byte, jbyte, s4)
2209 JNI_SET_FIELD(Char, jchar, s4)
2210 JNI_SET_FIELD(Short, jshort, s4)
2211 JNI_SET_FIELD(Int, jint, s4)
2212 JNI_SET_FIELD(Long, jlong, s8)
2213 JNI_SET_FIELD(Float, jfloat, float)
2214 JNI_SET_FIELD(Double, jdouble, double)
2217 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2220 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2222 LLNI_CRITICAL_START;
2224 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2230 /* Calling Static Methods *****************************************************/
2232 /* GetStaticMethodID ***********************************************************
2234 Returns the method ID for a static method of a class. The method is
2235 specified by its name and signature.
2237 GetStaticMethodID() causes an uninitialized class to be
2240 *******************************************************************************/
2242 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2250 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2252 c = LLNI_classinfo_unwrap(clazz);
2257 if (!(c->state & CLASS_INITIALIZED))
2258 if (!initialize_class(c))
2261 /* try to get the static method of the class */
2263 uname = utf_new_char((char *) name);
2264 udesc = utf_new_char((char *) sig);
2266 m = class_resolvemethod(c, uname, udesc);
2268 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2269 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2274 return (jmethodID) m;
2278 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2279 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2280 jmethodID methodID, ...) \
2286 m = (methodinfo *) methodID; \
2288 va_start(ap, methodID); \
2289 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2295 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2296 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2297 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2298 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2299 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2300 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2301 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2302 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2305 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2306 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2307 jmethodID methodID, va_list args) \
2312 m = (methodinfo *) methodID; \
2314 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2319 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2320 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2321 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2322 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2323 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2324 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2325 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2326 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2329 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2330 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2331 jmethodID methodID, const jvalue *args) \
2336 m = (methodinfo *) methodID; \
2338 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2343 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2344 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2345 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2346 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2347 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2348 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2349 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2350 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2353 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2354 jmethodID methodID, ...)
2360 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2362 m = (methodinfo *) methodID;
2364 va_start(ap, methodID);
2365 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2368 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2372 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2373 jmethodID methodID, va_list args)
2378 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2380 m = (methodinfo *) methodID;
2382 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2384 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2388 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2389 jmethodID methodID, const jvalue *args)
2394 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2396 m = (methodinfo *) methodID;
2398 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2400 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2404 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2405 jmethodID methodID, ...)
2410 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2412 m = (methodinfo *) methodID;
2414 va_start(ap, methodID);
2415 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2420 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2421 jmethodID methodID, va_list args)
2425 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2427 m = (methodinfo *) methodID;
2429 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2433 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2434 jmethodID methodID, const jvalue * args)
2438 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2440 m = (methodinfo *) methodID;
2442 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2446 /* Accessing Static Fields ****************************************************/
2448 /* GetStaticFieldID ************************************************************
2450 Returns the field ID for a static field of a class. The field is
2451 specified by its name and signature. The GetStatic<type>Field and
2452 SetStatic<type>Field families of accessor functions use field IDs
2453 to retrieve static fields.
2455 *******************************************************************************/
2457 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2465 STATISTICS(jniinvokation());
2467 c = LLNI_classinfo_unwrap(clazz);
2469 uname = utf_new_char((char *) name);
2470 usig = utf_new_char((char *) sig);
2472 f = class_findfield(c, uname, usig);
2475 exceptions_throw_nosuchfielderror(c, uname);
2477 return (jfieldID) f;
2481 /* GetStatic<type>Field ********************************************************
2483 This family of accessor routines returns the value of a static
2486 *******************************************************************************/
2488 #define JNI_GET_STATIC_FIELD(name, type, field) \
2489 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2495 STATISTICS(jniinvokation()); \
2497 c = LLNI_classinfo_unwrap(clazz); \
2498 f = (fieldinfo *) fieldID; \
2500 if (!(c->state & CLASS_INITIALIZED)) \
2501 if (!initialize_class(c)) \
2504 return f->value->field; \
2507 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2508 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2509 JNI_GET_STATIC_FIELD(Char, jchar, i)
2510 JNI_GET_STATIC_FIELD(Short, jshort, i)
2511 JNI_GET_STATIC_FIELD(Int, jint, i)
2512 JNI_GET_STATIC_FIELD(Long, jlong, l)
2513 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2514 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2517 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2524 STATISTICS(jniinvokation());
2526 c = LLNI_classinfo_unwrap(clazz);
2527 f = (fieldinfo *) fieldID;
2529 if (!(c->state & CLASS_INITIALIZED))
2530 if (!initialize_class(c))
2533 h = LLNI_WRAP(f->value->a);
2535 return _Jv_JNI_NewLocalRef(env, (jobject) h);
2539 /* SetStatic<type>Field *******************************************************
2541 This family of accessor routines sets the value of a static field
2544 *******************************************************************************/
2546 #define JNI_SET_STATIC_FIELD(name, type, field) \
2547 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2554 STATISTICS(jniinvokation()); \
2556 c = LLNI_classinfo_unwrap(clazz); \
2557 f = (fieldinfo *) fieldID; \
2559 if (!(c->state & CLASS_INITIALIZED)) \
2560 if (!initialize_class(c)) \
2563 f->value->field = value; \
2566 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2567 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2568 JNI_SET_STATIC_FIELD(Char, jchar, i)
2569 JNI_SET_STATIC_FIELD(Short, jshort, i)
2570 JNI_SET_STATIC_FIELD(Int, jint, i)
2571 JNI_SET_STATIC_FIELD(Long, jlong, l)
2572 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2573 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2576 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2582 STATISTICS(jniinvokation());
2584 c = LLNI_classinfo_unwrap(clazz);
2585 f = (fieldinfo *) fieldID;
2587 if (!(c->state & CLASS_INITIALIZED))
2588 if (!initialize_class(c))
2591 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2595 /* String Operations **********************************************************/
2597 /* NewString *******************************************************************
2599 Create new java.lang.String object from an array of Unicode
2602 *******************************************************************************/
2604 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2606 java_lang_String *s;
2607 java_handle_chararray_t *a;
2610 STATISTICS(jniinvokation());
2612 s = (java_lang_String *) builtin_new(class_java_lang_String);
2613 a = builtin_newarray_char(len);
2615 /* javastring or characterarray could not be created */
2616 if ((a == NULL) || (s == NULL))
2620 for (i = 0; i < len; i++)
2621 LLNI_array_direct(a, i) = buf[i];
2623 LLNI_field_set_ref(s, value , a);
2624 LLNI_field_set_val(s, offset, 0);
2625 LLNI_field_set_val(s, count , len);
2627 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2631 static jchar emptyStringJ[]={0,0};
2633 /* GetStringLength *************************************************************
2635 Returns the length (the count of Unicode characters) of a Java
2638 *******************************************************************************/
2640 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2642 java_lang_String *s;
2645 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2647 s = (java_lang_String *) str;
2649 LLNI_field_get_val(s, count, len);
2655 /******************** convertes javastring to u2-array ****************************/
2657 u2 *javastring_tou2(jstring so)
2659 java_lang_String *s;
2660 java_handle_chararray_t *a;
2666 STATISTICS(jniinvokation());
2668 s = (java_lang_String *) so;
2673 LLNI_field_get_ref(s, value, a);
2678 LLNI_field_get_val(s, count, count);
2679 LLNI_field_get_val(s, offset, offset);
2681 /* allocate memory */
2683 stringbuffer = MNEW(u2, count + 1);
2687 for (i = 0; i < count; i++)
2688 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2690 /* terminate string */
2692 stringbuffer[i] = '\0';
2694 return stringbuffer;
2698 /* GetStringChars **************************************************************
2700 Returns a pointer to the array of Unicode characters of the
2701 string. This pointer is valid until ReleaseStringChars() is called.
2703 *******************************************************************************/
2705 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2709 STATISTICS(jniinvokation());
2711 jc = javastring_tou2(str);
2723 return emptyStringJ;
2727 /* ReleaseStringChars **********************************************************
2729 Informs the VM that the native code no longer needs access to
2730 chars. The chars argument is a pointer obtained from string using
2733 *******************************************************************************/
2735 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2737 java_lang_String *s;
2739 STATISTICS(jniinvokation());
2741 if (chars == emptyStringJ)
2744 s = (java_lang_String *) str;
2746 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2750 /* NewStringUTF ****************************************************************
2752 Constructs a new java.lang.String object from an array of UTF-8
2755 *******************************************************************************/
2757 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2759 java_lang_String *s;
2761 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2763 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2765 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2769 /****************** returns the utf8 length in bytes of a string *******************/
2771 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2773 java_lang_String *s;
2776 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2778 s = (java_lang_String *) string;
2780 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2786 /* GetStringUTFChars ***********************************************************
2788 Returns a pointer to an array of UTF-8 characters of the
2789 string. This array is valid until it is released by
2790 ReleaseStringUTFChars().
2792 *******************************************************************************/
2794 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2799 STATISTICS(jniinvokation());
2807 u = javastring_toutf((java_handle_t *) string, false);
2816 /* ReleaseStringUTFChars *******************************************************
2818 Informs the VM that the native code no longer needs access to
2819 utf. The utf argument is a pointer derived from string using
2820 GetStringUTFChars().
2822 *******************************************************************************/
2824 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2826 STATISTICS(jniinvokation());
2828 /* XXX we don't release utf chars right now, perhaps that should be done
2829 later. Since there is always one reference the garbage collector will
2834 /* Array Operations ***********************************************************/
2836 /* GetArrayLength **************************************************************
2838 Returns the number of elements in the array.
2840 *******************************************************************************/
2842 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2847 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2849 a = (java_handle_t *) array;
2851 size = LLNI_array_size(a);
2857 /* NewObjectArray **************************************************************
2859 Constructs a new array holding objects in class elementClass. All
2860 elements are initially set to initialElement.
2862 *******************************************************************************/
2864 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2865 jclass elementClass, jobject initialElement)
2869 java_handle_objectarray_t *oa;
2872 STATISTICS(jniinvokation());
2874 c = LLNI_classinfo_unwrap(elementClass);
2875 o = (java_handle_t *) initialElement;
2878 exceptions_throw_negativearraysizeexception();
2882 oa = builtin_anewarray(length, c);
2887 /* set all elements to initialElement */
2889 for (i = 0; i < length; i++)
2890 array_objectarray_element_set(oa, i, o);
2892 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2896 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2899 java_handle_objectarray_t *oa;
2902 STATISTICS(jniinvokation());
2904 oa = (java_handle_objectarray_t *) array;
2906 if (index >= LLNI_array_size(oa)) {
2907 exceptions_throw_arrayindexoutofboundsexception();
2911 o = array_objectarray_element_get(oa, index);
2913 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2917 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2918 jsize index, jobject val)
2920 java_handle_objectarray_t *oa;
2923 STATISTICS(jniinvokation());
2925 oa = (java_handle_objectarray_t *) array;
2926 o = (java_handle_t *) val;
2928 if (index >= LLNI_array_size(oa)) {
2929 exceptions_throw_arrayindexoutofboundsexception();
2933 /* check if the class of value is a subclass of the element class
2936 if (!builtin_canstore(oa, o))
2939 array_objectarray_element_set(oa, index, o);
2943 #define JNI_NEW_ARRAY(name, type, intern) \
2944 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2946 java_handle_##intern##array_t *a; \
2948 STATISTICS(jniinvokation()); \
2951 exceptions_throw_negativearraysizeexception(); \
2955 a = builtin_newarray_##intern(len); \
2957 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2960 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2961 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2962 JNI_NEW_ARRAY(Char, jcharArray, char)
2963 JNI_NEW_ARRAY(Short, jshortArray, byte)
2964 JNI_NEW_ARRAY(Int, jintArray, int)
2965 JNI_NEW_ARRAY(Long, jlongArray, long)
2966 JNI_NEW_ARRAY(Float, jfloatArray, float)
2967 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2970 /* Get<PrimitiveType>ArrayElements *********************************************
2972 A family of functions that returns the body of the primitive array.
2974 *******************************************************************************/
2976 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2977 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2980 java_handle_##intern##array_t *a; \
2982 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2984 a = (java_handle_##intern##array_t *) array; \
2987 *isCopy = JNI_FALSE; \
2989 return (type *) LLNI_array_data(a); \
2992 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2993 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2994 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2995 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2996 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2997 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2998 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2999 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3002 /* Release<PrimitiveType>ArrayElements *****************************************
3004 A family of functions that informs the VM that the native code no
3005 longer needs access to elems. The elems argument is a pointer
3006 derived from array using the corresponding
3007 Get<PrimitiveType>ArrayElements() function. If necessary, this
3008 function copies back all changes made to elems to the original
3011 *******************************************************************************/
3013 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3014 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3015 type *elems, jint mode) \
3017 java_handle_##intern##array_t *a; \
3019 STATISTICS(jniinvokation()); \
3021 a = (java_handle_##intern##array_t *) array; \
3023 if (elems != (type *) LLNI_array_data(a)) { \
3026 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3029 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3030 /* XXX TWISTI how should it be freed? */ \
3033 /* XXX TWISTI how should it be freed? */ \
3039 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3040 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3041 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3042 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3043 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3044 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3045 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3046 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3049 /* Get<PrimitiveType>ArrayRegion **********************************************
3051 A family of functions that copies a region of a primitive array
3054 *******************************************************************************/
3056 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3057 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3058 jsize start, jsize len, type *buf) \
3060 java_handle_##intern##array_t *a; \
3062 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3064 a = (java_handle_##intern##array_t *) array; \
3066 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3067 exceptions_throw_arrayindexoutofboundsexception(); \
3069 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3072 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3073 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3074 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3075 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3076 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3077 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3078 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3079 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3082 /* Set<PrimitiveType>ArrayRegion **********************************************
3084 A family of functions that copies back a region of a primitive
3085 array from a buffer.
3087 *******************************************************************************/
3089 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3090 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3091 jsize start, jsize len, const type *buf) \
3093 java_handle_##intern##array_t *a; \
3095 STATISTICS(jniinvokation()); \
3097 a = (java_handle_##intern##array_t *) array; \
3099 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3100 exceptions_throw_arrayindexoutofboundsexception(); \
3102 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3105 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3106 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3107 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3108 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3109 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3110 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3111 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3112 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3115 /* Registering Native Methods *************************************************/
3117 /* RegisterNatives *************************************************************
3119 Registers native methods with the class specified by the clazz
3120 argument. The methods parameter specifies an array of
3121 JNINativeMethod structures that contain the names, signatures, and
3122 function pointers of the native methods. The nMethods parameter
3123 specifies the number of native methods in the array.
3125 *******************************************************************************/
3127 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3128 const JNINativeMethod *methods, jint nMethods)
3132 STATISTICS(jniinvokation());
3134 c = LLNI_classinfo_unwrap(clazz);
3136 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3137 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3140 native_method_register(c->name, methods, nMethods);
3146 /* UnregisterNatives ***********************************************************
3148 Unregisters native methods of a class. The class goes back to the
3149 state before it was linked or registered with its native method
3152 This function should not be used in normal native code. Instead, it
3153 provides special programs a way to reload and relink native
3156 *******************************************************************************/
3158 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3160 STATISTICS(jniinvokation());
3162 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3164 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3170 /* Monitor Operations *********************************************************/
3172 /* MonitorEnter ****************************************************************
3174 Enters the monitor associated with the underlying Java object
3177 *******************************************************************************/
3179 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3181 STATISTICS(jniinvokation());
3184 exceptions_throw_nullpointerexception();
3188 LOCK_MONITOR_ENTER(obj);
3194 /* MonitorExit *****************************************************************
3196 The current thread must be the owner of the monitor associated with
3197 the underlying Java object referred to by obj. The thread
3198 decrements the counter indicating the number of times it has
3199 entered this monitor. If the value of the counter becomes zero, the
3200 current thread releases the monitor.
3202 *******************************************************************************/
3204 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3206 STATISTICS(jniinvokation());
3209 exceptions_throw_nullpointerexception();
3213 LOCK_MONITOR_EXIT(obj);
3219 /* JavaVM Interface ***********************************************************/
3221 /* GetJavaVM *******************************************************************
3223 Returns the Java VM interface (used in the Invocation API)
3224 associated with the current thread. The result is placed at the
3225 location pointed to by the second argument, vm.
3227 *******************************************************************************/
3229 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3231 STATISTICS(jniinvokation());
3233 *vm = (JavaVM *) _Jv_jvm;
3239 /* GetStringRegion *************************************************************
3241 Copies len number of Unicode characters beginning at offset start
3242 to the given buffer buf.
3244 Throws StringIndexOutOfBoundsException on index overflow.
3246 *******************************************************************************/
3248 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3251 java_lang_String *s;
3252 java_handle_chararray_t *ca;
3254 STATISTICS(jniinvokation());
3256 s = (java_lang_String *) str;
3257 LLNI_field_get_ref(s, value, ca);
3259 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3260 (start + len > LLNI_field_direct(s, count))) {
3261 exceptions_throw_stringindexoutofboundsexception();
3265 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3269 /* GetStringUTFRegion **********************************************************
3271 Translates len number of Unicode characters beginning at offset
3272 start into UTF-8 format and place the result in the given buffer
3275 Throws StringIndexOutOfBoundsException on index overflow.
3277 *******************************************************************************/
3279 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3280 jsize len, char *buf)
3282 java_lang_String *s;
3283 java_handle_chararray_t *ca;
3288 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3290 s = (java_lang_String *) str;
3291 LLNI_field_get_ref(s, value, ca);
3292 LLNI_field_get_val(s, count, count);
3293 LLNI_field_get_val(s, offset, offset);
3295 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3296 exceptions_throw_stringindexoutofboundsexception();
3300 for (i = 0; i < len; i++)
3301 buf[i] = LLNI_array_direct(ca, offset + start + i);
3307 /* GetPrimitiveArrayCritical ***************************************************
3309 Obtain a direct pointer to array elements.
3311 *******************************************************************************/
3313 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3316 java_handle_bytearray_t *ba;
3319 ba = (java_handle_bytearray_t *) array;
3321 /* do the same as Kaffe does */
3323 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3329 /* ReleasePrimitiveArrayCritical ***********************************************
3331 No specific documentation.
3333 *******************************************************************************/
3335 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3336 void *carray, jint mode)
3338 STATISTICS(jniinvokation());
3340 /* do the same as Kaffe does */
3342 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3347 /* GetStringCritical ***********************************************************
3349 The semantics of these two functions are similar to the existing
3350 Get/ReleaseStringChars functions.
3352 *******************************************************************************/
3354 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3357 STATISTICS(jniinvokation());
3359 return _Jv_JNI_GetStringChars(env, string, isCopy);
3363 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3364 const jchar *cstring)
3366 STATISTICS(jniinvokation());
3368 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3372 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3374 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3380 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3382 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3386 /* NewGlobalRef ****************************************************************
3388 Creates a new global reference to the object referred to by the obj
3391 *******************************************************************************/
3393 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3395 hashtable_global_ref_entry *gre;
3396 u4 key; /* hashkey */
3397 u4 slot; /* slot in hashtable */
3400 STATISTICS(jniinvokation());
3402 o = (java_handle_t *) obj;
3404 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3406 LLNI_CRITICAL_START;
3408 /* normally addresses are aligned to 4, 8 or 16 bytes */
3410 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3411 slot = key & (hashtable_global_ref->size - 1);
3412 gre = hashtable_global_ref->ptr[slot];
3414 /* search external hash chain for the entry */
3417 if (gre->o == LLNI_DIRECT(o)) {
3418 /* global object found, increment the reference */
3425 gre = gre->hashlink; /* next element in external chain */
3430 /* global ref not found, create a new one */
3433 gre = NEW(hashtable_global_ref_entry);
3435 #if defined(ENABLE_GC_CACAO)
3436 /* register global ref with the GC */
3438 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3441 LLNI_CRITICAL_START;
3443 gre->o = LLNI_DIRECT(o);
3448 /* insert entry into hashtable */
3450 gre->hashlink = hashtable_global_ref->ptr[slot];
3452 hashtable_global_ref->ptr[slot] = gre;
3454 /* update number of hashtable-entries */
3456 hashtable_global_ref->entries++;
3459 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3461 #if defined(ENABLE_HANDLES)
3469 /* DeleteGlobalRef *************************************************************
3471 Deletes the global reference pointed to by globalRef.
3473 *******************************************************************************/
3475 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3477 hashtable_global_ref_entry *gre;
3478 hashtable_global_ref_entry *prevgre;
3479 u4 key; /* hashkey */
3480 u4 slot; /* slot in hashtable */
3483 STATISTICS(jniinvokation());
3485 o = (java_handle_t *) globalRef;
3487 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3489 LLNI_CRITICAL_START;
3491 /* normally addresses are aligned to 4, 8 or 16 bytes */
3493 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3494 slot = key & (hashtable_global_ref->size - 1);
3495 gre = hashtable_global_ref->ptr[slot];
3497 /* initialize prevgre */
3501 /* search external hash chain for the entry */
3504 if (gre->o == LLNI_DIRECT(o)) {
3505 /* global object found, decrement the reference count */
3509 /* if reference count is 0, remove the entry */
3511 if (gre->refs == 0) {
3512 /* special handling if it's the first in the chain */
3514 if (prevgre == NULL)
3515 hashtable_global_ref->ptr[slot] = gre->hashlink;
3517 prevgre->hashlink = gre->hashlink;
3519 #if defined(ENABLE_GC_CACAO)
3520 /* unregister global ref with the GC */
3522 gc_reference_unregister(&(gre->o));
3525 FREE(gre, hashtable_global_ref_entry);
3530 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3535 prevgre = gre; /* save current pointer for removal */
3536 gre = gre->hashlink; /* next element in external chain */
3539 log_println("JNI-DeleteGlobalRef: global reference not found");
3543 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3547 /* ExceptionCheck **************************************************************
3549 Returns JNI_TRUE when there is a pending exception; otherwise,
3552 *******************************************************************************/
3554 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3558 STATISTICS(jniinvokation());
3560 o = exceptions_get_exception();
3562 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3566 /* New JNI 1.4 functions ******************************************************/
3568 /* NewDirectByteBuffer *********************************************************
3570 Allocates and returns a direct java.nio.ByteBuffer referring to the
3571 block of memory starting at the memory address address and
3572 extending capacity bytes.
3574 *******************************************************************************/
3576 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3578 #if defined(ENABLE_JAVASE)
3579 # if defined(WITH_CLASSPATH_GNU)
3580 java_handle_t *nbuf;
3582 # if SIZEOF_VOID_P == 8
3583 gnu_classpath_Pointer64 *paddress;
3585 gnu_classpath_Pointer32 *paddress;
3588 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3590 /* alocate a gnu.classpath.Pointer{32,64} object */
3592 # if SIZEOF_VOID_P == 8
3593 if (!(paddress = (gnu_classpath_Pointer64 *)
3594 builtin_new(class_gnu_classpath_Pointer64)))
3596 if (!(paddress = (gnu_classpath_Pointer32 *)
3597 builtin_new(class_gnu_classpath_Pointer32)))
3601 /* fill gnu.classpath.Pointer{32,64} with address */
3603 LLNI_field_set_val(paddress, data, (ptrint) address);
3605 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3607 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3608 (jmethodID) dbbirw_init, NULL, paddress,
3609 (jint) capacity, (jint) capacity, (jint) 0);
3611 /* add local reference and return the value */
3613 return _Jv_JNI_NewLocalRef(env, nbuf);
3615 # elif defined(WITH_CLASSPATH_SUN)
3621 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3623 /* Be paranoid about address sign-extension. */
3625 addr = (int64_t) ((uintptr_t) address);
3626 cap = (int32_t) capacity;
3628 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3629 (jmethodID) dbb_init, addr, cap);
3631 /* Add local reference and return the value. */
3633 return _Jv_JNI_NewLocalRef(env, o);
3636 # error unknown classpath configuration
3640 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3642 /* keep compiler happy */
3649 /* GetDirectBufferAddress ******************************************************
3651 Fetches and returns the starting address of the memory region
3652 referenced by the given direct java.nio.Buffer.
3654 *******************************************************************************/
3656 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3658 #if defined(ENABLE_JAVASE)
3661 # if defined(WITH_CLASSPATH_GNU)
3663 java_nio_DirectByteBufferImpl *nbuf;
3664 gnu_classpath_Pointer *po;
3665 # if SIZEOF_VOID_P == 8
3666 gnu_classpath_Pointer64 *paddress;
3669 gnu_classpath_Pointer32 *paddress;
3674 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3676 /* Prevent compiler warning. */
3678 h = (java_handle_t *) buf;
3680 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3683 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3685 LLNI_field_get_ref(nbuf, address, po);
3687 # if SIZEOF_VOID_P == 8
3688 paddress = (gnu_classpath_Pointer64 *) po;
3690 paddress = (gnu_classpath_Pointer32 *) po;
3693 if (paddress == NULL)
3696 LLNI_field_get_val(paddress, data, address);
3698 p = (void *) (intptr_t) address;
3702 # elif defined(WITH_CLASSPATH_SUN)
3708 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3710 /* Prevent compiler warning. */
3712 h = (java_handle_t *) buf;
3714 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3717 o = (java_nio_Buffer *) buf;
3719 LLNI_field_get_val(o, address, address);
3721 p = (void *) (intptr_t) address;
3726 # error unknown classpath configuration
3731 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3733 /* keep compiler happy */
3741 /* GetDirectBufferCapacity *****************************************************
3743 Fetches and returns the capacity in bytes of the memory region
3744 referenced by the given direct java.nio.Buffer.
3746 *******************************************************************************/
3748 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3750 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3752 java_nio_Buffer *nbuf;
3755 STATISTICS(jniinvokation());
3757 o = (java_handle_t *) buf;
3759 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3762 nbuf = (java_nio_Buffer *) o;
3764 LLNI_field_get_val(nbuf, cap, capacity);
3768 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3770 /* keep compiler happy */
3777 /* GetObjectRefType ************************************************************
3779 Returns the type of the object referred to by the obj argument. The
3780 argument obj can either be a local, global or weak global
3783 *******************************************************************************/
3785 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3787 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3793 /* DestroyJavaVM ***************************************************************
3795 Unloads a Java VM and reclaims its resources. Only the main thread
3796 can unload the VM. The system waits until the main thread is only
3797 remaining user thread before it destroys the VM.
3799 *******************************************************************************/
3801 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3805 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3807 if (vm_created == false)
3810 status = vm_destroy(vm);
3816 /* AttachCurrentThread *********************************************************
3818 Attaches the current thread to a Java VM. Returns a JNI interface
3819 pointer in the JNIEnv argument.
3821 Trying to attach a thread that is already attached is a no-op.
3823 A native thread cannot be attached simultaneously to two Java VMs.
3825 When a thread is attached to the VM, the context class loader is
3826 the bootstrap loader.
3828 *******************************************************************************/
3830 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3832 #if defined(ENABLE_THREADS)
3833 JavaVMAttachArgs *vm_aargs;
3836 /* If the current thread has already been attached, this operation
3839 result = thread_current_is_attached();
3841 if (result == true) {
3847 vm_aargs = (JavaVMAttachArgs *) thr_args;
3849 if (vm_aargs != NULL) {
3850 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3851 (vm_aargs->version != JNI_VERSION_1_4))
3852 return JNI_EVERSION;
3855 if (!threads_attach_current_thread(vm_aargs, false))
3858 if (!localref_table_init())
3868 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3872 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3874 if (vm_created == false)
3877 result = jni_attach_current_thread(p_env, thr_args, false);
3883 /* DetachCurrentThread *********************************************************
3885 Detaches the current thread from a Java VM. All Java monitors held
3886 by this thread are released. All Java threads waiting for this
3887 thread to die are notified.
3889 In JDK 1.1, the main thread cannot be detached from the VM. It must
3890 call DestroyJavaVM to unload the entire VM.
3892 In the JDK, the main thread can be detached from the VM.
3894 The main thread, which is the thread that created the Java VM,
3895 cannot be detached from the VM. Instead, the main thread must call
3896 JNI_DestroyJavaVM() to unload the entire VM.
3898 *******************************************************************************/
3900 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3902 #if defined(ENABLE_THREADS)
3906 TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
3908 t = thread_get_current();
3914 /* If the given thread has already been detached, this operation
3917 result = thread_is_attached(t);
3919 if (result == false)
3922 /* We need to pop all frames before we can destroy the table. */
3924 localref_frame_pop_all();
3926 if (!localref_table_destroy())
3929 if (!threads_detach_thread(t))
3937 /* GetEnv **********************************************************************
3939 If the current thread is not attached to the VM, sets *env to NULL,
3940 and returns JNI_EDETACHED. If the specified version is not
3941 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3942 sets *env to the appropriate interface, and returns JNI_OK.
3944 *******************************************************************************/
3946 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3948 TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
3950 if (vm_created == false) {
3952 return JNI_EDETACHED;
3955 #if defined(ENABLE_THREADS)
3956 if (thread_get_current() == NULL) {
3959 return JNI_EDETACHED;
3963 /* Check the JNI version. */
3965 if (jni_version_check(version) == true) {
3970 #if defined(ENABLE_JVMTI)
3971 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3972 == JVMTI_VERSION_INTERFACE_JVMTI) {
3974 *env = (void *) jvmti_new_environment();
3983 return JNI_EVERSION;
3987 /* AttachCurrentThreadAsDaemon *************************************************
3989 Same semantics as AttachCurrentThread, but the newly-created
3990 java.lang.Thread instance is a daemon.
3992 If the thread has already been attached via either
3993 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3994 simply sets the value pointed to by penv to the JNIEnv of the
3995 current thread. In this case neither AttachCurrentThread nor this
3996 routine have any effect on the daemon status of the thread.
3998 *******************************************************************************/
4000 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
4004 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
4006 if (vm_created == false)
4009 result = jni_attach_current_thread(penv, args, true);
4015 /* JNI invocation table *******************************************************/
4017 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4022 _Jv_JNI_DestroyJavaVM,
4023 _Jv_JNI_AttachCurrentThread,
4024 _Jv_JNI_DetachCurrentThread,
4026 _Jv_JNI_AttachCurrentThreadAsDaemon
4030 /* JNI function table *********************************************************/
4032 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4039 _Jv_JNI_DefineClass,
4041 _Jv_JNI_FromReflectedMethod,
4042 _Jv_JNI_FromReflectedField,
4043 _Jv_JNI_ToReflectedMethod,
4044 _Jv_JNI_GetSuperclass,
4045 _Jv_JNI_IsAssignableFrom,
4046 _Jv_JNI_ToReflectedField,
4050 _Jv_JNI_ExceptionOccurred,
4051 jni_ExceptionDescribe,
4054 _Jv_JNI_PushLocalFrame,
4055 _Jv_JNI_PopLocalFrame,
4057 _Jv_JNI_NewGlobalRef,
4058 _Jv_JNI_DeleteGlobalRef,
4059 _Jv_JNI_DeleteLocalRef,
4060 _Jv_JNI_IsSameObject,
4061 _Jv_JNI_NewLocalRef,
4062 _Jv_JNI_EnsureLocalCapacity,
4064 _Jv_JNI_AllocObject,
4069 _Jv_JNI_GetObjectClass,
4070 _Jv_JNI_IsInstanceOf,
4072 _Jv_JNI_GetMethodID,
4074 _Jv_JNI_CallObjectMethod,
4075 _Jv_JNI_CallObjectMethodV,
4076 _Jv_JNI_CallObjectMethodA,
4077 _Jv_JNI_CallBooleanMethod,
4078 _Jv_JNI_CallBooleanMethodV,
4079 _Jv_JNI_CallBooleanMethodA,
4080 _Jv_JNI_CallByteMethod,
4081 _Jv_JNI_CallByteMethodV,
4082 _Jv_JNI_CallByteMethodA,
4083 _Jv_JNI_CallCharMethod,
4084 _Jv_JNI_CallCharMethodV,
4085 _Jv_JNI_CallCharMethodA,
4086 _Jv_JNI_CallShortMethod,
4087 _Jv_JNI_CallShortMethodV,
4088 _Jv_JNI_CallShortMethodA,
4089 _Jv_JNI_CallIntMethod,
4090 _Jv_JNI_CallIntMethodV,
4091 _Jv_JNI_CallIntMethodA,
4092 _Jv_JNI_CallLongMethod,
4093 _Jv_JNI_CallLongMethodV,
4094 _Jv_JNI_CallLongMethodA,
4095 _Jv_JNI_CallFloatMethod,
4096 _Jv_JNI_CallFloatMethodV,
4097 _Jv_JNI_CallFloatMethodA,
4098 _Jv_JNI_CallDoubleMethod,
4099 _Jv_JNI_CallDoubleMethodV,
4100 _Jv_JNI_CallDoubleMethodA,
4101 _Jv_JNI_CallVoidMethod,
4102 _Jv_JNI_CallVoidMethodV,
4103 _Jv_JNI_CallVoidMethodA,
4105 _Jv_JNI_CallNonvirtualObjectMethod,
4106 _Jv_JNI_CallNonvirtualObjectMethodV,
4107 _Jv_JNI_CallNonvirtualObjectMethodA,
4108 _Jv_JNI_CallNonvirtualBooleanMethod,
4109 _Jv_JNI_CallNonvirtualBooleanMethodV,
4110 _Jv_JNI_CallNonvirtualBooleanMethodA,
4111 _Jv_JNI_CallNonvirtualByteMethod,
4112 _Jv_JNI_CallNonvirtualByteMethodV,
4113 _Jv_JNI_CallNonvirtualByteMethodA,
4114 _Jv_JNI_CallNonvirtualCharMethod,
4115 _Jv_JNI_CallNonvirtualCharMethodV,
4116 _Jv_JNI_CallNonvirtualCharMethodA,
4117 _Jv_JNI_CallNonvirtualShortMethod,
4118 _Jv_JNI_CallNonvirtualShortMethodV,
4119 _Jv_JNI_CallNonvirtualShortMethodA,
4120 _Jv_JNI_CallNonvirtualIntMethod,
4121 _Jv_JNI_CallNonvirtualIntMethodV,
4122 _Jv_JNI_CallNonvirtualIntMethodA,
4123 _Jv_JNI_CallNonvirtualLongMethod,
4124 _Jv_JNI_CallNonvirtualLongMethodV,
4125 _Jv_JNI_CallNonvirtualLongMethodA,
4126 _Jv_JNI_CallNonvirtualFloatMethod,
4127 _Jv_JNI_CallNonvirtualFloatMethodV,
4128 _Jv_JNI_CallNonvirtualFloatMethodA,
4129 _Jv_JNI_CallNonvirtualDoubleMethod,
4130 _Jv_JNI_CallNonvirtualDoubleMethodV,
4131 _Jv_JNI_CallNonvirtualDoubleMethodA,
4132 _Jv_JNI_CallNonvirtualVoidMethod,
4133 _Jv_JNI_CallNonvirtualVoidMethodV,
4134 _Jv_JNI_CallNonvirtualVoidMethodA,
4138 _Jv_JNI_GetObjectField,
4139 _Jv_JNI_GetBooleanField,
4140 _Jv_JNI_GetByteField,
4141 _Jv_JNI_GetCharField,
4142 _Jv_JNI_GetShortField,
4143 _Jv_JNI_GetIntField,
4144 _Jv_JNI_GetLongField,
4145 _Jv_JNI_GetFloatField,
4146 _Jv_JNI_GetDoubleField,
4147 _Jv_JNI_SetObjectField,
4148 _Jv_JNI_SetBooleanField,
4149 _Jv_JNI_SetByteField,
4150 _Jv_JNI_SetCharField,
4151 _Jv_JNI_SetShortField,
4152 _Jv_JNI_SetIntField,
4153 _Jv_JNI_SetLongField,
4154 _Jv_JNI_SetFloatField,
4155 _Jv_JNI_SetDoubleField,
4157 _Jv_JNI_GetStaticMethodID,
4159 _Jv_JNI_CallStaticObjectMethod,
4160 _Jv_JNI_CallStaticObjectMethodV,
4161 _Jv_JNI_CallStaticObjectMethodA,
4162 _Jv_JNI_CallStaticBooleanMethod,
4163 _Jv_JNI_CallStaticBooleanMethodV,
4164 _Jv_JNI_CallStaticBooleanMethodA,
4165 _Jv_JNI_CallStaticByteMethod,
4166 _Jv_JNI_CallStaticByteMethodV,
4167 _Jv_JNI_CallStaticByteMethodA,
4168 _Jv_JNI_CallStaticCharMethod,
4169 _Jv_JNI_CallStaticCharMethodV,
4170 _Jv_JNI_CallStaticCharMethodA,
4171 _Jv_JNI_CallStaticShortMethod,
4172 _Jv_JNI_CallStaticShortMethodV,
4173 _Jv_JNI_CallStaticShortMethodA,
4174 _Jv_JNI_CallStaticIntMethod,
4175 _Jv_JNI_CallStaticIntMethodV,
4176 _Jv_JNI_CallStaticIntMethodA,
4177 _Jv_JNI_CallStaticLongMethod,
4178 _Jv_JNI_CallStaticLongMethodV,
4179 _Jv_JNI_CallStaticLongMethodA,
4180 _Jv_JNI_CallStaticFloatMethod,
4181 _Jv_JNI_CallStaticFloatMethodV,
4182 _Jv_JNI_CallStaticFloatMethodA,
4183 _Jv_JNI_CallStaticDoubleMethod,
4184 _Jv_JNI_CallStaticDoubleMethodV,
4185 _Jv_JNI_CallStaticDoubleMethodA,
4186 _Jv_JNI_CallStaticVoidMethod,
4187 _Jv_JNI_CallStaticVoidMethodV,
4188 _Jv_JNI_CallStaticVoidMethodA,
4190 _Jv_JNI_GetStaticFieldID,
4192 _Jv_JNI_GetStaticObjectField,
4193 _Jv_JNI_GetStaticBooleanField,
4194 _Jv_JNI_GetStaticByteField,
4195 _Jv_JNI_GetStaticCharField,
4196 _Jv_JNI_GetStaticShortField,
4197 _Jv_JNI_GetStaticIntField,
4198 _Jv_JNI_GetStaticLongField,
4199 _Jv_JNI_GetStaticFloatField,
4200 _Jv_JNI_GetStaticDoubleField,
4201 _Jv_JNI_SetStaticObjectField,
4202 _Jv_JNI_SetStaticBooleanField,
4203 _Jv_JNI_SetStaticByteField,
4204 _Jv_JNI_SetStaticCharField,
4205 _Jv_JNI_SetStaticShortField,
4206 _Jv_JNI_SetStaticIntField,
4207 _Jv_JNI_SetStaticLongField,
4208 _Jv_JNI_SetStaticFloatField,
4209 _Jv_JNI_SetStaticDoubleField,
4212 _Jv_JNI_GetStringLength,
4213 _Jv_JNI_GetStringChars,
4214 _Jv_JNI_ReleaseStringChars,
4216 _Jv_JNI_NewStringUTF,
4217 _Jv_JNI_GetStringUTFLength,
4218 _Jv_JNI_GetStringUTFChars,
4219 _Jv_JNI_ReleaseStringUTFChars,
4221 _Jv_JNI_GetArrayLength,
4223 _Jv_JNI_NewObjectArray,
4224 _Jv_JNI_GetObjectArrayElement,
4225 _Jv_JNI_SetObjectArrayElement,
4227 _Jv_JNI_NewBooleanArray,
4228 _Jv_JNI_NewByteArray,
4229 _Jv_JNI_NewCharArray,
4230 _Jv_JNI_NewShortArray,
4231 _Jv_JNI_NewIntArray,
4232 _Jv_JNI_NewLongArray,
4233 _Jv_JNI_NewFloatArray,
4234 _Jv_JNI_NewDoubleArray,
4236 _Jv_JNI_GetBooleanArrayElements,
4237 _Jv_JNI_GetByteArrayElements,
4238 _Jv_JNI_GetCharArrayElements,
4239 _Jv_JNI_GetShortArrayElements,
4240 _Jv_JNI_GetIntArrayElements,
4241 _Jv_JNI_GetLongArrayElements,
4242 _Jv_JNI_GetFloatArrayElements,
4243 _Jv_JNI_GetDoubleArrayElements,
4245 _Jv_JNI_ReleaseBooleanArrayElements,
4246 _Jv_JNI_ReleaseByteArrayElements,
4247 _Jv_JNI_ReleaseCharArrayElements,
4248 _Jv_JNI_ReleaseShortArrayElements,
4249 _Jv_JNI_ReleaseIntArrayElements,
4250 _Jv_JNI_ReleaseLongArrayElements,
4251 _Jv_JNI_ReleaseFloatArrayElements,
4252 _Jv_JNI_ReleaseDoubleArrayElements,
4254 _Jv_JNI_GetBooleanArrayRegion,
4255 _Jv_JNI_GetByteArrayRegion,
4256 _Jv_JNI_GetCharArrayRegion,
4257 _Jv_JNI_GetShortArrayRegion,
4258 _Jv_JNI_GetIntArrayRegion,
4259 _Jv_JNI_GetLongArrayRegion,
4260 _Jv_JNI_GetFloatArrayRegion,
4261 _Jv_JNI_GetDoubleArrayRegion,
4262 _Jv_JNI_SetBooleanArrayRegion,
4263 _Jv_JNI_SetByteArrayRegion,
4264 _Jv_JNI_SetCharArrayRegion,
4265 _Jv_JNI_SetShortArrayRegion,
4266 _Jv_JNI_SetIntArrayRegion,
4267 _Jv_JNI_SetLongArrayRegion,
4268 _Jv_JNI_SetFloatArrayRegion,
4269 _Jv_JNI_SetDoubleArrayRegion,
4271 _Jv_JNI_RegisterNatives,
4272 _Jv_JNI_UnregisterNatives,
4274 _Jv_JNI_MonitorEnter,
4275 _Jv_JNI_MonitorExit,
4279 /* New JNI 1.2 functions. */
4281 _Jv_JNI_GetStringRegion,
4282 _Jv_JNI_GetStringUTFRegion,
4284 _Jv_JNI_GetPrimitiveArrayCritical,
4285 _Jv_JNI_ReleasePrimitiveArrayCritical,
4287 _Jv_JNI_GetStringCritical,
4288 _Jv_JNI_ReleaseStringCritical,
4290 _Jv_JNI_NewWeakGlobalRef,
4291 _Jv_JNI_DeleteWeakGlobalRef,
4293 _Jv_JNI_ExceptionCheck,
4295 /* New JNI 1.4 functions. */
4297 _Jv_JNI_NewDirectByteBuffer,
4298 _Jv_JNI_GetDirectBufferAddress,
4299 _Jv_JNI_GetDirectBufferCapacity,
4301 /* New JNI 1.6 functions. */
4303 jni_GetObjectRefType
4307 /* Invocation API Functions ***************************************************/
4309 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4311 Returns a default configuration for the Java VM.
4313 *******************************************************************************/
4315 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4317 JavaVMInitArgs *_vm_args;
4319 _vm_args = (JavaVMInitArgs *) vm_args;
4321 /* GNU classpath currently supports JNI 1.2 */
4323 switch (_vm_args->version) {
4324 case JNI_VERSION_1_1:
4325 _vm_args->version = JNI_VERSION_1_1;
4328 case JNI_VERSION_1_2:
4329 case JNI_VERSION_1_4:
4330 _vm_args->ignoreUnrecognized = JNI_FALSE;
4331 _vm_args->options = NULL;
4332 _vm_args->nOptions = 0;
4343 /* JNI_GetCreatedJavaVMs *******************************************************
4345 Returns all Java VMs that have been created. Pointers to VMs are written in
4346 the buffer vmBuf in the order they are created. At most bufLen number of
4347 entries will be written. The total number of created VMs is returned in
4350 *******************************************************************************/
4352 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4354 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4359 /* We currently only support 1 VM running. */
4361 vmBuf[0] = (JavaVM *) _Jv_jvm;
4368 /* JNI_CreateJavaVM ************************************************************
4370 Loads and initializes a Java VM. The current thread becomes the main thread.
4371 Sets the env argument to the JNI interface pointer of the main thread.
4373 *******************************************************************************/
4375 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4377 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4379 /* actually create the JVM */
4381 if (!vm_createjvm(p_vm, p_env, vm_args))
4389 * These are local overrides for various environment variables in Emacs.
4390 * Please do not remove this and leave it at the end of the file, where
4391 * Emacs will automagically detect them.
4392 * ---------------------------------------------------------------------
4395 * indent-tabs-mode: t
4399 * vim:noexpandtab:sw=4:ts=4: