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 /* GetVersion ******************************************************************
806 Returns the major version number in the higher 16 bits and the
807 minor version number in the lower 16 bits.
809 *******************************************************************************/
811 jint _Jv_JNI_GetVersion(JNIEnv *env)
813 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
815 /* We support JNI 1.6. */
817 return JNI_VERSION_1_6;
821 /* Class Operations ***********************************************************/
823 /* DefineClass *****************************************************************
825 Loads a class from a buffer of raw class data. The buffer
826 containing the raw class data is not referenced by the VM after the
827 DefineClass call returns, and it may be discarded if desired.
829 *******************************************************************************/
831 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
832 const jbyte *buf, jsize bufLen)
834 #if defined(ENABLE_JAVASE)
840 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
842 u = utf_new_char(name);
843 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
845 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
847 co = LLNI_classinfo_wrap(c);
849 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
851 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
853 /* keep compiler happy */
860 /* FindClass *******************************************************************
862 This function loads a locally-defined class. It searches the
863 directories and zip files specified by the CLASSPATH environment
864 variable for the class with the specified name.
866 *******************************************************************************/
868 jclass jni_FindClass(JNIEnv *env, const char *name)
870 #if defined(ENABLE_JAVASE)
877 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
879 /* FIXME If name is NULL we have a problem here. */
881 u = utf_new_char_classname((char *) name);
883 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
884 exceptions_throw_noclassdeffounderror(u);
888 /* Check stacktrace for classloader, if one found use it,
889 otherwise use the system classloader. */
891 /* Quote from the JNI documentation:
893 In the Java 2 Platform, FindClass locates the class loader
894 associated with the current native method. If the native code
895 belongs to a system class, no class loader will be
896 involved. Otherwise, the proper class loader will be invoked to
897 load and link the named class. When FindClass is called through
898 the Invocation Interface, there is no current native method or
899 its associated class loader. In that case, the result of
900 ClassLoader.getBaseClassLoader is used." */
902 cc = stacktrace_get_current_class();
905 c = load_class_from_sysloader(u);
907 c = load_class_from_classloader(u, cc->classloader);
910 resolve_handle_pending_exception(true);
917 co = LLNI_classinfo_wrap(c);
919 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
921 #elif defined(ENABLE_JAVAME_CLDC1_1)
926 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
928 u = utf_new_char_classname((char *) name);
929 c = load_class_bootstrap(u);
932 resolve_handle_pending_exception(true);
939 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
942 vm_abort("jni_FindClass: not implemented in this configuration");
944 /* keep compiler happy */
951 /* GetSuperclass ***************************************************************
953 If clazz represents any class other than the class Object, then
954 this function returns the object that represents the superclass of
955 the class specified by clazz.
957 *******************************************************************************/
959 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
965 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
967 c = LLNI_classinfo_unwrap(sub);
972 super = class_get_superclass(c);
974 co = LLNI_classinfo_wrap(super);
976 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
980 /* IsAssignableFrom ************************************************************
982 Determines whether an object of sub can be safely cast to sup.
984 *******************************************************************************/
986 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
988 java_lang_Class *csup;
989 java_lang_Class *csub;
991 csup = (java_lang_Class *) sup;
992 csub = (java_lang_Class *) sub;
994 STATISTICS(jniinvokation());
996 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1000 /* Throw ***********************************************************************
1002 Causes a java.lang.Throwable object to be thrown.
1004 *******************************************************************************/
1006 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1010 STATISTICS(jniinvokation());
1012 o = (java_handle_t *) obj;
1014 exceptions_set_exception(o);
1020 /* ThrowNew ********************************************************************
1022 Constructs an exception object from the specified class with the
1023 message specified by message and causes that exception to be
1026 *******************************************************************************/
1028 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1034 STATISTICS(jniinvokation());
1036 c = LLNI_classinfo_unwrap(clazz);
1039 s = javastring_new_from_utf_string(msg);
1041 /* instantiate exception object */
1043 o = native_new_and_init_string(c, s);
1048 exceptions_set_exception(o);
1054 /* ExceptionOccurred ***********************************************************
1056 Determines if an exception is being thrown. The exception stays
1057 being thrown until either the native code calls ExceptionClear(),
1058 or the Java code handles the exception.
1060 *******************************************************************************/
1062 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1066 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1068 o = exceptions_get_exception();
1070 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1074 /* ExceptionDescribe ***********************************************************
1076 Prints an exception and a backtrace of the stack to a system
1077 error-reporting channel, such as stderr. This is a convenience
1078 routine provided for debugging.
1080 *******************************************************************************/
1082 void jni_ExceptionDescribe(JNIEnv *env)
1084 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1086 exceptions_print_stacktrace();
1090 /* ExceptionClear **************************************************************
1092 Clears any exception that is currently being thrown. If no
1093 exception is currently being thrown, this routine has no effect.
1095 *******************************************************************************/
1097 void jni_ExceptionClear(JNIEnv *env)
1099 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1101 exceptions_clear_exception();
1105 /* FatalError ******************************************************************
1107 Raises a fatal error and does not expect the VM to recover. This
1108 function does not return.
1110 *******************************************************************************/
1112 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1114 STATISTICS(jniinvokation());
1116 /* this seems to be the best way */
1118 vm_abort("JNI Fatal error: %s", msg);
1122 /* PushLocalFrame **************************************************************
1124 Creates a new local reference frame, in which at least a given
1125 number of local references can be created.
1127 *******************************************************************************/
1129 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1131 STATISTICS(jniinvokation());
1136 /* add new local reference frame to current table */
1138 if (!localref_frame_push(capacity))
1145 /* PopLocalFrame ***************************************************************
1147 Pops off the current local reference frame, frees all the local
1148 references, and returns a local reference in the previous local
1149 reference frame for the given result object.
1151 *******************************************************************************/
1153 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1155 STATISTICS(jniinvokation());
1157 /* release all current local frames */
1159 localref_frame_pop_all();
1161 /* add local reference and return the value */
1163 return _Jv_JNI_NewLocalRef(env, result);
1167 /* DeleteLocalRef **************************************************************
1169 Deletes the local reference pointed to by localRef.
1171 *******************************************************************************/
1173 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1177 STATISTICS(jniinvokation());
1179 o = (java_handle_t *) localRef;
1184 /* delete the reference */
1190 /* IsSameObject ****************************************************************
1192 Tests whether two references refer to the same Java object.
1194 *******************************************************************************/
1196 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1202 STATISTICS(jniinvokation());
1204 o1 = (java_handle_t *) ref1;
1205 o2 = (java_handle_t *) ref2;
1207 LLNI_CRITICAL_START;
1209 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1220 /* NewLocalRef *****************************************************************
1222 Creates a new local reference that refers to the same object as ref.
1224 *******************************************************************************/
1226 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1229 java_handle_t *localref;
1231 STATISTICS(jniinvokation());
1233 o = (java_handle_t *) ref;
1238 /* insert the reference */
1240 localref = localref_add(LLNI_DIRECT(o));
1242 return (jobject) localref;
1246 /* EnsureLocalCapacity *********************************************************
1248 Ensures that at least a given number of local references can be
1249 created in the current thread
1251 *******************************************************************************/
1253 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1255 localref_table *lrt;
1257 STATISTICS(jniinvokation());
1259 /* get local reference table (thread specific) */
1261 lrt = LOCALREFTABLE;
1263 /* check if capacity elements are available in the local references table */
1265 if ((lrt->used + capacity) > lrt->capacity)
1266 return _Jv_JNI_PushLocalFrame(env, capacity);
1272 /* AllocObject *****************************************************************
1274 Allocates a new Java object without invoking any of the
1275 constructors for the object. Returns a reference to the object.
1277 *******************************************************************************/
1279 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1284 STATISTICS(jniinvokation());
1286 c = LLNI_classinfo_unwrap(clazz);
1288 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1289 exceptions_throw_instantiationexception(c);
1295 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1299 /* NewObject *******************************************************************
1301 Programmers place all arguments that are to be passed to the
1302 constructor immediately following the methodID
1303 argument. NewObject() accepts these arguments and passes them to
1304 the Java method that the programmer wishes to invoke.
1306 *******************************************************************************/
1308 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1315 STATISTICS(jniinvokation());
1317 c = LLNI_classinfo_unwrap(clazz);
1318 m = (methodinfo *) methodID;
1327 /* call constructor */
1329 va_start(ap, methodID);
1330 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1333 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1337 /* NewObjectV ******************************************************************
1339 Programmers place all arguments that are to be passed to the
1340 constructor in an args argument of type va_list that immediately
1341 follows the methodID argument. NewObjectV() accepts these
1342 arguments, and, in turn, passes them to the Java method that the
1343 programmer wishes to invoke.
1345 *******************************************************************************/
1347 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1354 STATISTICS(jniinvokation());
1356 c = LLNI_classinfo_unwrap(clazz);
1357 m = (methodinfo *) methodID;
1366 /* call constructor */
1368 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1370 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1374 /* NewObjectA *****************************************************************
1376 Programmers place all arguments that are to be passed to the
1377 constructor in an args array of jvalues that immediately follows
1378 the methodID argument. NewObjectA() accepts the arguments in this
1379 array, and, in turn, passes them to the Java method that the
1380 programmer wishes to invoke.
1382 *******************************************************************************/
1384 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1391 STATISTICS(jniinvokation());
1393 c = LLNI_classinfo_unwrap(clazz);
1394 m = (methodinfo *) methodID;
1403 /* call constructor */
1405 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1407 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1411 /* GetObjectClass **************************************************************
1413 Returns the class of an object.
1415 *******************************************************************************/
1417 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1421 java_lang_Class *co;
1423 STATISTICS(jniinvokation());
1425 o = (java_handle_t *) obj;
1427 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1430 LLNI_class_get(o, c);
1432 co = LLNI_classinfo_wrap(c);
1434 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1438 /* IsInstanceOf ****************************************************************
1440 Tests whether an object is an instance of a class.
1442 *******************************************************************************/
1444 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1447 java_lang_Object *o;
1449 STATISTICS(jniinvokation());
1451 c = (java_lang_Class *) clazz;
1452 o = (java_lang_Object *) obj;
1454 return _Jv_java_lang_Class_isInstance(c, o);
1458 /* Reflection Support *********************************************************/
1460 /* FromReflectedMethod *********************************************************
1462 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1463 object to a method ID.
1465 *******************************************************************************/
1467 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1469 #if defined(ENABLE_JAVASE)
1475 STATISTICS(jniinvokation());
1477 o = (java_handle_t *) method;
1482 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1483 java_lang_reflect_Method *rm;
1485 rm = (java_lang_reflect_Method *) method;
1486 LLNI_field_get_cls(rm, clazz, c);
1487 LLNI_field_get_val(rm, slot , slot);
1489 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1490 java_lang_reflect_Constructor *rc;
1492 rc = (java_lang_reflect_Constructor *) method;
1493 LLNI_field_get_cls(rc, clazz, c);
1494 LLNI_field_get_val(rc, slot , slot);
1499 m = &(c->methods[slot]);
1501 return (jmethodID) m;
1503 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1505 /* keep compiler happy */
1512 /* FromReflectedField **********************************************************
1514 Converts a java.lang.reflect.Field to a field ID.
1516 *******************************************************************************/
1518 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1520 #if defined(ENABLE_JAVASE)
1521 java_lang_reflect_Field *rf;
1526 STATISTICS(jniinvokation());
1528 rf = (java_lang_reflect_Field *) field;
1533 LLNI_field_get_cls(rf, clazz, c);
1534 LLNI_field_get_val(rf, slot , slot);
1535 f = &(c->fields[slot]);
1537 return (jfieldID) f;
1539 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1541 /* keep compiler happy */
1548 /* ToReflectedMethod ***********************************************************
1550 Converts a method ID derived from cls to an instance of the
1551 java.lang.reflect.Method class or to an instance of the
1552 java.lang.reflect.Constructor class.
1554 *******************************************************************************/
1556 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1559 #if defined(ENABLE_JAVASE)
1561 java_lang_reflect_Constructor *rc;
1562 java_lang_reflect_Method *rm;
1564 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1566 m = (methodinfo *) methodID;
1568 /* HotSpot does the same assert. */
1570 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1572 if (m->name == utf_init) {
1573 rc = reflect_constructor_new(m);
1575 return (jobject) rc;
1578 rm = reflect_method_new(m);
1580 return (jobject) rm;
1583 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1585 /* keep compiler happy */
1592 /* ToReflectedField ************************************************************
1594 Converts a field ID derived from cls to an instance of the
1595 java.lang.reflect.Field class.
1597 *******************************************************************************/
1599 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1602 STATISTICS(jniinvokation());
1604 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1610 /* Calling Instance Methods ***************************************************/
1612 /* GetMethodID *****************************************************************
1614 Returns the method ID for an instance (nonstatic) method of a class
1615 or interface. The method may be defined in one of the clazz's
1616 superclasses and inherited by clazz. The method is determined by
1617 its name and signature.
1619 GetMethodID() causes an uninitialized class to be initialized.
1621 *******************************************************************************/
1623 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1631 STATISTICS(jniinvokation());
1633 c = LLNI_classinfo_unwrap(clazz);
1638 if (!(c->state & CLASS_INITIALIZED))
1639 if (!initialize_class(c))
1642 /* try to get the method of the class or one of it's superclasses */
1644 uname = utf_new_char((char *) name);
1645 udesc = utf_new_char((char *) sig);
1647 m = class_resolvemethod(c, uname, udesc);
1649 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1650 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1655 return (jmethodID) m;
1659 /* JNI-functions for calling instance methods *********************************/
1661 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1662 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1663 jmethodID methodID, ...) \
1670 o = (java_handle_t *) obj; \
1671 m = (methodinfo *) methodID; \
1673 va_start(ap, methodID); \
1674 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1680 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1681 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1682 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1683 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1684 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1685 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1686 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1687 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1690 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1691 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1692 jmethodID methodID, va_list args) \
1698 o = (java_handle_t *) obj; \
1699 m = (methodinfo *) methodID; \
1701 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1706 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1707 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1708 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1709 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1710 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1711 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1712 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1713 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1716 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1717 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1718 jmethodID methodID, \
1719 const jvalue *args) \
1725 o = (java_handle_t *) obj; \
1726 m = (methodinfo *) methodID; \
1728 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1733 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1734 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1735 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1736 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1737 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1738 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1739 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1740 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1743 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1751 o = (java_handle_t *) obj;
1752 m = (methodinfo *) methodID;
1754 va_start(ap, methodID);
1755 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1758 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1762 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1769 o = (java_handle_t *) obj;
1770 m = (methodinfo *) methodID;
1772 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1774 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1778 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1785 o = (java_handle_t *) obj;
1786 m = (methodinfo *) methodID;
1788 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1790 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1795 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1801 o = (java_handle_t *) obj;
1802 m = (methodinfo *) methodID;
1804 va_start(ap, methodID);
1805 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1810 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1816 o = (java_handle_t *) obj;
1817 m = (methodinfo *) methodID;
1819 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1823 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1829 o = (java_handle_t *) obj;
1830 m = (methodinfo *) methodID;
1832 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1837 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1838 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1839 jclass clazz, jmethodID methodID, \
1848 o = (java_handle_t *) obj; \
1849 c = LLNI_classinfo_unwrap(clazz); \
1850 m = (methodinfo *) methodID; \
1852 va_start(ap, methodID); \
1853 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1859 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1860 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1861 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1862 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1863 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1864 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1865 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1866 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1869 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1870 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1871 jclass clazz, jmethodID methodID, \
1879 o = (java_handle_t *) obj; \
1880 c = LLNI_classinfo_unwrap(clazz); \
1881 m = (methodinfo *) methodID; \
1883 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1888 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1889 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1890 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1891 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1892 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1893 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1894 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1895 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1898 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1899 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1900 jclass clazz, jmethodID methodID, \
1901 const jvalue *args) \
1903 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1908 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1909 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1910 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1911 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1912 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1913 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1914 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1915 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1917 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1918 jclass clazz, jmethodID methodID,
1927 o = (java_handle_t *) obj;
1928 c = LLNI_classinfo_unwrap(clazz);
1929 m = (methodinfo *) methodID;
1931 va_start(ap, methodID);
1932 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1935 return _Jv_JNI_NewLocalRef(env, (jobject) r);
1939 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1940 jclass clazz, jmethodID methodID,
1948 o = (java_handle_t *) obj;
1949 c = LLNI_classinfo_unwrap(clazz);
1950 m = (methodinfo *) methodID;
1952 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1954 return _Jv_JNI_NewLocalRef(env, (jobject) r);
1958 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1959 jclass clazz, jmethodID methodID,
1962 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1964 return _Jv_JNI_NewLocalRef(env, NULL);
1968 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1969 jmethodID methodID, ...)
1976 o = (java_handle_t *) obj;
1977 c = LLNI_classinfo_unwrap(clazz);
1978 m = (methodinfo *) methodID;
1980 va_start(ap, methodID);
1981 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1986 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1987 jmethodID methodID, va_list args)
1993 o = (java_handle_t *) obj;
1994 c = LLNI_classinfo_unwrap(clazz);
1995 m = (methodinfo *) methodID;
1997 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2001 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2002 jmethodID methodID, const jvalue * args)
2008 o = (java_handle_t *) obj;
2009 c = LLNI_classinfo_unwrap(clazz);
2010 m = (methodinfo *) methodID;
2012 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2016 /* Accessing Fields of Objects ************************************************/
2018 /* GetFieldID ******************************************************************
2020 Returns the field ID for an instance (nonstatic) field of a
2021 class. The field is specified by its name and signature. The
2022 Get<type>Field and Set<type>Field families of accessor functions
2023 use field IDs to retrieve object fields.
2025 *******************************************************************************/
2027 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2035 STATISTICS(jniinvokation());
2037 c = LLNI_classinfo_unwrap(clazz);
2039 /* XXX NPE check? */
2041 uname = utf_new_char((char *) name);
2042 udesc = utf_new_char((char *) sig);
2044 f = class_findfield(c, uname, udesc);
2047 exceptions_throw_nosuchfielderror(c, uname);
2049 return (jfieldID) f;
2053 /* Get<type>Field Routines *****************************************************
2055 This family of accessor routines returns the value of an instance
2056 (nonstatic) field of an object. The field to access is specified by
2057 a field ID obtained by calling GetFieldID().
2059 *******************************************************************************/
2061 #define GET_FIELD(o,type,f) \
2062 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2064 #define JNI_GET_FIELD(name, type, intern) \
2065 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2069 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2071 LLNI_CRITICAL_START; \
2073 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2075 LLNI_CRITICAL_END; \
2077 return (type) ret; \
2080 JNI_GET_FIELD(Boolean, jboolean, s4)
2081 JNI_GET_FIELD(Byte, jbyte, s4)
2082 JNI_GET_FIELD(Char, jchar, s4)
2083 JNI_GET_FIELD(Short, jshort, s4)
2084 JNI_GET_FIELD(Int, jint, s4)
2085 JNI_GET_FIELD(Long, jlong, s8)
2086 JNI_GET_FIELD(Float, jfloat, float)
2087 JNI_GET_FIELD(Double, jdouble, double)
2090 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2094 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2096 LLNI_CRITICAL_START;
2098 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2102 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2106 /* Set<type>Field Routines *****************************************************
2108 This family of accessor routines sets the value of an instance
2109 (nonstatic) field of an object. The field to access is specified by
2110 a field ID obtained by calling GetFieldID().
2112 *******************************************************************************/
2114 #define SET_FIELD(o,type,f,value) \
2115 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2117 #define JNI_SET_FIELD(name, type, intern) \
2118 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2121 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2123 LLNI_CRITICAL_START; \
2125 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2127 LLNI_CRITICAL_START; \
2130 JNI_SET_FIELD(Boolean, jboolean, s4)
2131 JNI_SET_FIELD(Byte, jbyte, s4)
2132 JNI_SET_FIELD(Char, jchar, s4)
2133 JNI_SET_FIELD(Short, jshort, s4)
2134 JNI_SET_FIELD(Int, jint, s4)
2135 JNI_SET_FIELD(Long, jlong, s8)
2136 JNI_SET_FIELD(Float, jfloat, float)
2137 JNI_SET_FIELD(Double, jdouble, double)
2140 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2143 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2145 LLNI_CRITICAL_START;
2147 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2153 /* Calling Static Methods *****************************************************/
2155 /* GetStaticMethodID ***********************************************************
2157 Returns the method ID for a static method of a class. The method is
2158 specified by its name and signature.
2160 GetStaticMethodID() causes an uninitialized class to be
2163 *******************************************************************************/
2165 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2173 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2175 c = LLNI_classinfo_unwrap(clazz);
2180 if (!(c->state & CLASS_INITIALIZED))
2181 if (!initialize_class(c))
2184 /* try to get the static method of the class */
2186 uname = utf_new_char((char *) name);
2187 udesc = utf_new_char((char *) sig);
2189 m = class_resolvemethod(c, uname, udesc);
2191 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2192 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2197 return (jmethodID) m;
2201 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2202 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2203 jmethodID methodID, ...) \
2209 m = (methodinfo *) methodID; \
2211 va_start(ap, methodID); \
2212 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2218 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2219 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2220 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2221 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2222 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2223 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2224 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2225 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2228 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2229 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2230 jmethodID methodID, va_list args) \
2235 m = (methodinfo *) methodID; \
2237 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2242 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2243 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2244 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2245 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2246 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2247 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2248 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2249 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2252 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2253 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2254 jmethodID methodID, const jvalue *args) \
2259 m = (methodinfo *) methodID; \
2261 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2266 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2267 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2268 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2269 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2270 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2271 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2272 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2273 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2276 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2277 jmethodID methodID, ...)
2283 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2285 m = (methodinfo *) methodID;
2287 va_start(ap, methodID);
2288 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2291 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2295 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2296 jmethodID methodID, va_list args)
2301 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2303 m = (methodinfo *) methodID;
2305 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2307 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2311 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2312 jmethodID methodID, const jvalue *args)
2317 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2319 m = (methodinfo *) methodID;
2321 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2323 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2327 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2328 jmethodID methodID, ...)
2333 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2335 m = (methodinfo *) methodID;
2337 va_start(ap, methodID);
2338 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2343 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2344 jmethodID methodID, va_list args)
2348 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2350 m = (methodinfo *) methodID;
2352 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2356 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2357 jmethodID methodID, const jvalue * args)
2361 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2363 m = (methodinfo *) methodID;
2365 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2369 /* Accessing Static Fields ****************************************************/
2371 /* GetStaticFieldID ************************************************************
2373 Returns the field ID for a static field of a class. The field is
2374 specified by its name and signature. The GetStatic<type>Field and
2375 SetStatic<type>Field families of accessor functions use field IDs
2376 to retrieve static fields.
2378 *******************************************************************************/
2380 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2388 STATISTICS(jniinvokation());
2390 c = LLNI_classinfo_unwrap(clazz);
2392 uname = utf_new_char((char *) name);
2393 usig = utf_new_char((char *) sig);
2395 f = class_findfield(c, uname, usig);
2398 exceptions_throw_nosuchfielderror(c, uname);
2400 return (jfieldID) f;
2404 /* GetStatic<type>Field ********************************************************
2406 This family of accessor routines returns the value of a static
2409 *******************************************************************************/
2411 #define JNI_GET_STATIC_FIELD(name, type, field) \
2412 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2418 STATISTICS(jniinvokation()); \
2420 c = LLNI_classinfo_unwrap(clazz); \
2421 f = (fieldinfo *) fieldID; \
2423 if (!(c->state & CLASS_INITIALIZED)) \
2424 if (!initialize_class(c)) \
2427 return f->value->field; \
2430 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2431 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2432 JNI_GET_STATIC_FIELD(Char, jchar, i)
2433 JNI_GET_STATIC_FIELD(Short, jshort, i)
2434 JNI_GET_STATIC_FIELD(Int, jint, i)
2435 JNI_GET_STATIC_FIELD(Long, jlong, l)
2436 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2437 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2440 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2447 STATISTICS(jniinvokation());
2449 c = LLNI_classinfo_unwrap(clazz);
2450 f = (fieldinfo *) fieldID;
2452 if (!(c->state & CLASS_INITIALIZED))
2453 if (!initialize_class(c))
2456 h = LLNI_WRAP(f->value->a);
2458 return _Jv_JNI_NewLocalRef(env, (jobject) h);
2462 /* SetStatic<type>Field *******************************************************
2464 This family of accessor routines sets the value of a static field
2467 *******************************************************************************/
2469 #define JNI_SET_STATIC_FIELD(name, type, field) \
2470 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2477 STATISTICS(jniinvokation()); \
2479 c = LLNI_classinfo_unwrap(clazz); \
2480 f = (fieldinfo *) fieldID; \
2482 if (!(c->state & CLASS_INITIALIZED)) \
2483 if (!initialize_class(c)) \
2486 f->value->field = value; \
2489 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2490 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2491 JNI_SET_STATIC_FIELD(Char, jchar, i)
2492 JNI_SET_STATIC_FIELD(Short, jshort, i)
2493 JNI_SET_STATIC_FIELD(Int, jint, i)
2494 JNI_SET_STATIC_FIELD(Long, jlong, l)
2495 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2496 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2499 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2505 STATISTICS(jniinvokation());
2507 c = LLNI_classinfo_unwrap(clazz);
2508 f = (fieldinfo *) fieldID;
2510 if (!(c->state & CLASS_INITIALIZED))
2511 if (!initialize_class(c))
2514 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2518 /* String Operations **********************************************************/
2520 /* NewString *******************************************************************
2522 Create new java.lang.String object from an array of Unicode
2525 *******************************************************************************/
2527 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2529 java_lang_String *s;
2530 java_handle_chararray_t *a;
2533 STATISTICS(jniinvokation());
2535 s = (java_lang_String *) builtin_new(class_java_lang_String);
2536 a = builtin_newarray_char(len);
2538 /* javastring or characterarray could not be created */
2539 if ((a == NULL) || (s == NULL))
2543 for (i = 0; i < len; i++)
2544 LLNI_array_direct(a, i) = buf[i];
2546 LLNI_field_set_ref(s, value , a);
2547 LLNI_field_set_val(s, offset, 0);
2548 LLNI_field_set_val(s, count , len);
2550 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2554 static jchar emptyStringJ[]={0,0};
2556 /* GetStringLength *************************************************************
2558 Returns the length (the count of Unicode characters) of a Java
2561 *******************************************************************************/
2563 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2565 java_lang_String *s;
2568 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2570 s = (java_lang_String *) str;
2572 LLNI_field_get_val(s, count, len);
2578 /******************** convertes javastring to u2-array ****************************/
2580 u2 *javastring_tou2(jstring so)
2582 java_lang_String *s;
2583 java_handle_chararray_t *a;
2589 STATISTICS(jniinvokation());
2591 s = (java_lang_String *) so;
2596 LLNI_field_get_ref(s, value, a);
2601 LLNI_field_get_val(s, count, count);
2602 LLNI_field_get_val(s, offset, offset);
2604 /* allocate memory */
2606 stringbuffer = MNEW(u2, count + 1);
2610 for (i = 0; i < count; i++)
2611 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2613 /* terminate string */
2615 stringbuffer[i] = '\0';
2617 return stringbuffer;
2621 /* GetStringChars **************************************************************
2623 Returns a pointer to the array of Unicode characters of the
2624 string. This pointer is valid until ReleaseStringChars() is called.
2626 *******************************************************************************/
2628 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2632 STATISTICS(jniinvokation());
2634 jc = javastring_tou2(str);
2646 return emptyStringJ;
2650 /* ReleaseStringChars **********************************************************
2652 Informs the VM that the native code no longer needs access to
2653 chars. The chars argument is a pointer obtained from string using
2656 *******************************************************************************/
2658 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2660 java_lang_String *s;
2662 STATISTICS(jniinvokation());
2664 if (chars == emptyStringJ)
2667 s = (java_lang_String *) str;
2669 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2673 /* NewStringUTF ****************************************************************
2675 Constructs a new java.lang.String object from an array of UTF-8
2678 *******************************************************************************/
2680 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2682 java_lang_String *s;
2684 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2686 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2688 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2692 /****************** returns the utf8 length in bytes of a string *******************/
2694 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2696 java_lang_String *s;
2699 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2701 s = (java_lang_String *) string;
2703 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2709 /* GetStringUTFChars ***********************************************************
2711 Returns a pointer to an array of UTF-8 characters of the
2712 string. This array is valid until it is released by
2713 ReleaseStringUTFChars().
2715 *******************************************************************************/
2717 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2722 STATISTICS(jniinvokation());
2730 u = javastring_toutf((java_handle_t *) string, false);
2739 /* ReleaseStringUTFChars *******************************************************
2741 Informs the VM that the native code no longer needs access to
2742 utf. The utf argument is a pointer derived from string using
2743 GetStringUTFChars().
2745 *******************************************************************************/
2747 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2749 STATISTICS(jniinvokation());
2751 /* XXX we don't release utf chars right now, perhaps that should be done
2752 later. Since there is always one reference the garbage collector will
2757 /* Array Operations ***********************************************************/
2759 /* GetArrayLength **************************************************************
2761 Returns the number of elements in the array.
2763 *******************************************************************************/
2765 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2770 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2772 a = (java_handle_t *) array;
2774 size = LLNI_array_size(a);
2780 /* NewObjectArray **************************************************************
2782 Constructs a new array holding objects in class elementClass. All
2783 elements are initially set to initialElement.
2785 *******************************************************************************/
2787 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2788 jclass elementClass, jobject initialElement)
2792 java_handle_objectarray_t *oa;
2795 STATISTICS(jniinvokation());
2797 c = LLNI_classinfo_unwrap(elementClass);
2798 o = (java_handle_t *) initialElement;
2801 exceptions_throw_negativearraysizeexception();
2805 oa = builtin_anewarray(length, c);
2810 /* set all elements to initialElement */
2812 for (i = 0; i < length; i++)
2813 array_objectarray_element_set(oa, i, o);
2815 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2819 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2822 java_handle_objectarray_t *oa;
2825 STATISTICS(jniinvokation());
2827 oa = (java_handle_objectarray_t *) array;
2829 if (index >= LLNI_array_size(oa)) {
2830 exceptions_throw_arrayindexoutofboundsexception();
2834 o = array_objectarray_element_get(oa, index);
2836 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2840 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2841 jsize index, jobject val)
2843 java_handle_objectarray_t *oa;
2846 STATISTICS(jniinvokation());
2848 oa = (java_handle_objectarray_t *) array;
2849 o = (java_handle_t *) val;
2851 if (index >= LLNI_array_size(oa)) {
2852 exceptions_throw_arrayindexoutofboundsexception();
2856 /* check if the class of value is a subclass of the element class
2859 if (!builtin_canstore(oa, o))
2862 array_objectarray_element_set(oa, index, o);
2866 #define JNI_NEW_ARRAY(name, type, intern) \
2867 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2869 java_handle_##intern##array_t *a; \
2871 STATISTICS(jniinvokation()); \
2874 exceptions_throw_negativearraysizeexception(); \
2878 a = builtin_newarray_##intern(len); \
2880 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2883 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2884 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2885 JNI_NEW_ARRAY(Char, jcharArray, char)
2886 JNI_NEW_ARRAY(Short, jshortArray, byte)
2887 JNI_NEW_ARRAY(Int, jintArray, int)
2888 JNI_NEW_ARRAY(Long, jlongArray, long)
2889 JNI_NEW_ARRAY(Float, jfloatArray, float)
2890 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2893 /* Get<PrimitiveType>ArrayElements *********************************************
2895 A family of functions that returns the body of the primitive array.
2897 *******************************************************************************/
2899 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2900 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2903 java_handle_##intern##array_t *a; \
2905 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2907 a = (java_handle_##intern##array_t *) array; \
2910 *isCopy = JNI_FALSE; \
2912 return (type *) LLNI_array_data(a); \
2915 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2916 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2917 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2918 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2919 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2920 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2921 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2922 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2925 /* Release<PrimitiveType>ArrayElements *****************************************
2927 A family of functions that informs the VM that the native code no
2928 longer needs access to elems. The elems argument is a pointer
2929 derived from array using the corresponding
2930 Get<PrimitiveType>ArrayElements() function. If necessary, this
2931 function copies back all changes made to elems to the original
2934 *******************************************************************************/
2936 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2937 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2938 type *elems, jint mode) \
2940 java_handle_##intern##array_t *a; \
2942 STATISTICS(jniinvokation()); \
2944 a = (java_handle_##intern##array_t *) array; \
2946 if (elems != (type *) LLNI_array_data(a)) { \
2949 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2952 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2953 /* XXX TWISTI how should it be freed? */ \
2956 /* XXX TWISTI how should it be freed? */ \
2962 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2963 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2964 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2965 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2966 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2967 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2968 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2969 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2972 /* Get<PrimitiveType>ArrayRegion **********************************************
2974 A family of functions that copies a region of a primitive array
2977 *******************************************************************************/
2979 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2980 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2981 jsize start, jsize len, type *buf) \
2983 java_handle_##intern##array_t *a; \
2985 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2987 a = (java_handle_##intern##array_t *) array; \
2989 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2990 exceptions_throw_arrayindexoutofboundsexception(); \
2992 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
2995 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2996 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2997 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2998 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2999 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3000 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3001 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3002 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3005 /* Set<PrimitiveType>ArrayRegion **********************************************
3007 A family of functions that copies back a region of a primitive
3008 array from a buffer.
3010 *******************************************************************************/
3012 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3013 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3014 jsize start, jsize len, const type *buf) \
3016 java_handle_##intern##array_t *a; \
3018 STATISTICS(jniinvokation()); \
3020 a = (java_handle_##intern##array_t *) array; \
3022 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3023 exceptions_throw_arrayindexoutofboundsexception(); \
3025 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3028 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3029 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3030 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3031 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3032 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3033 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3034 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3035 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3038 /* Registering Native Methods *************************************************/
3040 /* RegisterNatives *************************************************************
3042 Registers native methods with the class specified by the clazz
3043 argument. The methods parameter specifies an array of
3044 JNINativeMethod structures that contain the names, signatures, and
3045 function pointers of the native methods. The nMethods parameter
3046 specifies the number of native methods in the array.
3048 *******************************************************************************/
3050 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3051 const JNINativeMethod *methods, jint nMethods)
3055 STATISTICS(jniinvokation());
3057 c = LLNI_classinfo_unwrap(clazz);
3059 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3060 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3063 native_method_register(c->name, methods, nMethods);
3069 /* UnregisterNatives ***********************************************************
3071 Unregisters native methods of a class. The class goes back to the
3072 state before it was linked or registered with its native method
3075 This function should not be used in normal native code. Instead, it
3076 provides special programs a way to reload and relink native
3079 *******************************************************************************/
3081 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3083 STATISTICS(jniinvokation());
3085 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3087 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3093 /* Monitor Operations *********************************************************/
3095 /* MonitorEnter ****************************************************************
3097 Enters the monitor associated with the underlying Java object
3100 *******************************************************************************/
3102 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3104 STATISTICS(jniinvokation());
3107 exceptions_throw_nullpointerexception();
3111 LOCK_MONITOR_ENTER(obj);
3117 /* MonitorExit *****************************************************************
3119 The current thread must be the owner of the monitor associated with
3120 the underlying Java object referred to by obj. The thread
3121 decrements the counter indicating the number of times it has
3122 entered this monitor. If the value of the counter becomes zero, the
3123 current thread releases the monitor.
3125 *******************************************************************************/
3127 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3129 STATISTICS(jniinvokation());
3132 exceptions_throw_nullpointerexception();
3136 LOCK_MONITOR_EXIT(obj);
3142 /* JavaVM Interface ***********************************************************/
3144 /* GetJavaVM *******************************************************************
3146 Returns the Java VM interface (used in the Invocation API)
3147 associated with the current thread. The result is placed at the
3148 location pointed to by the second argument, vm.
3150 *******************************************************************************/
3152 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3154 STATISTICS(jniinvokation());
3156 *vm = (JavaVM *) _Jv_jvm;
3162 /* GetStringRegion *************************************************************
3164 Copies len number of Unicode characters beginning at offset start
3165 to the given buffer buf.
3167 Throws StringIndexOutOfBoundsException on index overflow.
3169 *******************************************************************************/
3171 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3174 java_lang_String *s;
3175 java_handle_chararray_t *ca;
3177 STATISTICS(jniinvokation());
3179 s = (java_lang_String *) str;
3180 LLNI_field_get_ref(s, value, ca);
3182 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3183 (start + len > LLNI_field_direct(s, count))) {
3184 exceptions_throw_stringindexoutofboundsexception();
3188 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3192 /* GetStringUTFRegion **********************************************************
3194 Translates len number of Unicode characters beginning at offset
3195 start into UTF-8 format and place the result in the given buffer
3198 Throws StringIndexOutOfBoundsException on index overflow.
3200 *******************************************************************************/
3202 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3203 jsize len, char *buf)
3205 java_lang_String *s;
3206 java_handle_chararray_t *ca;
3211 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3213 s = (java_lang_String *) str;
3214 LLNI_field_get_ref(s, value, ca);
3215 LLNI_field_get_val(s, count, count);
3216 LLNI_field_get_val(s, offset, offset);
3218 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3219 exceptions_throw_stringindexoutofboundsexception();
3223 for (i = 0; i < len; i++)
3224 buf[i] = LLNI_array_direct(ca, offset + start + i);
3230 /* GetPrimitiveArrayCritical ***************************************************
3232 Obtain a direct pointer to array elements.
3234 *******************************************************************************/
3236 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3239 java_handle_bytearray_t *ba;
3242 ba = (java_handle_bytearray_t *) array;
3244 /* do the same as Kaffe does */
3246 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3252 /* ReleasePrimitiveArrayCritical ***********************************************
3254 No specific documentation.
3256 *******************************************************************************/
3258 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3259 void *carray, jint mode)
3261 STATISTICS(jniinvokation());
3263 /* do the same as Kaffe does */
3265 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3270 /* GetStringCritical ***********************************************************
3272 The semantics of these two functions are similar to the existing
3273 Get/ReleaseStringChars functions.
3275 *******************************************************************************/
3277 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3280 STATISTICS(jniinvokation());
3282 return _Jv_JNI_GetStringChars(env, string, isCopy);
3286 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3287 const jchar *cstring)
3289 STATISTICS(jniinvokation());
3291 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3295 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3297 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3303 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3305 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3309 /* NewGlobalRef ****************************************************************
3311 Creates a new global reference to the object referred to by the obj
3314 *******************************************************************************/
3316 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3318 hashtable_global_ref_entry *gre;
3319 u4 key; /* hashkey */
3320 u4 slot; /* slot in hashtable */
3323 STATISTICS(jniinvokation());
3325 o = (java_handle_t *) obj;
3327 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3329 LLNI_CRITICAL_START;
3331 /* normally addresses are aligned to 4, 8 or 16 bytes */
3333 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3334 slot = key & (hashtable_global_ref->size - 1);
3335 gre = hashtable_global_ref->ptr[slot];
3337 /* search external hash chain for the entry */
3340 if (gre->o == LLNI_DIRECT(o)) {
3341 /* global object found, increment the reference */
3348 gre = gre->hashlink; /* next element in external chain */
3353 /* global ref not found, create a new one */
3356 gre = NEW(hashtable_global_ref_entry);
3358 #if defined(ENABLE_GC_CACAO)
3359 /* register global ref with the GC */
3361 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3364 LLNI_CRITICAL_START;
3366 gre->o = LLNI_DIRECT(o);
3371 /* insert entry into hashtable */
3373 gre->hashlink = hashtable_global_ref->ptr[slot];
3375 hashtable_global_ref->ptr[slot] = gre;
3377 /* update number of hashtable-entries */
3379 hashtable_global_ref->entries++;
3382 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3384 #if defined(ENABLE_HANDLES)
3392 /* DeleteGlobalRef *************************************************************
3394 Deletes the global reference pointed to by globalRef.
3396 *******************************************************************************/
3398 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3400 hashtable_global_ref_entry *gre;
3401 hashtable_global_ref_entry *prevgre;
3402 u4 key; /* hashkey */
3403 u4 slot; /* slot in hashtable */
3406 STATISTICS(jniinvokation());
3408 o = (java_handle_t *) globalRef;
3410 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3412 LLNI_CRITICAL_START;
3414 /* normally addresses are aligned to 4, 8 or 16 bytes */
3416 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3417 slot = key & (hashtable_global_ref->size - 1);
3418 gre = hashtable_global_ref->ptr[slot];
3420 /* initialize prevgre */
3424 /* search external hash chain for the entry */
3427 if (gre->o == LLNI_DIRECT(o)) {
3428 /* global object found, decrement the reference count */
3432 /* if reference count is 0, remove the entry */
3434 if (gre->refs == 0) {
3435 /* special handling if it's the first in the chain */
3437 if (prevgre == NULL)
3438 hashtable_global_ref->ptr[slot] = gre->hashlink;
3440 prevgre->hashlink = gre->hashlink;
3442 #if defined(ENABLE_GC_CACAO)
3443 /* unregister global ref with the GC */
3445 gc_reference_unregister(&(gre->o));
3448 FREE(gre, hashtable_global_ref_entry);
3453 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3458 prevgre = gre; /* save current pointer for removal */
3459 gre = gre->hashlink; /* next element in external chain */
3462 log_println("JNI-DeleteGlobalRef: global reference not found");
3466 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3470 /* ExceptionCheck **************************************************************
3472 Returns JNI_TRUE when there is a pending exception; otherwise,
3475 *******************************************************************************/
3477 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3481 STATISTICS(jniinvokation());
3483 o = exceptions_get_exception();
3485 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3489 /* New JNI 1.4 functions ******************************************************/
3491 /* NewDirectByteBuffer *********************************************************
3493 Allocates and returns a direct java.nio.ByteBuffer referring to the
3494 block of memory starting at the memory address address and
3495 extending capacity bytes.
3497 *******************************************************************************/
3499 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3501 #if defined(ENABLE_JAVASE)
3502 # if defined(WITH_CLASSPATH_GNU)
3503 java_handle_t *nbuf;
3505 # if SIZEOF_VOID_P == 8
3506 gnu_classpath_Pointer64 *paddress;
3508 gnu_classpath_Pointer32 *paddress;
3511 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3513 /* alocate a gnu.classpath.Pointer{32,64} object */
3515 # if SIZEOF_VOID_P == 8
3516 if (!(paddress = (gnu_classpath_Pointer64 *)
3517 builtin_new(class_gnu_classpath_Pointer64)))
3519 if (!(paddress = (gnu_classpath_Pointer32 *)
3520 builtin_new(class_gnu_classpath_Pointer32)))
3524 /* fill gnu.classpath.Pointer{32,64} with address */
3526 LLNI_field_set_val(paddress, data, (ptrint) address);
3528 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3530 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3531 (jmethodID) dbbirw_init, NULL, paddress,
3532 (jint) capacity, (jint) capacity, (jint) 0);
3534 /* add local reference and return the value */
3536 return _Jv_JNI_NewLocalRef(env, nbuf);
3538 # elif defined(WITH_CLASSPATH_SUN)
3544 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3546 /* Be paranoid about address sign-extension. */
3548 addr = (int64_t) ((uintptr_t) address);
3549 cap = (int32_t) capacity;
3551 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3552 (jmethodID) dbb_init, addr, cap);
3554 /* Add local reference and return the value. */
3556 return _Jv_JNI_NewLocalRef(env, o);
3559 # error unknown classpath configuration
3563 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3565 /* keep compiler happy */
3572 /* GetDirectBufferAddress ******************************************************
3574 Fetches and returns the starting address of the memory region
3575 referenced by the given direct java.nio.Buffer.
3577 *******************************************************************************/
3579 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3581 #if defined(ENABLE_JAVASE)
3584 # if defined(WITH_CLASSPATH_GNU)
3586 java_nio_DirectByteBufferImpl *nbuf;
3587 gnu_classpath_Pointer *po;
3588 # if SIZEOF_VOID_P == 8
3589 gnu_classpath_Pointer64 *paddress;
3592 gnu_classpath_Pointer32 *paddress;
3597 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3599 /* Prevent compiler warning. */
3601 h = (java_handle_t *) buf;
3603 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3606 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3608 LLNI_field_get_ref(nbuf, address, po);
3610 # if SIZEOF_VOID_P == 8
3611 paddress = (gnu_classpath_Pointer64 *) po;
3613 paddress = (gnu_classpath_Pointer32 *) po;
3616 if (paddress == NULL)
3619 LLNI_field_get_val(paddress, data, address);
3621 p = (void *) (intptr_t) address;
3625 # elif defined(WITH_CLASSPATH_SUN)
3631 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3633 /* Prevent compiler warning. */
3635 h = (java_handle_t *) buf;
3637 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3640 o = (java_nio_Buffer *) buf;
3642 LLNI_field_get_val(o, address, address);
3644 p = (void *) (intptr_t) address;
3649 # error unknown classpath configuration
3654 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3656 /* keep compiler happy */
3664 /* GetDirectBufferCapacity *****************************************************
3666 Fetches and returns the capacity in bytes of the memory region
3667 referenced by the given direct java.nio.Buffer.
3669 *******************************************************************************/
3671 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3673 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3675 java_nio_Buffer *nbuf;
3678 STATISTICS(jniinvokation());
3680 o = (java_handle_t *) buf;
3682 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3685 nbuf = (java_nio_Buffer *) o;
3687 LLNI_field_get_val(nbuf, cap, capacity);
3691 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3693 /* keep compiler happy */
3700 /* GetObjectRefType ************************************************************
3702 Returns the type of the object referred to by the obj argument. The
3703 argument obj can either be a local, global or weak global
3706 *******************************************************************************/
3708 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3710 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3716 /* DestroyJavaVM ***************************************************************
3718 Unloads a Java VM and reclaims its resources. Only the main thread
3719 can unload the VM. The system waits until the main thread is only
3720 remaining user thread before it destroys the VM.
3722 *******************************************************************************/
3724 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3728 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3730 if (vm_created == false)
3733 status = vm_destroy(vm);
3739 /* AttachCurrentThread *********************************************************
3741 Attaches the current thread to a Java VM. Returns a JNI interface
3742 pointer in the JNIEnv argument.
3744 Trying to attach a thread that is already attached is a no-op.
3746 A native thread cannot be attached simultaneously to two Java VMs.
3748 When a thread is attached to the VM, the context class loader is
3749 the bootstrap loader.
3751 *******************************************************************************/
3753 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3755 #if defined(ENABLE_THREADS)
3756 JavaVMAttachArgs *vm_aargs;
3759 /* If the current thread has already been attached, this operation
3762 result = thread_current_is_attached();
3764 if (result == true) {
3770 vm_aargs = (JavaVMAttachArgs *) thr_args;
3772 if (vm_aargs != NULL) {
3773 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3774 (vm_aargs->version != JNI_VERSION_1_4))
3775 return JNI_EVERSION;
3778 if (!threads_attach_current_thread(vm_aargs, false))
3781 if (!localref_table_init())
3791 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3795 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3797 if (vm_created == false)
3800 result = jni_attach_current_thread(p_env, thr_args, false);
3806 /* DetachCurrentThread *********************************************************
3808 Detaches the current thread from a Java VM. All Java monitors held
3809 by this thread are released. All Java threads waiting for this
3810 thread to die are notified.
3812 In JDK 1.1, the main thread cannot be detached from the VM. It must
3813 call DestroyJavaVM to unload the entire VM.
3815 In the JDK, the main thread can be detached from the VM.
3817 The main thread, which is the thread that created the Java VM,
3818 cannot be detached from the VM. Instead, the main thread must call
3819 JNI_DestroyJavaVM() to unload the entire VM.
3821 *******************************************************************************/
3823 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3825 #if defined(ENABLE_THREADS)
3829 TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
3831 t = thread_get_current();
3837 /* If the given thread has already been detached, this operation
3840 result = thread_is_attached(t);
3842 if (result == false)
3845 /* We need to pop all frames before we can destroy the table. */
3847 localref_frame_pop_all();
3849 if (!localref_table_destroy())
3852 if (!threads_detach_thread(t))
3860 /* GetEnv **********************************************************************
3862 If the current thread is not attached to the VM, sets *env to NULL,
3863 and returns JNI_EDETACHED. If the specified version is not
3864 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3865 sets *env to the appropriate interface, and returns JNI_OK.
3867 *******************************************************************************/
3869 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3871 TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
3873 if (vm_created == false) {
3875 return JNI_EDETACHED;
3878 #if defined(ENABLE_THREADS)
3879 if (thread_get_current() == NULL) {
3882 return JNI_EDETACHED;
3886 /* Check the JNI version. */
3888 if (jni_version_check(version) == true) {
3893 #if defined(ENABLE_JVMTI)
3894 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3895 == JVMTI_VERSION_INTERFACE_JVMTI) {
3897 *env = (void *) jvmti_new_environment();
3906 return JNI_EVERSION;
3910 /* AttachCurrentThreadAsDaemon *************************************************
3912 Same semantics as AttachCurrentThread, but the newly-created
3913 java.lang.Thread instance is a daemon.
3915 If the thread has already been attached via either
3916 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3917 simply sets the value pointed to by penv to the JNIEnv of the
3918 current thread. In this case neither AttachCurrentThread nor this
3919 routine have any effect on the daemon status of the thread.
3921 *******************************************************************************/
3923 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3927 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
3929 if (vm_created == false)
3932 result = jni_attach_current_thread(penv, args, true);
3938 /* JNI invocation table *******************************************************/
3940 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3945 _Jv_JNI_DestroyJavaVM,
3946 _Jv_JNI_AttachCurrentThread,
3947 _Jv_JNI_DetachCurrentThread,
3949 _Jv_JNI_AttachCurrentThreadAsDaemon
3953 /* JNI function table *********************************************************/
3955 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3962 _Jv_JNI_DefineClass,
3964 _Jv_JNI_FromReflectedMethod,
3965 _Jv_JNI_FromReflectedField,
3966 _Jv_JNI_ToReflectedMethod,
3967 _Jv_JNI_GetSuperclass,
3968 _Jv_JNI_IsAssignableFrom,
3969 _Jv_JNI_ToReflectedField,
3973 _Jv_JNI_ExceptionOccurred,
3974 jni_ExceptionDescribe,
3977 _Jv_JNI_PushLocalFrame,
3978 _Jv_JNI_PopLocalFrame,
3980 _Jv_JNI_NewGlobalRef,
3981 _Jv_JNI_DeleteGlobalRef,
3982 _Jv_JNI_DeleteLocalRef,
3983 _Jv_JNI_IsSameObject,
3984 _Jv_JNI_NewLocalRef,
3985 _Jv_JNI_EnsureLocalCapacity,
3987 _Jv_JNI_AllocObject,
3992 _Jv_JNI_GetObjectClass,
3993 _Jv_JNI_IsInstanceOf,
3995 _Jv_JNI_GetMethodID,
3997 _Jv_JNI_CallObjectMethod,
3998 _Jv_JNI_CallObjectMethodV,
3999 _Jv_JNI_CallObjectMethodA,
4000 _Jv_JNI_CallBooleanMethod,
4001 _Jv_JNI_CallBooleanMethodV,
4002 _Jv_JNI_CallBooleanMethodA,
4003 _Jv_JNI_CallByteMethod,
4004 _Jv_JNI_CallByteMethodV,
4005 _Jv_JNI_CallByteMethodA,
4006 _Jv_JNI_CallCharMethod,
4007 _Jv_JNI_CallCharMethodV,
4008 _Jv_JNI_CallCharMethodA,
4009 _Jv_JNI_CallShortMethod,
4010 _Jv_JNI_CallShortMethodV,
4011 _Jv_JNI_CallShortMethodA,
4012 _Jv_JNI_CallIntMethod,
4013 _Jv_JNI_CallIntMethodV,
4014 _Jv_JNI_CallIntMethodA,
4015 _Jv_JNI_CallLongMethod,
4016 _Jv_JNI_CallLongMethodV,
4017 _Jv_JNI_CallLongMethodA,
4018 _Jv_JNI_CallFloatMethod,
4019 _Jv_JNI_CallFloatMethodV,
4020 _Jv_JNI_CallFloatMethodA,
4021 _Jv_JNI_CallDoubleMethod,
4022 _Jv_JNI_CallDoubleMethodV,
4023 _Jv_JNI_CallDoubleMethodA,
4024 _Jv_JNI_CallVoidMethod,
4025 _Jv_JNI_CallVoidMethodV,
4026 _Jv_JNI_CallVoidMethodA,
4028 _Jv_JNI_CallNonvirtualObjectMethod,
4029 _Jv_JNI_CallNonvirtualObjectMethodV,
4030 _Jv_JNI_CallNonvirtualObjectMethodA,
4031 _Jv_JNI_CallNonvirtualBooleanMethod,
4032 _Jv_JNI_CallNonvirtualBooleanMethodV,
4033 _Jv_JNI_CallNonvirtualBooleanMethodA,
4034 _Jv_JNI_CallNonvirtualByteMethod,
4035 _Jv_JNI_CallNonvirtualByteMethodV,
4036 _Jv_JNI_CallNonvirtualByteMethodA,
4037 _Jv_JNI_CallNonvirtualCharMethod,
4038 _Jv_JNI_CallNonvirtualCharMethodV,
4039 _Jv_JNI_CallNonvirtualCharMethodA,
4040 _Jv_JNI_CallNonvirtualShortMethod,
4041 _Jv_JNI_CallNonvirtualShortMethodV,
4042 _Jv_JNI_CallNonvirtualShortMethodA,
4043 _Jv_JNI_CallNonvirtualIntMethod,
4044 _Jv_JNI_CallNonvirtualIntMethodV,
4045 _Jv_JNI_CallNonvirtualIntMethodA,
4046 _Jv_JNI_CallNonvirtualLongMethod,
4047 _Jv_JNI_CallNonvirtualLongMethodV,
4048 _Jv_JNI_CallNonvirtualLongMethodA,
4049 _Jv_JNI_CallNonvirtualFloatMethod,
4050 _Jv_JNI_CallNonvirtualFloatMethodV,
4051 _Jv_JNI_CallNonvirtualFloatMethodA,
4052 _Jv_JNI_CallNonvirtualDoubleMethod,
4053 _Jv_JNI_CallNonvirtualDoubleMethodV,
4054 _Jv_JNI_CallNonvirtualDoubleMethodA,
4055 _Jv_JNI_CallNonvirtualVoidMethod,
4056 _Jv_JNI_CallNonvirtualVoidMethodV,
4057 _Jv_JNI_CallNonvirtualVoidMethodA,
4061 _Jv_JNI_GetObjectField,
4062 _Jv_JNI_GetBooleanField,
4063 _Jv_JNI_GetByteField,
4064 _Jv_JNI_GetCharField,
4065 _Jv_JNI_GetShortField,
4066 _Jv_JNI_GetIntField,
4067 _Jv_JNI_GetLongField,
4068 _Jv_JNI_GetFloatField,
4069 _Jv_JNI_GetDoubleField,
4070 _Jv_JNI_SetObjectField,
4071 _Jv_JNI_SetBooleanField,
4072 _Jv_JNI_SetByteField,
4073 _Jv_JNI_SetCharField,
4074 _Jv_JNI_SetShortField,
4075 _Jv_JNI_SetIntField,
4076 _Jv_JNI_SetLongField,
4077 _Jv_JNI_SetFloatField,
4078 _Jv_JNI_SetDoubleField,
4080 _Jv_JNI_GetStaticMethodID,
4082 _Jv_JNI_CallStaticObjectMethod,
4083 _Jv_JNI_CallStaticObjectMethodV,
4084 _Jv_JNI_CallStaticObjectMethodA,
4085 _Jv_JNI_CallStaticBooleanMethod,
4086 _Jv_JNI_CallStaticBooleanMethodV,
4087 _Jv_JNI_CallStaticBooleanMethodA,
4088 _Jv_JNI_CallStaticByteMethod,
4089 _Jv_JNI_CallStaticByteMethodV,
4090 _Jv_JNI_CallStaticByteMethodA,
4091 _Jv_JNI_CallStaticCharMethod,
4092 _Jv_JNI_CallStaticCharMethodV,
4093 _Jv_JNI_CallStaticCharMethodA,
4094 _Jv_JNI_CallStaticShortMethod,
4095 _Jv_JNI_CallStaticShortMethodV,
4096 _Jv_JNI_CallStaticShortMethodA,
4097 _Jv_JNI_CallStaticIntMethod,
4098 _Jv_JNI_CallStaticIntMethodV,
4099 _Jv_JNI_CallStaticIntMethodA,
4100 _Jv_JNI_CallStaticLongMethod,
4101 _Jv_JNI_CallStaticLongMethodV,
4102 _Jv_JNI_CallStaticLongMethodA,
4103 _Jv_JNI_CallStaticFloatMethod,
4104 _Jv_JNI_CallStaticFloatMethodV,
4105 _Jv_JNI_CallStaticFloatMethodA,
4106 _Jv_JNI_CallStaticDoubleMethod,
4107 _Jv_JNI_CallStaticDoubleMethodV,
4108 _Jv_JNI_CallStaticDoubleMethodA,
4109 _Jv_JNI_CallStaticVoidMethod,
4110 _Jv_JNI_CallStaticVoidMethodV,
4111 _Jv_JNI_CallStaticVoidMethodA,
4113 _Jv_JNI_GetStaticFieldID,
4115 _Jv_JNI_GetStaticObjectField,
4116 _Jv_JNI_GetStaticBooleanField,
4117 _Jv_JNI_GetStaticByteField,
4118 _Jv_JNI_GetStaticCharField,
4119 _Jv_JNI_GetStaticShortField,
4120 _Jv_JNI_GetStaticIntField,
4121 _Jv_JNI_GetStaticLongField,
4122 _Jv_JNI_GetStaticFloatField,
4123 _Jv_JNI_GetStaticDoubleField,
4124 _Jv_JNI_SetStaticObjectField,
4125 _Jv_JNI_SetStaticBooleanField,
4126 _Jv_JNI_SetStaticByteField,
4127 _Jv_JNI_SetStaticCharField,
4128 _Jv_JNI_SetStaticShortField,
4129 _Jv_JNI_SetStaticIntField,
4130 _Jv_JNI_SetStaticLongField,
4131 _Jv_JNI_SetStaticFloatField,
4132 _Jv_JNI_SetStaticDoubleField,
4135 _Jv_JNI_GetStringLength,
4136 _Jv_JNI_GetStringChars,
4137 _Jv_JNI_ReleaseStringChars,
4139 _Jv_JNI_NewStringUTF,
4140 _Jv_JNI_GetStringUTFLength,
4141 _Jv_JNI_GetStringUTFChars,
4142 _Jv_JNI_ReleaseStringUTFChars,
4144 _Jv_JNI_GetArrayLength,
4146 _Jv_JNI_NewObjectArray,
4147 _Jv_JNI_GetObjectArrayElement,
4148 _Jv_JNI_SetObjectArrayElement,
4150 _Jv_JNI_NewBooleanArray,
4151 _Jv_JNI_NewByteArray,
4152 _Jv_JNI_NewCharArray,
4153 _Jv_JNI_NewShortArray,
4154 _Jv_JNI_NewIntArray,
4155 _Jv_JNI_NewLongArray,
4156 _Jv_JNI_NewFloatArray,
4157 _Jv_JNI_NewDoubleArray,
4159 _Jv_JNI_GetBooleanArrayElements,
4160 _Jv_JNI_GetByteArrayElements,
4161 _Jv_JNI_GetCharArrayElements,
4162 _Jv_JNI_GetShortArrayElements,
4163 _Jv_JNI_GetIntArrayElements,
4164 _Jv_JNI_GetLongArrayElements,
4165 _Jv_JNI_GetFloatArrayElements,
4166 _Jv_JNI_GetDoubleArrayElements,
4168 _Jv_JNI_ReleaseBooleanArrayElements,
4169 _Jv_JNI_ReleaseByteArrayElements,
4170 _Jv_JNI_ReleaseCharArrayElements,
4171 _Jv_JNI_ReleaseShortArrayElements,
4172 _Jv_JNI_ReleaseIntArrayElements,
4173 _Jv_JNI_ReleaseLongArrayElements,
4174 _Jv_JNI_ReleaseFloatArrayElements,
4175 _Jv_JNI_ReleaseDoubleArrayElements,
4177 _Jv_JNI_GetBooleanArrayRegion,
4178 _Jv_JNI_GetByteArrayRegion,
4179 _Jv_JNI_GetCharArrayRegion,
4180 _Jv_JNI_GetShortArrayRegion,
4181 _Jv_JNI_GetIntArrayRegion,
4182 _Jv_JNI_GetLongArrayRegion,
4183 _Jv_JNI_GetFloatArrayRegion,
4184 _Jv_JNI_GetDoubleArrayRegion,
4185 _Jv_JNI_SetBooleanArrayRegion,
4186 _Jv_JNI_SetByteArrayRegion,
4187 _Jv_JNI_SetCharArrayRegion,
4188 _Jv_JNI_SetShortArrayRegion,
4189 _Jv_JNI_SetIntArrayRegion,
4190 _Jv_JNI_SetLongArrayRegion,
4191 _Jv_JNI_SetFloatArrayRegion,
4192 _Jv_JNI_SetDoubleArrayRegion,
4194 _Jv_JNI_RegisterNatives,
4195 _Jv_JNI_UnregisterNatives,
4197 _Jv_JNI_MonitorEnter,
4198 _Jv_JNI_MonitorExit,
4202 /* New JNI 1.2 functions. */
4204 _Jv_JNI_GetStringRegion,
4205 _Jv_JNI_GetStringUTFRegion,
4207 _Jv_JNI_GetPrimitiveArrayCritical,
4208 _Jv_JNI_ReleasePrimitiveArrayCritical,
4210 _Jv_JNI_GetStringCritical,
4211 _Jv_JNI_ReleaseStringCritical,
4213 _Jv_JNI_NewWeakGlobalRef,
4214 _Jv_JNI_DeleteWeakGlobalRef,
4216 _Jv_JNI_ExceptionCheck,
4218 /* New JNI 1.4 functions. */
4220 _Jv_JNI_NewDirectByteBuffer,
4221 _Jv_JNI_GetDirectBufferAddress,
4222 _Jv_JNI_GetDirectBufferCapacity,
4224 /* New JNI 1.6 functions. */
4226 jni_GetObjectRefType
4230 /* Invocation API Functions ***************************************************/
4232 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4234 Returns a default configuration for the Java VM.
4236 *******************************************************************************/
4238 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4240 JavaVMInitArgs *_vm_args;
4242 _vm_args = (JavaVMInitArgs *) vm_args;
4244 /* GNU classpath currently supports JNI 1.2 */
4246 switch (_vm_args->version) {
4247 case JNI_VERSION_1_1:
4248 _vm_args->version = JNI_VERSION_1_1;
4251 case JNI_VERSION_1_2:
4252 case JNI_VERSION_1_4:
4253 _vm_args->ignoreUnrecognized = JNI_FALSE;
4254 _vm_args->options = NULL;
4255 _vm_args->nOptions = 0;
4266 /* JNI_GetCreatedJavaVMs *******************************************************
4268 Returns all Java VMs that have been created. Pointers to VMs are written in
4269 the buffer vmBuf in the order they are created. At most bufLen number of
4270 entries will be written. The total number of created VMs is returned in
4273 *******************************************************************************/
4275 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4277 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4282 /* We currently only support 1 VM running. */
4284 vmBuf[0] = (JavaVM *) _Jv_jvm;
4291 /* JNI_CreateJavaVM ************************************************************
4293 Loads and initializes a Java VM. The current thread becomes the main thread.
4294 Sets the env argument to the JNI interface pointer of the main thread.
4296 *******************************************************************************/
4298 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4300 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4302 /* actually create the JVM */
4304 if (!vm_createjvm(p_vm, p_env, vm_args))
4312 * These are local overrides for various environment variables in Emacs.
4313 * Please do not remove this and leave it at the end of the file, where
4314 * Emacs will automagically detect them.
4315 * ---------------------------------------------------------------------
4318 * indent-tabs-mode: t
4322 * vim:noexpandtab:sw=4:ts=4: