1 /* src/native/jni.cpp - 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
35 #include "mm/memory.hpp"
37 #include "native/jni.hpp"
38 #include "native/llni.h"
39 #include "native/localref.hpp"
40 #include "native/native.hpp"
42 #if defined(ENABLE_JVMTI)
43 # include "native/jvmti/cacaodbg.h"
46 #include "threads/lock.hpp"
47 #include "threads/mutex.hpp"
48 #include "threads/thread.hpp"
50 #include "toolbox/logging.hpp"
52 #include "vm/array.hpp"
53 #include "vm/jit/builtin.hpp"
54 #include "vm/exceptions.hpp"
55 #include "vm/global.h"
56 #include "vm/globals.hpp"
57 #include "vm/initialize.hpp"
58 #include "vm/javaobjects.hpp"
59 #include "vm/loader.hpp"
60 #include "vm/options.h"
61 #include "vm/primitive.hpp"
62 #include "vm/resolve.hpp"
63 #include "vm/statistics.h"
64 #include "vm/string.hpp"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/jit.hpp"
69 #include "vm/jit/stacktrace.hpp"
72 /* debug **********************************************************************/
76 # define TRACEJNICALLS(x) \
78 if (opt_TraceJNICalls) { \
83 # define TRACEJNICALLSENTER(x) \
85 if (opt_TraceJNICalls) { \
91 # define TRACEJNICALLSEXIT(x) \
93 if (opt_TraceJNICalls) { \
101 # define TRACEJNICALLS(x)
102 # define TRACEJNICALLSENTER(x)
103 # define TRACEJNICALLSEXIT(x)
108 /* global variables ***********************************************************/
110 /* global reference table *****************************************************/
112 /* hashsize must be power of 2 */
114 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
116 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
119 /* direct buffer stuff ********************************************************/
121 #if defined(ENABLE_JAVASE)
122 static classinfo *class_java_nio_Buffer;
124 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
126 static classinfo *class_java_nio_DirectByteBufferImpl;
127 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
129 # if SIZEOF_VOID_P == 8
130 static classinfo *class_gnu_classpath_Pointer64;
132 static classinfo *class_gnu_classpath_Pointer32;
135 static methodinfo *dbbirw_init;
137 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
139 static classinfo *class_sun_nio_ch_DirectBuffer;
140 static classinfo *class_java_nio_DirectByteBuffer;
142 static methodinfo *dbb_init;
148 /* some forward declarations **************************************************/
151 jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
155 /* jni_init ********************************************************************
157 Initialize the JNI subsystem.
159 *******************************************************************************/
163 TRACESUBSYSTEMINITIALIZATION("jni_init");
165 /* create global ref hashtable */
167 hashtable_global_ref = NEW(hashtable);
169 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
172 #if defined(ENABLE_JAVASE)
173 /* Direct buffer stuff. */
175 if (!(class_java_nio_Buffer =
176 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
177 !link_class(class_java_nio_Buffer))
180 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
182 if (!(class_java_nio_DirectByteBufferImpl =
183 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
184 !link_class(class_java_nio_DirectByteBufferImpl))
187 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
188 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
189 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
193 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
195 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
198 # if SIZEOF_VOID_P == 8
199 if (!(class_gnu_classpath_Pointer64 =
200 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
201 !link_class(class_gnu_classpath_Pointer64))
204 if (!(class_gnu_classpath_Pointer32 =
205 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
206 !link_class(class_gnu_classpath_Pointer32))
210 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
212 if (!(class_sun_nio_ch_DirectBuffer =
213 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
214 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
216 if (!link_class(class_sun_nio_ch_DirectBuffer))
217 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
219 if (!(class_java_nio_DirectByteBuffer =
220 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
221 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
223 if (!link_class(class_java_nio_DirectByteBuffer))
224 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
227 class_resolvemethod(class_java_nio_DirectByteBuffer,
229 utf_new_char("(JI)V"))))
230 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
234 #endif /* defined(ENABLE_JAVASE) */
240 /* jni_version_check ***********************************************************
242 Check if the given JNI version is supported.
245 version....JNI version to check
249 false......not supported
251 *******************************************************************************/
253 bool jni_version_check(int version)
256 case JNI_VERSION_1_1:
257 case JNI_VERSION_1_2:
258 case JNI_VERSION_1_4:
259 case JNI_VERSION_1_6:
267 /* _Jv_jni_CallObjectMethod ****************************************************
269 Internal function to call Java Object methods.
271 *******************************************************************************/
273 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
275 methodinfo *m, va_list ap)
280 STATISTICS(jniinvokation());
283 exceptions_throw_nullpointerexception();
287 /* Class initialization is done by the JIT compiler. This is ok
288 since a static method always belongs to the declaring class. */
290 if (m->flags & ACC_STATIC) {
291 /* For static methods we reset the object. */
296 /* for convenience */
301 /* For instance methods we make a virtual function table lookup. */
303 resm = method_vftbl_lookup(vftbl, m);
306 STATISTICS(jnicallXmethodnvokation());
308 ro = vm_call_method_valist(resm, o, ap);
314 /* _Jv_jni_CallObjectMethodA ***************************************************
316 Internal function to call Java Object methods.
318 *******************************************************************************/
320 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
328 STATISTICS(jniinvokation());
331 exceptions_throw_nullpointerexception();
335 /* Class initialization is done by the JIT compiler. This is ok
336 since a static method always belongs to the declaring class. */
338 if (m->flags & ACC_STATIC) {
339 /* For static methods we reset the object. */
344 /* for convenience */
349 /* For instance methods we make a virtual function table lookup. */
351 resm = method_vftbl_lookup(vftbl, m);
354 STATISTICS(jnicallXmethodnvokation());
356 ro = vm_call_method_jvalue(resm, o, args);
362 /* _Jv_jni_CallIntMethod *******************************************************
364 Internal function to call Java integer class methods (boolean,
365 byte, char, short, int).
367 *******************************************************************************/
369 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
370 methodinfo *m, va_list ap)
375 STATISTICS(jniinvokation());
378 exceptions_throw_nullpointerexception();
382 /* Class initialization is done by the JIT compiler. This is ok
383 since a static method always belongs to the declaring class. */
385 if (m->flags & ACC_STATIC) {
386 /* For static methods we reset the object. */
391 /* for convenience */
396 /* For instance methods we make a virtual function table lookup. */
398 resm = method_vftbl_lookup(vftbl, m);
401 STATISTICS(jnicallXmethodnvokation());
403 i = vm_call_method_int_valist(resm, o, ap);
409 /* _Jv_jni_CallIntMethodA ******************************************************
411 Internal function to call Java integer class methods (boolean,
412 byte, char, short, int).
414 *******************************************************************************/
416 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
417 methodinfo *m, const jvalue *args)
422 STATISTICS(jniinvokation());
425 exceptions_throw_nullpointerexception();
429 /* Class initialization is done by the JIT compiler. This is ok
430 since a static method always belongs to the declaring class. */
432 if (m->flags & ACC_STATIC) {
433 /* For static methods we reset the object. */
438 /* for convenience */
443 /* For instance methods we make a virtual function table lookup. */
445 resm = method_vftbl_lookup(vftbl, m);
448 STATISTICS(jnicallXmethodnvokation());
450 i = vm_call_method_int_jvalue(resm, o, args);
456 /* _Jv_jni_CallLongMethod ******************************************************
458 Internal function to call Java long methods.
460 *******************************************************************************/
462 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
463 methodinfo *m, va_list ap)
468 STATISTICS(jniinvokation());
471 exceptions_throw_nullpointerexception();
475 /* Class initialization is done by the JIT compiler. This is ok
476 since a static method always belongs to the declaring class. */
478 if (m->flags & ACC_STATIC) {
479 /* For static methods we reset the object. */
484 /* for convenience */
489 /* For instance methods we make a virtual function table lookup. */
491 resm = method_vftbl_lookup(vftbl, m);
494 STATISTICS(jnicallXmethodnvokation());
496 l = vm_call_method_long_valist(resm, o, ap);
502 /* _Jv_jni_CallLongMethodA *****************************************************
504 Internal function to call Java long methods.
506 *******************************************************************************/
508 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
509 methodinfo *m, const jvalue *args)
514 STATISTICS(jniinvokation());
517 exceptions_throw_nullpointerexception();
521 /* Class initialization is done by the JIT compiler. This is ok
522 since a static method always belongs to the declaring class. */
524 if (m->flags & ACC_STATIC) {
525 /* For static methods we reset the object. */
530 /* for convenience */
535 /* For instance methods we make a virtual function table lookup. */
537 resm = method_vftbl_lookup(vftbl, m);
540 STATISTICS(jnicallXmethodnvokation());
542 l = vm_call_method_long_jvalue(resm, o, args);
548 /* _Jv_jni_CallFloatMethod *****************************************************
550 Internal function to call Java float methods.
552 *******************************************************************************/
554 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
555 methodinfo *m, va_list ap)
560 /* Class initialization is done by the JIT compiler. This is ok
561 since a static method always belongs to the declaring class. */
563 if (m->flags & ACC_STATIC) {
564 /* For static methods we reset the object. */
569 /* for convenience */
574 /* For instance methods we make a virtual function table lookup. */
576 resm = method_vftbl_lookup(vftbl, m);
579 STATISTICS(jnicallXmethodnvokation());
581 f = vm_call_method_float_valist(resm, o, ap);
587 /* _Jv_jni_CallFloatMethodA ****************************************************
589 Internal function to call Java float methods.
591 *******************************************************************************/
593 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
594 methodinfo *m, const jvalue *args)
599 /* Class initialization is done by the JIT compiler. This is ok
600 since a static method always belongs to the declaring class. */
602 if (m->flags & ACC_STATIC) {
603 /* For static methods we reset the object. */
608 /* for convenience */
613 /* For instance methods we make a virtual function table lookup. */
615 resm = method_vftbl_lookup(vftbl, m);
618 STATISTICS(jnicallXmethodnvokation());
620 f = vm_call_method_float_jvalue(resm, o, args);
626 /* _Jv_jni_CallDoubleMethod ****************************************************
628 Internal function to call Java double methods.
630 *******************************************************************************/
632 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
633 methodinfo *m, va_list ap)
638 /* Class initialization is done by the JIT compiler. This is ok
639 since a static method always belongs to the declaring class. */
641 if (m->flags & ACC_STATIC) {
642 /* For static methods we reset the object. */
647 /* for convenience */
652 /* For instance methods we make a virtual function table lookup. */
654 resm = method_vftbl_lookup(vftbl, m);
657 d = vm_call_method_double_valist(resm, o, ap);
663 /* _Jv_jni_CallDoubleMethodA ***************************************************
665 Internal function to call Java double methods.
667 *******************************************************************************/
669 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
670 methodinfo *m, const jvalue *args)
675 /* Class initialization is done by the JIT compiler. This is ok
676 since a static method always belongs to the declaring class. */
678 if (m->flags & ACC_STATIC) {
679 /* For static methods we reset the object. */
684 /* for convenience */
689 /* For instance methods we make a virtual function table lookup. */
691 resm = method_vftbl_lookup(vftbl, m);
694 d = vm_call_method_double_jvalue(resm, o, args);
700 /* _Jv_jni_CallVoidMethod ******************************************************
702 Internal function to call Java void methods.
704 *******************************************************************************/
706 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
707 methodinfo *m, va_list ap)
712 exceptions_throw_nullpointerexception();
716 /* Class initialization is done by the JIT compiler. This is ok
717 since a static method always belongs to the declaring class. */
719 if (m->flags & ACC_STATIC) {
720 /* For static methods we reset the object. */
725 /* for convenience */
730 /* For instance methods we make a virtual function table lookup. */
732 resm = method_vftbl_lookup(vftbl, m);
735 STATISTICS(jnicallXmethodnvokation());
737 (void) vm_call_method_valist(resm, o, ap);
741 /* _Jv_jni_CallVoidMethodA *****************************************************
743 Internal function to call Java void methods.
745 *******************************************************************************/
747 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
748 methodinfo *m, const jvalue *args)
753 exceptions_throw_nullpointerexception();
757 /* Class initialization is done by the JIT compiler. This is ok
758 since a static method always belongs to the declaring class. */
760 if (m->flags & ACC_STATIC) {
761 /* For static methods we reset the object. */
766 /* for convenience */
771 /* For instance methods we make a virtual function table lookup. */
773 resm = method_vftbl_lookup(vftbl, m);
776 STATISTICS(jnicallXmethodnvokation());
778 (void) vm_call_method_jvalue(resm, o, args);
782 // JNI functions are exported as C functions.
785 /* GetVersion ******************************************************************
787 Returns the major version number in the higher 16 bits and the
788 minor version number in the lower 16 bits.
790 *******************************************************************************/
792 jint _Jv_JNI_GetVersion(JNIEnv *env)
794 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
796 /* We support JNI 1.6. */
798 return JNI_VERSION_1_6;
802 /* Class Operations ***********************************************************/
804 /* DefineClass *****************************************************************
806 Loads a class from a buffer of raw class data. The buffer
807 containing the raw class data is not referenced by the VM after the
808 DefineClass call returns, and it may be discarded if desired.
810 *******************************************************************************/
812 jclass jni_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
814 #if defined(ENABLE_JAVASE)
820 TRACEJNICALLS(("jni_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
822 u = utf_new_char(name);
823 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
825 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
827 h = LLNI_classinfo_wrap(c);
829 return (jclass) jni_NewLocalRef(env, (jobject) h);
831 vm_abort("jni_DefineClass: Not implemented in this configuration");
833 // Keep compiler happy.
840 /* FindClass *******************************************************************
842 This function loads a locally-defined class. It searches the
843 directories and zip files specified by the CLASSPATH environment
844 variable for the class with the specified name.
846 *******************************************************************************/
848 jclass jni_FindClass(JNIEnv *env, const char *name)
850 #if defined(ENABLE_JAVASE)
857 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
859 /* FIXME If name is NULL we have a problem here. */
861 u = utf_new_char_classname((char *) name);
863 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
864 exceptions_throw_noclassdeffounderror(u);
868 /* Check stacktrace for classloader, if one found use it,
869 otherwise use the system classloader. */
871 /* Quote from the JNI documentation:
873 In the Java 2 Platform, FindClass locates the class loader
874 associated with the current native method. If the native code
875 belongs to a system class, no class loader will be
876 involved. Otherwise, the proper class loader will be invoked to
877 load and link the named class. When FindClass is called through
878 the Invocation Interface, there is no current native method or
879 its associated class loader. In that case, the result of
880 ClassLoader.getBaseClassLoader is used." */
882 cc = stacktrace_get_current_class();
885 c = load_class_from_sysloader(u);
887 c = load_class_from_classloader(u, cc->classloader);
890 resolve_handle_pending_exception(true);
897 h = LLNI_classinfo_wrap(c);
899 return (jclass) jni_NewLocalRef(env, (jobject) h);
901 #elif defined(ENABLE_JAVAME_CLDC1_1)
906 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
908 u = utf_new_char_classname((char *) name);
909 c = load_class_bootstrap(u);
912 resolve_handle_pending_exception(true);
919 return (jclass) jni_NewLocalRef(env, (jobject) c);
922 vm_abort("jni_FindClass: not implemented in this configuration");
924 /* keep compiler happy */
931 /* GetSuperclass ***************************************************************
933 If clazz represents any class other than the class Object, then
934 this function returns the object that represents the superclass of
935 the class specified by clazz.
937 *******************************************************************************/
939 jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
944 TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
946 c = LLNI_classinfo_unwrap(sub);
951 super = class_get_superclass(c);
953 java_handle_t* h = LLNI_classinfo_wrap(super);
955 return (jclass) jni_NewLocalRef(env, (jobject) h);
959 /* IsAssignableFrom ************************************************************
961 Determines whether an object of sub can be safely cast to sup.
963 *******************************************************************************/
965 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
970 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
972 to = (classinfo *) sup;
973 from = (classinfo *) sub;
975 return class_is_assignable_from(to, from);
979 /* Throw ***********************************************************************
981 Causes a java.lang.Throwable object to be thrown.
983 *******************************************************************************/
985 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
989 STATISTICS(jniinvokation());
991 o = (java_handle_t *) obj;
993 exceptions_set_exception(o);
999 /* ThrowNew ********************************************************************
1001 Constructs an exception object from the specified class with the
1002 message specified by message and causes that exception to be
1005 *******************************************************************************/
1007 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1013 STATISTICS(jniinvokation());
1015 c = LLNI_classinfo_unwrap(clazz);
1018 s = javastring_new_from_utf_string(msg);
1020 /* instantiate exception object */
1022 o = native_new_and_init_string(c, s);
1027 exceptions_set_exception(o);
1033 /* ExceptionOccurred ***********************************************************
1035 Determines if an exception is being thrown. The exception stays
1036 being thrown until either the native code calls ExceptionClear(),
1037 or the Java code handles the exception.
1039 *******************************************************************************/
1041 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1045 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1047 o = exceptions_get_exception();
1049 return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1053 /* ExceptionDescribe ***********************************************************
1055 Prints an exception and a backtrace of the stack to a system
1056 error-reporting channel, such as stderr. This is a convenience
1057 routine provided for debugging.
1059 *******************************************************************************/
1061 void jni_ExceptionDescribe(JNIEnv *env)
1063 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1065 exceptions_print_stacktrace();
1069 /* ExceptionClear **************************************************************
1071 Clears any exception that is currently being thrown. If no
1072 exception is currently being thrown, this routine has no effect.
1074 *******************************************************************************/
1076 void jni_ExceptionClear(JNIEnv *env)
1078 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1080 exceptions_clear_exception();
1084 /* FatalError ******************************************************************
1086 Raises a fatal error and does not expect the VM to recover. This
1087 function does not return.
1089 *******************************************************************************/
1091 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1093 STATISTICS(jniinvokation());
1095 /* this seems to be the best way */
1097 vm_abort("JNI Fatal error: %s", msg);
1101 /* PushLocalFrame **************************************************************
1103 Creates a new local reference frame, in which at least a given
1104 number of local references can be created.
1106 *******************************************************************************/
1108 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1110 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1115 /* add new local reference frame to current table */
1117 if (!localref_frame_push(capacity))
1124 /* PopLocalFrame ***************************************************************
1126 Pops off the current local reference frame, frees all the local
1127 references, and returns a local reference in the previous local
1128 reference frame for the given result object.
1130 *******************************************************************************/
1132 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1134 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1136 /* release all current local frames */
1138 localref_frame_pop_all();
1140 /* add local reference and return the value */
1142 return jni_NewLocalRef(env, result);
1146 /* DeleteLocalRef **************************************************************
1148 Deletes the local reference pointed to by localRef.
1150 *******************************************************************************/
1152 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1156 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1158 o = (java_handle_t *) localRef;
1163 /* delete the reference */
1169 /* IsSameObject ****************************************************************
1171 Tests whether two references refer to the same Java object.
1173 *******************************************************************************/
1175 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1181 STATISTICS(jniinvokation());
1183 o1 = (java_handle_t *) ref1;
1184 o2 = (java_handle_t *) ref2;
1186 LLNI_CRITICAL_START;
1188 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1199 /* NewLocalRef *****************************************************************
1201 Creates a new local reference that refers to the same object as ref.
1203 *******************************************************************************/
1205 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1208 java_handle_t *localref;
1210 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1212 o = (java_handle_t *) ref;
1217 /* insert the reference */
1219 localref = localref_add(LLNI_DIRECT(o));
1221 return (jobject) localref;
1225 /* EnsureLocalCapacity *********************************************************
1227 Ensures that at least a given number of local references can be
1228 created in the current thread
1230 *******************************************************************************/
1232 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1234 localref_table *lrt;
1236 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1238 /* get local reference table (thread specific) */
1240 lrt = LOCALREFTABLE;
1242 /* check if capacity elements are available in the local references table */
1244 if ((lrt->used + capacity) > lrt->capacity)
1245 return jni_PushLocalFrame(env, capacity);
1251 /* AllocObject *****************************************************************
1253 Allocates a new Java object without invoking any of the
1254 constructors for the object. Returns a reference to the object.
1256 *******************************************************************************/
1258 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1263 STATISTICS(jniinvokation());
1265 c = LLNI_classinfo_unwrap(clazz);
1267 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1268 exceptions_throw_instantiationexception(c);
1274 return jni_NewLocalRef(env, (jobject) o);
1278 /* NewObject *******************************************************************
1280 Programmers place all arguments that are to be passed to the
1281 constructor immediately following the methodID
1282 argument. NewObject() accepts these arguments and passes them to
1283 the Java method that the programmer wishes to invoke.
1285 *******************************************************************************/
1287 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1294 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1296 c = LLNI_classinfo_unwrap(clazz);
1297 m = (methodinfo *) methodID;
1306 /* call constructor */
1308 va_start(ap, methodID);
1309 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1312 TRACEJNICALLSEXIT(("->%p", o));
1314 return jni_NewLocalRef(env, (jobject) o);
1318 /* NewObjectV ******************************************************************
1320 Programmers place all arguments that are to be passed to the
1321 constructor in an args argument of type va_list that immediately
1322 follows the methodID argument. NewObjectV() accepts these
1323 arguments, and, in turn, passes them to the Java method that the
1324 programmer wishes to invoke.
1326 *******************************************************************************/
1328 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1335 STATISTICS(jniinvokation());
1337 c = LLNI_classinfo_unwrap(clazz);
1338 m = (methodinfo *) methodID;
1347 /* call constructor */
1349 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1351 return jni_NewLocalRef(env, (jobject) o);
1355 /* NewObjectA *****************************************************************
1357 Programmers place all arguments that are to be passed to the
1358 constructor in an args array of jvalues that immediately follows
1359 the methodID argument. NewObjectA() accepts the arguments in this
1360 array, and, in turn, passes them to the Java method that the
1361 programmer wishes to invoke.
1363 *******************************************************************************/
1365 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1372 STATISTICS(jniinvokation());
1374 c = LLNI_classinfo_unwrap(clazz);
1375 m = (methodinfo *) methodID;
1384 /* call constructor */
1386 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1388 return jni_NewLocalRef(env, (jobject) o);
1392 /* GetObjectClass **************************************************************
1394 Returns the class of an object.
1396 *******************************************************************************/
1398 jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
1403 TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
1405 o = (java_handle_t *) obj;
1407 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1410 LLNI_class_get(o, c);
1412 java_handle_t* h = LLNI_classinfo_wrap(c);
1414 return (jclass) jni_NewLocalRef(env, (jobject) h);
1418 /* IsInstanceOf ****************************************************************
1420 Tests whether an object is an instance of a class.
1422 *******************************************************************************/
1424 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1429 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1431 /* XXX Is this correct? */
1432 c = LLNI_classinfo_unwrap(clazz);
1433 h = (java_handle_t *) obj;
1435 return class_is_instance(c, h);
1439 /* Reflection Support *********************************************************/
1441 /* FromReflectedMethod *********************************************************
1443 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1444 object to a method ID.
1446 *******************************************************************************/
1448 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1450 #if defined(ENABLE_JAVASE)
1453 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1455 java_lang_Object o(method);
1460 if (o.get_Class() == class_java_lang_reflect_Constructor) {
1461 java_lang_reflect_Constructor rc(method);
1462 m = rc.get_method();
1465 assert(o.get_Class() == class_java_lang_reflect_Method);
1467 java_lang_reflect_Method rm(method);
1468 m = rm.get_method();
1471 return (jmethodID) m;
1473 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1475 // Keep compiler happy.
1481 /* FromReflectedField **********************************************************
1483 Converts a java.lang.reflect.Field to a field ID.
1485 *******************************************************************************/
1487 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1489 #if defined(ENABLE_JAVASE)
1491 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1493 java_lang_reflect_Field rf(field);
1498 fieldinfo* f = rf.get_field();
1500 return (jfieldID) f;
1502 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1504 // Keep compiler happy.
1510 /* ToReflectedMethod ***********************************************************
1512 Converts a method ID derived from cls to an instance of the
1513 java.lang.reflect.Method class or to an instance of the
1514 java.lang.reflect.Constructor class.
1516 *******************************************************************************/
1518 jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1520 #if defined(ENABLE_JAVASE)
1521 TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1523 methodinfo* m = (methodinfo *) methodID;
1525 /* HotSpot does the same assert. */
1527 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1531 if (m->name == utf_init) {
1532 h = java_lang_reflect_Constructor(m).get_handle();
1535 h = java_lang_reflect_Method(m).get_handle();
1540 vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
1542 /* keep compiler happy */
1549 /* ToReflectedField ************************************************************
1551 Converts a field ID derived from cls to an instance of the
1552 java.lang.reflect.Field class.
1554 *******************************************************************************/
1556 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1559 STATISTICS(jniinvokation());
1561 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1567 /* Calling Instance Methods ***************************************************/
1569 /* GetMethodID *****************************************************************
1571 Returns the method ID for an instance (nonstatic) method of a class
1572 or interface. The method may be defined in one of the clazz's
1573 superclasses and inherited by clazz. The method is determined by
1574 its name and signature.
1576 GetMethodID() causes an uninitialized class to be initialized.
1578 *******************************************************************************/
1580 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1588 STATISTICS(jniinvokation());
1590 c = LLNI_classinfo_unwrap(clazz);
1595 if (!(c->state & CLASS_INITIALIZED))
1596 if (!initialize_class(c))
1599 /* try to get the method of the class or one of it's superclasses */
1601 uname = utf_new_char((char *) name);
1602 udesc = utf_new_char((char *) sig);
1604 m = class_resolvemethod(c, uname, udesc);
1606 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1607 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1612 return (jmethodID) m;
1616 /* JNI-functions for calling instance methods *********************************/
1618 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1619 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1620 jmethodID methodID, ...) \
1627 o = (java_handle_t *) obj; \
1628 m = (methodinfo *) methodID; \
1630 va_start(ap, methodID); \
1631 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1637 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1638 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1639 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1640 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1641 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1642 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1643 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1644 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1647 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1648 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1649 jmethodID methodID, va_list args) \
1655 o = (java_handle_t *) obj; \
1656 m = (methodinfo *) methodID; \
1658 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1663 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1664 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1665 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1666 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1667 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1668 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1669 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1670 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1673 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1674 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1675 jmethodID methodID, \
1676 const jvalue *args) \
1682 o = (java_handle_t *) obj; \
1683 m = (methodinfo *) methodID; \
1685 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1690 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1691 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1692 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1693 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1694 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1695 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1696 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1697 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1700 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1708 o = (java_handle_t *) obj;
1709 m = (methodinfo *) methodID;
1711 va_start(ap, methodID);
1712 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1715 return jni_NewLocalRef(env, (jobject) ret);
1719 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1726 o = (java_handle_t *) obj;
1727 m = (methodinfo *) methodID;
1729 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1731 return jni_NewLocalRef(env, (jobject) ret);
1735 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1742 o = (java_handle_t *) obj;
1743 m = (methodinfo *) methodID;
1745 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1747 return jni_NewLocalRef(env, (jobject) ret);
1752 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1758 o = (java_handle_t *) obj;
1759 m = (methodinfo *) methodID;
1761 va_start(ap, methodID);
1762 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1767 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1773 o = (java_handle_t *) obj;
1774 m = (methodinfo *) methodID;
1776 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1780 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1786 o = (java_handle_t *) obj;
1787 m = (methodinfo *) methodID;
1789 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1794 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1795 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1796 jclass clazz, jmethodID methodID, \
1805 o = (java_handle_t *) obj; \
1806 c = LLNI_classinfo_unwrap(clazz); \
1807 m = (methodinfo *) methodID; \
1809 va_start(ap, methodID); \
1810 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1816 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1817 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1818 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1819 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1820 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1821 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1822 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1823 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1826 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1827 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1828 jclass clazz, jmethodID methodID, \
1836 o = (java_handle_t *) obj; \
1837 c = LLNI_classinfo_unwrap(clazz); \
1838 m = (methodinfo *) methodID; \
1840 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1845 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1846 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1847 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1848 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1849 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1850 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1851 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1852 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1855 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1856 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1857 jclass clazz, jmethodID methodID, \
1858 const jvalue *args) \
1860 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1865 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1866 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1867 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1868 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1869 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1870 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1871 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1872 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1874 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1875 jclass clazz, jmethodID methodID,
1884 o = (java_handle_t *) obj;
1885 c = LLNI_classinfo_unwrap(clazz);
1886 m = (methodinfo *) methodID;
1888 va_start(ap, methodID);
1889 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1892 return jni_NewLocalRef(env, (jobject) r);
1896 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1897 jclass clazz, jmethodID methodID,
1905 o = (java_handle_t *) obj;
1906 c = LLNI_classinfo_unwrap(clazz);
1907 m = (methodinfo *) methodID;
1909 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1911 return jni_NewLocalRef(env, (jobject) r);
1915 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1916 jclass clazz, jmethodID methodID,
1919 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1921 return jni_NewLocalRef(env, NULL);
1925 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1926 jmethodID methodID, ...)
1933 o = (java_handle_t *) obj;
1934 c = LLNI_classinfo_unwrap(clazz);
1935 m = (methodinfo *) methodID;
1937 va_start(ap, methodID);
1938 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1943 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1944 jmethodID methodID, va_list args)
1950 o = (java_handle_t *) obj;
1951 c = LLNI_classinfo_unwrap(clazz);
1952 m = (methodinfo *) methodID;
1954 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
1958 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
1959 jmethodID methodID, const jvalue * args)
1965 o = (java_handle_t *) obj;
1966 c = LLNI_classinfo_unwrap(clazz);
1967 m = (methodinfo *) methodID;
1969 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
1973 /* Accessing Fields of Objects ************************************************/
1975 /* GetFieldID ******************************************************************
1977 Returns the field ID for an instance (nonstatic) field of a
1978 class. The field is specified by its name and signature. The
1979 Get<type>Field and Set<type>Field families of accessor functions
1980 use field IDs to retrieve object fields.
1982 *******************************************************************************/
1984 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
1992 STATISTICS(jniinvokation());
1994 c = LLNI_classinfo_unwrap(clazz);
1996 /* XXX NPE check? */
1998 uname = utf_new_char((char *) name);
1999 udesc = utf_new_char((char *) sig);
2001 f = class_findfield(c, uname, udesc);
2004 exceptions_throw_nosuchfielderror(c, uname);
2006 return (jfieldID) f;
2010 /* Get<type>Field Routines *****************************************************
2012 This family of accessor routines returns the value of an instance
2013 (nonstatic) field of an object. The field to access is specified by
2014 a field ID obtained by calling GetFieldID().
2016 *******************************************************************************/
2018 #define GET_FIELD(o,type,f) \
2019 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2021 #define JNI_GET_FIELD(name, type, intern) \
2022 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2026 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2028 LLNI_CRITICAL_START; \
2030 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2032 LLNI_CRITICAL_END; \
2034 return (type) ret; \
2037 JNI_GET_FIELD(Boolean, jboolean, s4)
2038 JNI_GET_FIELD(Byte, jbyte, s4)
2039 JNI_GET_FIELD(Char, jchar, s4)
2040 JNI_GET_FIELD(Short, jshort, s4)
2041 JNI_GET_FIELD(Int, jint, s4)
2042 JNI_GET_FIELD(Long, jlong, s8)
2043 JNI_GET_FIELD(Float, jfloat, float)
2044 JNI_GET_FIELD(Double, jdouble, double)
2047 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2051 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2053 LLNI_CRITICAL_START;
2055 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2059 return jni_NewLocalRef(env, (jobject) o);
2063 /* Set<type>Field Routines *****************************************************
2065 This family of accessor routines sets the value of an instance
2066 (nonstatic) field of an object. The field to access is specified by
2067 a field ID obtained by calling GetFieldID().
2069 *******************************************************************************/
2071 #define SET_FIELD(o,type,f,value) \
2072 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2074 #define JNI_SET_FIELD(name, type, intern) \
2075 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2078 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2080 LLNI_CRITICAL_START; \
2082 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2084 LLNI_CRITICAL_START; \
2087 JNI_SET_FIELD(Boolean, jboolean, s4)
2088 JNI_SET_FIELD(Byte, jbyte, s4)
2089 JNI_SET_FIELD(Char, jchar, s4)
2090 JNI_SET_FIELD(Short, jshort, s4)
2091 JNI_SET_FIELD(Int, jint, s4)
2092 JNI_SET_FIELD(Long, jlong, s8)
2093 JNI_SET_FIELD(Float, jfloat, float)
2094 JNI_SET_FIELD(Double, jdouble, double)
2097 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2100 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2102 LLNI_CRITICAL_START;
2104 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2110 /* Calling Static Methods *****************************************************/
2112 /* GetStaticMethodID ***********************************************************
2114 Returns the method ID for a static method of a class. The method is
2115 specified by its name and signature.
2117 GetStaticMethodID() causes an uninitialized class to be
2120 *******************************************************************************/
2122 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2130 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2132 c = LLNI_classinfo_unwrap(clazz);
2137 if (!(c->state & CLASS_INITIALIZED))
2138 if (!initialize_class(c))
2141 /* try to get the static method of the class */
2143 uname = utf_new_char((char *) name);
2144 udesc = utf_new_char((char *) sig);
2146 m = class_resolvemethod(c, uname, udesc);
2148 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2149 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2154 return (jmethodID) m;
2158 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2159 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2160 jmethodID methodID, ...) \
2166 m = (methodinfo *) methodID; \
2168 va_start(ap, methodID); \
2169 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2175 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2176 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2177 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2178 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2179 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2180 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2181 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2182 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2185 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2186 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2187 jmethodID methodID, va_list args) \
2192 m = (methodinfo *) methodID; \
2194 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2199 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2200 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2201 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2202 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2203 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2204 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2205 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2206 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2209 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2210 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2211 jmethodID methodID, const jvalue *args) \
2216 m = (methodinfo *) methodID; \
2218 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2223 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2224 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2225 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2226 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2227 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2228 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2229 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2230 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2233 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2234 jmethodID methodID, ...)
2240 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2242 m = (methodinfo *) methodID;
2244 va_start(ap, methodID);
2245 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2248 return jni_NewLocalRef(env, (jobject) o);
2252 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2253 jmethodID methodID, va_list args)
2258 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2260 m = (methodinfo *) methodID;
2262 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2264 return jni_NewLocalRef(env, (jobject) o);
2268 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2269 jmethodID methodID, const jvalue *args)
2274 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2276 m = (methodinfo *) methodID;
2278 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2280 return jni_NewLocalRef(env, (jobject) o);
2284 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2285 jmethodID methodID, ...)
2290 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2292 m = (methodinfo *) methodID;
2294 va_start(ap, methodID);
2295 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2300 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2301 jmethodID methodID, va_list args)
2305 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2307 m = (methodinfo *) methodID;
2309 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2313 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2314 jmethodID methodID, const jvalue * args)
2318 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2320 m = (methodinfo *) methodID;
2322 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2326 /* Accessing Static Fields ****************************************************/
2328 /* GetStaticFieldID ************************************************************
2330 Returns the field ID for a static field of a class. The field is
2331 specified by its name and signature. The GetStatic<type>Field and
2332 SetStatic<type>Field families of accessor functions use field IDs
2333 to retrieve static fields.
2335 *******************************************************************************/
2337 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2345 STATISTICS(jniinvokation());
2347 c = LLNI_classinfo_unwrap(clazz);
2349 uname = utf_new_char((char *) name);
2350 usig = utf_new_char((char *) sig);
2352 f = class_findfield(c, uname, usig);
2355 exceptions_throw_nosuchfielderror(c, uname);
2357 return (jfieldID) f;
2361 /* GetStatic<type>Field ********************************************************
2363 This family of accessor routines returns the value of a static
2366 *******************************************************************************/
2368 #define JNI_GET_STATIC_FIELD(name, type, field) \
2369 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2375 STATISTICS(jniinvokation()); \
2377 c = LLNI_classinfo_unwrap(clazz); \
2378 f = (fieldinfo *) fieldID; \
2380 if (!(c->state & CLASS_INITIALIZED)) \
2381 if (!initialize_class(c)) \
2384 return f->value->field; \
2387 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2388 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2389 JNI_GET_STATIC_FIELD(Char, jchar, i)
2390 JNI_GET_STATIC_FIELD(Short, jshort, i)
2391 JNI_GET_STATIC_FIELD(Int, jint, i)
2392 JNI_GET_STATIC_FIELD(Long, jlong, l)
2393 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2394 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2397 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2404 STATISTICS(jniinvokation());
2406 c = LLNI_classinfo_unwrap(clazz);
2407 f = (fieldinfo *) fieldID;
2409 if (!(c->state & CLASS_INITIALIZED))
2410 if (!initialize_class(c))
2413 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2415 return jni_NewLocalRef(env, (jobject) h);
2419 /* SetStatic<type>Field *******************************************************
2421 This family of accessor routines sets the value of a static field
2424 *******************************************************************************/
2426 #define JNI_SET_STATIC_FIELD(name, type, field) \
2427 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2434 STATISTICS(jniinvokation()); \
2436 c = LLNI_classinfo_unwrap(clazz); \
2437 f = (fieldinfo *) fieldID; \
2439 if (!(c->state & CLASS_INITIALIZED)) \
2440 if (!initialize_class(c)) \
2443 f->value->field = value; \
2446 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2447 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2448 JNI_SET_STATIC_FIELD(Char, jchar, i)
2449 JNI_SET_STATIC_FIELD(Short, jshort, i)
2450 JNI_SET_STATIC_FIELD(Int, jint, i)
2451 JNI_SET_STATIC_FIELD(Long, jlong, l)
2452 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2453 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2456 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2462 STATISTICS(jniinvokation());
2464 c = LLNI_classinfo_unwrap(clazz);
2465 f = (fieldinfo *) fieldID;
2467 if (!(c->state & CLASS_INITIALIZED))
2468 if (!initialize_class(c))
2471 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2475 /* String Operations **********************************************************/
2477 /* NewString *******************************************************************
2479 Create new java.lang.String object from an array of Unicode
2482 *******************************************************************************/
2484 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
2486 TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
2488 java_handle_chararray_t* a = builtin_newarray_char(len);
2494 for (jsize i = 0; i < len; i++)
2495 LLNI_array_direct(a, i) = buf[i];
2497 java_handle_t* h = builtin_new(class_java_lang_String);
2502 java_lang_String s(h, a, len, 0);
2504 return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
2508 static jchar emptyStringJ[]={0,0};
2510 /* GetStringLength *************************************************************
2512 Returns the length (the count of Unicode characters) of a Java
2515 *******************************************************************************/
2517 jsize jni_GetStringLength(JNIEnv *env, jstring str)
2519 TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
2521 java_lang_String s(str);
2522 jsize count = s.get_count();
2524 TRACEJNICALLSEXIT(("->%d)", count));
2530 /* GetStringChars **************************************************************
2532 Returns a pointer to the array of Unicode characters of the
2533 string. This pointer is valid until ReleaseStringChars() is called.
2535 *******************************************************************************/
2537 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2542 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2545 // FIXME This is really ugly.
2546 return emptyStringJ;
2548 java_lang_String s(str);
2550 java_handle_chararray_t* ca = s.get_value();
2551 int32_t count = s.get_count();
2552 int32_t offset = s.get_offset();
2557 /* allocate memory */
2559 stringbuffer = MNEW(u2, count + 1);
2563 for (i = 0; i < count; i++)
2564 stringbuffer[i] = LLNI_array_direct(ca, offset + i);
2566 /* terminate string */
2568 stringbuffer[i] = '\0';
2573 return (jchar*) stringbuffer;
2577 /* ReleaseStringChars **********************************************************
2579 Informs the VM that the native code no longer needs access to
2580 chars. The chars argument is a pointer obtained from string using
2583 *******************************************************************************/
2585 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2587 TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
2590 if (chars == emptyStringJ)
2593 java_lang_String s(str);
2594 int32_t count = s.get_count();
2596 MFREE(((jchar*) chars), jchar, count + 1);
2600 /* NewStringUTF ****************************************************************
2602 Constructs a new java.lang.String object from an array of UTF-8
2605 *******************************************************************************/
2607 jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
2609 TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2611 java_handle_t *h = javastring_safe_new_from_utf8(bytes);
2613 return (jstring) jni_NewLocalRef(env, (jobject) h);
2617 /****************** returns the utf8 length in bytes of a string *******************/
2619 jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
2621 TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
2623 java_lang_String s(string);
2624 java_handle_chararray_t* ca = s.get_value();
2625 int32_t count = s.get_count();
2627 // FIXME GC critical section!
2628 int32_t length = u2_utflength(ca->data, count);
2634 /* GetStringUTFChars ***********************************************************
2636 Returns a pointer to an array of UTF-8 characters of the
2637 string. This array is valid until it is released by
2638 ReleaseStringUTFChars().
2640 *******************************************************************************/
2642 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2647 STATISTICS(jniinvokation());
2655 u = javastring_toutf((java_handle_t *) string, false);
2664 /* ReleaseStringUTFChars *******************************************************
2666 Informs the VM that the native code no longer needs access to
2667 utf. The utf argument is a pointer derived from string using
2668 GetStringUTFChars().
2670 *******************************************************************************/
2672 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2674 STATISTICS(jniinvokation());
2676 /* XXX we don't release utf chars right now, perhaps that should be done
2677 later. Since there is always one reference the garbage collector will
2682 /* Array Operations ***********************************************************/
2684 /* GetArrayLength **************************************************************
2686 Returns the number of elements in the array.
2688 *******************************************************************************/
2690 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2695 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2697 a = (java_handle_t *) array;
2699 size = LLNI_array_size(a);
2705 /* NewObjectArray **************************************************************
2707 Constructs a new array holding objects in class elementClass. All
2708 elements are initially set to initialElement.
2710 *******************************************************************************/
2712 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2713 jclass elementClass, jobject initialElement)
2717 java_handle_objectarray_t *oa;
2720 STATISTICS(jniinvokation());
2722 c = LLNI_classinfo_unwrap(elementClass);
2723 o = (java_handle_t *) initialElement;
2726 exceptions_throw_negativearraysizeexception();
2730 oa = builtin_anewarray(length, c);
2735 /* set all elements to initialElement */
2737 for (i = 0; i < length; i++)
2738 array_objectarray_element_set(oa, i, o);
2740 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2744 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2747 java_handle_objectarray_t *oa;
2750 STATISTICS(jniinvokation());
2752 oa = (java_handle_objectarray_t *) array;
2754 if (index >= LLNI_array_size(oa)) {
2755 exceptions_throw_arrayindexoutofboundsexception();
2759 o = array_objectarray_element_get(oa, index);
2761 return jni_NewLocalRef(env, (jobject) o);
2765 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2766 jsize index, jobject val)
2768 java_handle_objectarray_t *oa;
2771 STATISTICS(jniinvokation());
2773 oa = (java_handle_objectarray_t *) array;
2774 o = (java_handle_t *) val;
2776 if (index >= LLNI_array_size(oa)) {
2777 exceptions_throw_arrayindexoutofboundsexception();
2781 /* check if the class of value is a subclass of the element class
2784 if (!builtin_canstore(oa, o))
2787 array_objectarray_element_set(oa, index, o);
2791 #define JNI_NEW_ARRAY(name, type, intern) \
2792 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2794 java_handle_##intern##array_t *a; \
2796 STATISTICS(jniinvokation()); \
2799 exceptions_throw_negativearraysizeexception(); \
2803 a = builtin_newarray_##intern(len); \
2805 return (type) jni_NewLocalRef(env, (jobject) a); \
2808 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2809 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2810 JNI_NEW_ARRAY(Char, jcharArray, char)
2811 JNI_NEW_ARRAY(Short, jshortArray, short)
2812 JNI_NEW_ARRAY(Int, jintArray, int)
2813 JNI_NEW_ARRAY(Long, jlongArray, long)
2814 JNI_NEW_ARRAY(Float, jfloatArray, float)
2815 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2818 /* Get<PrimitiveType>ArrayElements *********************************************
2820 A family of functions that returns the body of the primitive array.
2822 *******************************************************************************/
2824 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2825 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2828 java_handle_##intern##array_t *a; \
2830 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2832 a = (java_handle_##intern##array_t *) array; \
2835 *isCopy = JNI_FALSE; \
2837 return (type *) LLNI_array_data(a); \
2840 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2841 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2842 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2843 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2844 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2845 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2846 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2847 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2850 /* Release<PrimitiveType>ArrayElements *****************************************
2852 A family of functions that informs the VM that the native code no
2853 longer needs access to elems. The elems argument is a pointer
2854 derived from array using the corresponding
2855 Get<PrimitiveType>ArrayElements() function. If necessary, this
2856 function copies back all changes made to elems to the original
2859 *******************************************************************************/
2861 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2862 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2863 type *elems, jint mode) \
2865 java_handle_##intern##array_t *a; \
2867 STATISTICS(jniinvokation()); \
2869 a = (java_handle_##intern##array_t *) array; \
2871 if (elems != (type *) LLNI_array_data(a)) { \
2874 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2877 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2878 /* XXX TWISTI how should it be freed? */ \
2881 /* XXX TWISTI how should it be freed? */ \
2887 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2888 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2889 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2890 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2891 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2892 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2893 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2894 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2897 /* Get<PrimitiveType>ArrayRegion **********************************************
2899 A family of functions that copies a region of a primitive array
2902 *******************************************************************************/
2904 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2905 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2906 jsize start, jsize len, type *buf) \
2908 java_handle_##intern##array_t *a; \
2910 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2912 a = (java_handle_##intern##array_t *) array; \
2914 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2915 exceptions_throw_arrayindexoutofboundsexception(); \
2917 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
2920 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2921 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2922 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2923 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2924 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
2925 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
2926 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
2927 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
2930 /* Set<PrimitiveType>ArrayRegion **********************************************
2932 A family of functions that copies back a region of a primitive
2933 array from a buffer.
2935 *******************************************************************************/
2937 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
2938 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
2939 jsize start, jsize len, const type *buf) \
2941 java_handle_##intern##array_t *a; \
2943 STATISTICS(jniinvokation()); \
2945 a = (java_handle_##intern##array_t *) array; \
2947 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2948 exceptions_throw_arrayindexoutofboundsexception(); \
2950 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
2953 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2954 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
2955 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
2956 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
2957 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
2958 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
2959 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
2960 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
2963 /* Registering Native Methods *************************************************/
2965 /* RegisterNatives *************************************************************
2967 Registers native methods with the class specified by the clazz
2968 argument. The methods parameter specifies an array of
2969 JNINativeMethod structures that contain the names, signatures, and
2970 function pointers of the native methods. The nMethods parameter
2971 specifies the number of native methods in the array.
2973 *******************************************************************************/
2975 jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
2977 TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
2979 classinfo* c = LLNI_classinfo_unwrap(clazz);
2981 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
2982 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
2985 NativeMethods& nm = VM::get_current()->get_nativemethods();
2986 nm.register_methods(c->name, methods, nMethods);
2992 /* UnregisterNatives ***********************************************************
2994 Unregisters native methods of a class. The class goes back to the
2995 state before it was linked or registered with its native method
2998 This function should not be used in normal native code. Instead, it
2999 provides special programs a way to reload and relink native
3002 *******************************************************************************/
3004 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3006 STATISTICS(jniinvokation());
3008 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3010 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3016 /* Monitor Operations *********************************************************/
3018 /* MonitorEnter ****************************************************************
3020 Enters the monitor associated with the underlying Java object
3023 *******************************************************************************/
3025 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3027 STATISTICS(jniinvokation());
3030 exceptions_throw_nullpointerexception();
3034 LOCK_MONITOR_ENTER(obj);
3040 /* MonitorExit *****************************************************************
3042 The current thread must be the owner of the monitor associated with
3043 the underlying Java object referred to by obj. The thread
3044 decrements the counter indicating the number of times it has
3045 entered this monitor. If the value of the counter becomes zero, the
3046 current thread releases the monitor.
3048 *******************************************************************************/
3050 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3052 STATISTICS(jniinvokation());
3055 exceptions_throw_nullpointerexception();
3059 LOCK_MONITOR_EXIT(obj);
3065 /* JavaVM Interface ***********************************************************/
3067 /* GetJavaVM *******************************************************************
3069 Returns the Java VM interface (used in the Invocation API)
3070 associated with the current thread. The result is placed at the
3071 location pointed to by the second argument, vm.
3073 *******************************************************************************/
3075 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3077 STATISTICS(jniinvokation());
3079 *javavm = VM::get_current()->get_javavm();
3085 /* GetStringRegion *************************************************************
3087 Copies len number of Unicode characters beginning at offset start
3088 to the given buffer buf.
3090 Throws StringIndexOutOfBoundsException on index overflow.
3092 *******************************************************************************/
3094 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3096 java_lang_String s(str);
3097 java_handle_chararray_t* ca = s.get_value();
3098 int32_t count = s.get_count();
3100 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3101 exceptions_throw_stringindexoutofboundsexception();
3105 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3109 /* GetStringUTFRegion **********************************************************
3111 Translates len number of Unicode characters beginning at offset
3112 start into UTF-8 format and place the result in the given buffer
3115 Throws StringIndexOutOfBoundsException on index overflow.
3117 *******************************************************************************/
3119 void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3121 TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3123 java_lang_String s(str);
3124 java_handle_chararray_t* ca = s.get_value();
3125 int32_t count = s.get_count();
3126 int32_t offset = s.get_offset();
3128 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3129 exceptions_throw_stringindexoutofboundsexception();
3135 for (i = 0; i < len; i++)
3136 buf[i] = LLNI_array_direct(ca, offset + start + i);
3142 /* GetPrimitiveArrayCritical ***************************************************
3144 Obtain a direct pointer to array elements.
3146 ATTENTION: Critical section keeps open when this function returns!
3147 See ReleasePrimitiveArrayCritical.
3149 *******************************************************************************/
3151 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3155 arraydescriptor* ad;
3158 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3160 if (isCopy != NULL) {
3161 *isCopy = JNI_FALSE;
3164 LLNI_CRITICAL_START;
3166 h = (java_handle_t*) array;
3167 a = (java_array_t*) LLNI_UNWRAP(h);
3168 ad = a->objheader.vftbl->arraydesc;
3174 data = (void*) (((intptr_t) a) + ad->dataoffset);
3180 /* ReleasePrimitiveArrayCritical ***********************************************
3182 No specific documentation.
3184 ATTENTION: This function closes the critical section opened in
3185 GetPrimitiveArrayCritical!
3187 *******************************************************************************/
3189 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3191 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3197 /* GetStringCritical ***********************************************************
3199 The semantics of these two functions are similar to the existing
3200 Get/ReleaseStringChars functions.
3202 *******************************************************************************/
3204 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3207 STATISTICS(jniinvokation());
3209 return jni_GetStringChars(env, string, isCopy);
3213 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3214 const jchar *cstring)
3216 STATISTICS(jniinvokation());
3218 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3222 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3224 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3230 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3232 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3236 /* NewGlobalRef ****************************************************************
3238 Creates a new global reference to the object referred to by the obj
3241 *******************************************************************************/
3243 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3245 hashtable_global_ref_entry *gre;
3246 u4 key; /* hashkey */
3247 u4 slot; /* slot in hashtable */
3250 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3252 o = (java_handle_t *) obj;
3254 hashtable_global_ref->mutex->lock();
3256 LLNI_CRITICAL_START;
3258 /* normally addresses are aligned to 4, 8 or 16 bytes */
3260 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3261 slot = key & (hashtable_global_ref->size - 1);
3262 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3264 /* search external hash chain for the entry */
3267 if (gre->o == LLNI_DIRECT(o)) {
3268 /* global object found, increment the reference */
3275 gre = gre->hashlink; /* next element in external chain */
3280 /* global ref not found, create a new one */
3283 gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3285 #if defined(ENABLE_GC_CACAO)
3286 /* register global ref with the GC */
3288 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3291 LLNI_CRITICAL_START;
3293 gre->o = LLNI_DIRECT(o);
3298 /* insert entry into hashtable */
3300 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3302 hashtable_global_ref->ptr[slot] = gre;
3304 /* update number of hashtable-entries */
3306 hashtable_global_ref->entries++;
3309 hashtable_global_ref->mutex->unlock();
3311 #if defined(ENABLE_HANDLES)
3319 /* DeleteGlobalRef *************************************************************
3321 Deletes the global reference pointed to by globalRef.
3323 *******************************************************************************/
3325 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3327 hashtable_global_ref_entry *gre;
3328 hashtable_global_ref_entry *prevgre;
3329 u4 key; /* hashkey */
3330 u4 slot; /* slot in hashtable */
3333 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3335 o = (java_handle_t *) globalRef;
3337 hashtable_global_ref->mutex->lock();
3339 LLNI_CRITICAL_START;
3341 /* normally addresses are aligned to 4, 8 or 16 bytes */
3343 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3344 slot = key & (hashtable_global_ref->size - 1);
3345 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3347 /* initialize prevgre */
3351 /* search external hash chain for the entry */
3354 if (gre->o == LLNI_DIRECT(o)) {
3355 /* global object found, decrement the reference count */
3359 /* if reference count is 0, remove the entry */
3361 if (gre->refs == 0) {
3362 /* special handling if it's the first in the chain */
3364 if (prevgre == NULL)
3365 hashtable_global_ref->ptr[slot] = gre->hashlink;
3367 prevgre->hashlink = gre->hashlink;
3369 #if defined(ENABLE_GC_CACAO)
3370 /* unregister global ref with the GC */
3372 gc_reference_unregister(&(gre->o));
3380 hashtable_global_ref->mutex->unlock();
3385 prevgre = gre; /* save current pointer for removal */
3386 gre = gre->hashlink; /* next element in external chain */
3389 log_println("jni_DeleteGlobalRef: Global reference not found.");
3393 hashtable_global_ref->mutex->unlock();
3397 /* ExceptionCheck **************************************************************
3399 Returns JNI_TRUE when there is a pending exception; otherwise,
3402 *******************************************************************************/
3404 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3408 STATISTICS(jniinvokation());
3410 o = exceptions_get_exception();
3412 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3416 /* New JNI 1.4 functions ******************************************************/
3418 /* NewDirectByteBuffer *********************************************************
3420 Allocates and returns a direct java.nio.ByteBuffer referring to the
3421 block of memory starting at the memory address address and
3422 extending capacity bytes.
3424 *******************************************************************************/
3426 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3428 #if defined(ENABLE_JAVASE)
3429 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3430 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3432 // Allocate a gnu.classpath.Pointer{32,64} object.
3434 # if SIZEOF_VOID_P == 8
3435 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
3437 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
3443 gnu_classpath_Pointer p(h, address);
3445 // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
3447 java_handle_t* nbuf =
3448 (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3449 (jmethodID) dbbirw_init, NULL, p.get_handle(),
3450 (jint) capacity, (jint) capacity, (jint) 0);
3452 // Add a local reference and return the value.
3454 TRACEJNICALLSEXIT(("->%p", nbuf));
3456 return jni_NewLocalRef(env, (jobject) nbuf);
3458 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3464 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3466 /* Be paranoid about address sign-extension. */
3468 addr = (int64_t) ((uintptr_t) address);
3469 cap = (int32_t) capacity;
3471 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3472 (jmethodID) dbb_init, addr, cap);
3474 /* Add local reference and return the value. */
3476 TRACEJNICALLSEXIT(("->%p", o));
3478 return jni_NewLocalRef(env, o);
3481 # error unknown classpath configuration
3485 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3487 /* keep compiler happy */
3494 /* GetDirectBufferAddress ******************************************************
3496 Fetches and returns the starting address of the memory region
3497 referenced by the given direct java.nio.Buffer.
3499 *******************************************************************************/
3501 void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3503 #if defined(ENABLE_JAVASE)
3504 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3506 TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3508 /* Prevent compiler warning. */
3510 java_handle_t* h = (java_handle_t *) buf;
3512 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3515 java_nio_DirectByteBufferImpl dbb(buf);
3516 java_handle_t* address = dbb.get_address();
3518 if (address == NULL) {
3519 TRACEJNICALLSEXIT(("->%p", NULL));
3523 gnu_classpath_Pointer p(address);
3524 void* data = p.get_data();
3526 TRACEJNICALLSEXIT(("->%p", data));
3530 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3532 TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3534 java_nio_Buffer jnb(buf);
3536 if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3539 void* address = jnb.get_address();
3544 # error unknown classpath configuration
3549 vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
3551 // Keep compiler happy.
3558 /* GetDirectBufferCapacity *****************************************************
3560 Fetches and returns the capacity in bytes of the memory region
3561 referenced by the given direct java.nio.Buffer.
3563 *******************************************************************************/
3565 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3567 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3568 TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3570 java_handle_t* h = (java_handle_t *) buf;
3572 if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
3575 java_nio_Buffer b(h);
3576 jlong capacity = b.get_cap();
3580 vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
3582 // Keep compiler happy.
3589 /* GetObjectRefType ************************************************************
3591 Returns the type of the object referred to by the obj argument. The
3592 argument obj can either be a local, global or weak global
3595 *******************************************************************************/
3597 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3599 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3601 return (jobjectRefType) NULL;
3605 /* DestroyJavaVM ***************************************************************
3607 Unloads a Java VM and reclaims its resources. Only the main thread
3608 can unload the VM. The system waits until the main thread is only
3609 remaining user thread before it destroys the VM.
3611 *******************************************************************************/
3613 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3617 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3619 if (VM::get_current()->is_created() == false)
3622 status = vm_destroy(javavm);
3628 /* AttachCurrentThread *********************************************************
3630 Attaches the current thread to a Java VM. Returns a JNI interface
3631 pointer in the JNIEnv argument.
3633 Trying to attach a thread that is already attached is a no-op.
3635 A native thread cannot be attached simultaneously to two Java VMs.
3637 When a thread is attached to the VM, the context class loader is
3638 the bootstrap loader.
3640 *******************************************************************************/
3642 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3644 #if defined(ENABLE_THREADS)
3645 JavaVMAttachArgs *vm_aargs;
3648 /* If the current thread has already been attached, this operation
3651 result = thread_current_is_attached();
3653 if (result == true) {
3654 *p_env = VM::get_current()->get_jnienv();
3658 vm_aargs = (JavaVMAttachArgs *) thr_args;
3660 if (vm_aargs != NULL) {
3661 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3662 (vm_aargs->version != JNI_VERSION_1_4))
3663 return JNI_EVERSION;
3666 if (!thread_attach_current_external_thread(vm_aargs, false))
3669 if (!localref_table_init())
3673 *p_env = VM::get_current()->get_jnienv();
3679 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3683 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3685 if (VM::get_current()->is_created() == false)
3688 result = jni_attach_current_thread(p_env, thr_args, false);
3694 /* DetachCurrentThread *********************************************************
3696 Detaches the current thread from a Java VM. All Java monitors held
3697 by this thread are released. All Java threads waiting for this
3698 thread to die are notified.
3700 In JDK 1.1, the main thread cannot be detached from the VM. It must
3701 call DestroyJavaVM to unload the entire VM.
3703 In the JDK, the main thread can be detached from the VM.
3705 The main thread, which is the thread that created the Java VM,
3706 cannot be detached from the VM. Instead, the main thread must call
3707 JNI_DestroyJavaVM() to unload the entire VM.
3709 *******************************************************************************/
3711 jint jni_DetachCurrentThread(JavaVM *vm)
3713 #if defined(ENABLE_THREADS)
3716 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3718 /* If the current thread has already been detached, this operation
3721 result = thread_current_is_attached();
3723 if (result == false)
3726 /* We need to pop all frames before we can destroy the table. */
3728 localref_frame_pop_all();
3730 if (!localref_table_destroy())
3733 if (!thread_detach_current_external_thread())
3741 /* GetEnv **********************************************************************
3743 If the current thread is not attached to the VM, sets *env to NULL,
3744 and returns JNI_EDETACHED. If the specified version is not
3745 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3746 sets *env to the appropriate interface, and returns JNI_OK.
3748 *******************************************************************************/
3750 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3752 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3754 if (VM::get_current()->is_created() == false) {
3756 return JNI_EDETACHED;
3759 #if defined(ENABLE_THREADS)
3760 if (thread_get_current() == NULL) {
3763 return JNI_EDETACHED;
3767 /* Check the JNI version. */
3769 if (jni_version_check(version) == true) {
3770 *env = VM::get_current()->get_jnienv();
3774 #if defined(ENABLE_JVMTI)
3775 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3776 == JVMTI_VERSION_INTERFACE_JVMTI) {
3778 *env = (void *) jvmti_new_environment();
3787 return JNI_EVERSION;
3791 /* AttachCurrentThreadAsDaemon *************************************************
3793 Same semantics as AttachCurrentThread, but the newly-created
3794 java.lang.Thread instance is a daemon.
3796 If the thread has already been attached via either
3797 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3798 simply sets the value pointed to by penv to the JNIEnv of the
3799 current thread. In this case neither AttachCurrentThread nor this
3800 routine have any effect on the daemon status of the thread.
3802 *******************************************************************************/
3804 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3808 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
3810 if (VM::get_current()->is_created() == false)
3813 result = jni_attach_current_thread(penv, args, true);
3819 /* JNI invocation table *******************************************************/
3821 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3826 _Jv_JNI_DestroyJavaVM,
3827 jni_AttachCurrentThread,
3828 jni_DetachCurrentThread,
3830 jni_AttachCurrentThreadAsDaemon
3834 /* JNI function table *********************************************************/
3836 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3845 jni_FromReflectedMethod,
3846 jni_FromReflectedField,
3847 jni_ToReflectedMethod,
3849 _Jv_JNI_IsAssignableFrom,
3850 _Jv_JNI_ToReflectedField,
3854 _Jv_JNI_ExceptionOccurred,
3855 jni_ExceptionDescribe,
3862 jni_DeleteGlobalRef,
3864 _Jv_JNI_IsSameObject,
3866 jni_EnsureLocalCapacity,
3868 _Jv_JNI_AllocObject,
3874 _Jv_JNI_IsInstanceOf,
3876 _Jv_JNI_GetMethodID,
3878 _Jv_JNI_CallObjectMethod,
3879 _Jv_JNI_CallObjectMethodV,
3880 _Jv_JNI_CallObjectMethodA,
3881 _Jv_JNI_CallBooleanMethod,
3882 _Jv_JNI_CallBooleanMethodV,
3883 _Jv_JNI_CallBooleanMethodA,
3884 _Jv_JNI_CallByteMethod,
3885 _Jv_JNI_CallByteMethodV,
3886 _Jv_JNI_CallByteMethodA,
3887 _Jv_JNI_CallCharMethod,
3888 _Jv_JNI_CallCharMethodV,
3889 _Jv_JNI_CallCharMethodA,
3890 _Jv_JNI_CallShortMethod,
3891 _Jv_JNI_CallShortMethodV,
3892 _Jv_JNI_CallShortMethodA,
3893 _Jv_JNI_CallIntMethod,
3894 _Jv_JNI_CallIntMethodV,
3895 _Jv_JNI_CallIntMethodA,
3896 _Jv_JNI_CallLongMethod,
3897 _Jv_JNI_CallLongMethodV,
3898 _Jv_JNI_CallLongMethodA,
3899 _Jv_JNI_CallFloatMethod,
3900 _Jv_JNI_CallFloatMethodV,
3901 _Jv_JNI_CallFloatMethodA,
3902 _Jv_JNI_CallDoubleMethod,
3903 _Jv_JNI_CallDoubleMethodV,
3904 _Jv_JNI_CallDoubleMethodA,
3905 _Jv_JNI_CallVoidMethod,
3906 _Jv_JNI_CallVoidMethodV,
3907 _Jv_JNI_CallVoidMethodA,
3909 _Jv_JNI_CallNonvirtualObjectMethod,
3910 _Jv_JNI_CallNonvirtualObjectMethodV,
3911 _Jv_JNI_CallNonvirtualObjectMethodA,
3912 _Jv_JNI_CallNonvirtualBooleanMethod,
3913 _Jv_JNI_CallNonvirtualBooleanMethodV,
3914 _Jv_JNI_CallNonvirtualBooleanMethodA,
3915 _Jv_JNI_CallNonvirtualByteMethod,
3916 _Jv_JNI_CallNonvirtualByteMethodV,
3917 _Jv_JNI_CallNonvirtualByteMethodA,
3918 _Jv_JNI_CallNonvirtualCharMethod,
3919 _Jv_JNI_CallNonvirtualCharMethodV,
3920 _Jv_JNI_CallNonvirtualCharMethodA,
3921 _Jv_JNI_CallNonvirtualShortMethod,
3922 _Jv_JNI_CallNonvirtualShortMethodV,
3923 _Jv_JNI_CallNonvirtualShortMethodA,
3924 _Jv_JNI_CallNonvirtualIntMethod,
3925 _Jv_JNI_CallNonvirtualIntMethodV,
3926 _Jv_JNI_CallNonvirtualIntMethodA,
3927 _Jv_JNI_CallNonvirtualLongMethod,
3928 _Jv_JNI_CallNonvirtualLongMethodV,
3929 _Jv_JNI_CallNonvirtualLongMethodA,
3930 _Jv_JNI_CallNonvirtualFloatMethod,
3931 _Jv_JNI_CallNonvirtualFloatMethodV,
3932 _Jv_JNI_CallNonvirtualFloatMethodA,
3933 _Jv_JNI_CallNonvirtualDoubleMethod,
3934 _Jv_JNI_CallNonvirtualDoubleMethodV,
3935 _Jv_JNI_CallNonvirtualDoubleMethodA,
3936 _Jv_JNI_CallNonvirtualVoidMethod,
3937 _Jv_JNI_CallNonvirtualVoidMethodV,
3938 _Jv_JNI_CallNonvirtualVoidMethodA,
3942 _Jv_JNI_GetObjectField,
3943 _Jv_JNI_GetBooleanField,
3944 _Jv_JNI_GetByteField,
3945 _Jv_JNI_GetCharField,
3946 _Jv_JNI_GetShortField,
3947 _Jv_JNI_GetIntField,
3948 _Jv_JNI_GetLongField,
3949 _Jv_JNI_GetFloatField,
3950 _Jv_JNI_GetDoubleField,
3951 _Jv_JNI_SetObjectField,
3952 _Jv_JNI_SetBooleanField,
3953 _Jv_JNI_SetByteField,
3954 _Jv_JNI_SetCharField,
3955 _Jv_JNI_SetShortField,
3956 _Jv_JNI_SetIntField,
3957 _Jv_JNI_SetLongField,
3958 _Jv_JNI_SetFloatField,
3959 _Jv_JNI_SetDoubleField,
3961 _Jv_JNI_GetStaticMethodID,
3963 _Jv_JNI_CallStaticObjectMethod,
3964 _Jv_JNI_CallStaticObjectMethodV,
3965 _Jv_JNI_CallStaticObjectMethodA,
3966 _Jv_JNI_CallStaticBooleanMethod,
3967 _Jv_JNI_CallStaticBooleanMethodV,
3968 _Jv_JNI_CallStaticBooleanMethodA,
3969 _Jv_JNI_CallStaticByteMethod,
3970 _Jv_JNI_CallStaticByteMethodV,
3971 _Jv_JNI_CallStaticByteMethodA,
3972 _Jv_JNI_CallStaticCharMethod,
3973 _Jv_JNI_CallStaticCharMethodV,
3974 _Jv_JNI_CallStaticCharMethodA,
3975 _Jv_JNI_CallStaticShortMethod,
3976 _Jv_JNI_CallStaticShortMethodV,
3977 _Jv_JNI_CallStaticShortMethodA,
3978 _Jv_JNI_CallStaticIntMethod,
3979 _Jv_JNI_CallStaticIntMethodV,
3980 _Jv_JNI_CallStaticIntMethodA,
3981 _Jv_JNI_CallStaticLongMethod,
3982 _Jv_JNI_CallStaticLongMethodV,
3983 _Jv_JNI_CallStaticLongMethodA,
3984 _Jv_JNI_CallStaticFloatMethod,
3985 _Jv_JNI_CallStaticFloatMethodV,
3986 _Jv_JNI_CallStaticFloatMethodA,
3987 _Jv_JNI_CallStaticDoubleMethod,
3988 _Jv_JNI_CallStaticDoubleMethodV,
3989 _Jv_JNI_CallStaticDoubleMethodA,
3990 _Jv_JNI_CallStaticVoidMethod,
3991 _Jv_JNI_CallStaticVoidMethodV,
3992 _Jv_JNI_CallStaticVoidMethodA,
3994 _Jv_JNI_GetStaticFieldID,
3996 _Jv_JNI_GetStaticObjectField,
3997 _Jv_JNI_GetStaticBooleanField,
3998 _Jv_JNI_GetStaticByteField,
3999 _Jv_JNI_GetStaticCharField,
4000 _Jv_JNI_GetStaticShortField,
4001 _Jv_JNI_GetStaticIntField,
4002 _Jv_JNI_GetStaticLongField,
4003 _Jv_JNI_GetStaticFloatField,
4004 _Jv_JNI_GetStaticDoubleField,
4005 _Jv_JNI_SetStaticObjectField,
4006 _Jv_JNI_SetStaticBooleanField,
4007 _Jv_JNI_SetStaticByteField,
4008 _Jv_JNI_SetStaticCharField,
4009 _Jv_JNI_SetStaticShortField,
4010 _Jv_JNI_SetStaticIntField,
4011 _Jv_JNI_SetStaticLongField,
4012 _Jv_JNI_SetStaticFloatField,
4013 _Jv_JNI_SetStaticDoubleField,
4016 jni_GetStringLength,
4018 _Jv_JNI_ReleaseStringChars,
4021 jni_GetStringUTFLength,
4022 _Jv_JNI_GetStringUTFChars,
4023 _Jv_JNI_ReleaseStringUTFChars,
4025 _Jv_JNI_GetArrayLength,
4027 _Jv_JNI_NewObjectArray,
4028 _Jv_JNI_GetObjectArrayElement,
4029 _Jv_JNI_SetObjectArrayElement,
4031 _Jv_JNI_NewBooleanArray,
4032 _Jv_JNI_NewByteArray,
4033 _Jv_JNI_NewCharArray,
4034 _Jv_JNI_NewShortArray,
4035 _Jv_JNI_NewIntArray,
4036 _Jv_JNI_NewLongArray,
4037 _Jv_JNI_NewFloatArray,
4038 _Jv_JNI_NewDoubleArray,
4040 _Jv_JNI_GetBooleanArrayElements,
4041 _Jv_JNI_GetByteArrayElements,
4042 _Jv_JNI_GetCharArrayElements,
4043 _Jv_JNI_GetShortArrayElements,
4044 _Jv_JNI_GetIntArrayElements,
4045 _Jv_JNI_GetLongArrayElements,
4046 _Jv_JNI_GetFloatArrayElements,
4047 _Jv_JNI_GetDoubleArrayElements,
4049 _Jv_JNI_ReleaseBooleanArrayElements,
4050 _Jv_JNI_ReleaseByteArrayElements,
4051 _Jv_JNI_ReleaseCharArrayElements,
4052 _Jv_JNI_ReleaseShortArrayElements,
4053 _Jv_JNI_ReleaseIntArrayElements,
4054 _Jv_JNI_ReleaseLongArrayElements,
4055 _Jv_JNI_ReleaseFloatArrayElements,
4056 _Jv_JNI_ReleaseDoubleArrayElements,
4058 _Jv_JNI_GetBooleanArrayRegion,
4059 _Jv_JNI_GetByteArrayRegion,
4060 _Jv_JNI_GetCharArrayRegion,
4061 _Jv_JNI_GetShortArrayRegion,
4062 _Jv_JNI_GetIntArrayRegion,
4063 _Jv_JNI_GetLongArrayRegion,
4064 _Jv_JNI_GetFloatArrayRegion,
4065 _Jv_JNI_GetDoubleArrayRegion,
4066 _Jv_JNI_SetBooleanArrayRegion,
4067 _Jv_JNI_SetByteArrayRegion,
4068 _Jv_JNI_SetCharArrayRegion,
4069 _Jv_JNI_SetShortArrayRegion,
4070 _Jv_JNI_SetIntArrayRegion,
4071 _Jv_JNI_SetLongArrayRegion,
4072 _Jv_JNI_SetFloatArrayRegion,
4073 _Jv_JNI_SetDoubleArrayRegion,
4075 jni_RegisterNatives,
4076 _Jv_JNI_UnregisterNatives,
4078 _Jv_JNI_MonitorEnter,
4079 _Jv_JNI_MonitorExit,
4083 /* New JNI 1.2 functions. */
4085 jni_GetStringRegion,
4086 jni_GetStringUTFRegion,
4088 jni_GetPrimitiveArrayCritical,
4089 jni_ReleasePrimitiveArrayCritical,
4091 _Jv_JNI_GetStringCritical,
4092 _Jv_JNI_ReleaseStringCritical,
4094 _Jv_JNI_NewWeakGlobalRef,
4095 _Jv_JNI_DeleteWeakGlobalRef,
4097 _Jv_JNI_ExceptionCheck,
4099 /* New JNI 1.4 functions. */
4101 jni_NewDirectByteBuffer,
4102 jni_GetDirectBufferAddress,
4103 jni_GetDirectBufferCapacity,
4105 /* New JNI 1.6 functions. */
4107 jni_GetObjectRefType
4111 /* Invocation API Functions ***************************************************/
4113 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4115 Returns a default configuration for the Java VM.
4117 *******************************************************************************/
4119 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4121 JavaVMInitArgs *_vm_args;
4123 _vm_args = (JavaVMInitArgs *) vm_args;
4125 /* GNU classpath currently supports JNI 1.2 */
4127 switch (_vm_args->version) {
4128 case JNI_VERSION_1_1:
4129 _vm_args->version = JNI_VERSION_1_1;
4132 case JNI_VERSION_1_2:
4133 case JNI_VERSION_1_4:
4134 _vm_args->ignoreUnrecognized = JNI_FALSE;
4135 _vm_args->options = NULL;
4136 _vm_args->nOptions = 0;
4147 /* JNI_GetCreatedJavaVMs *******************************************************
4149 Returns all Java VMs that have been created. Pointers to VMs are written in
4150 the buffer vmBuf in the order they are created. At most bufLen number of
4151 entries will be written. The total number of created VMs is returned in
4154 *******************************************************************************/
4156 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4158 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4163 // We currently only support 1 VM running.
4165 vmBuf[0] = VM::get_current()->get_javavm();
4172 /* JNI_CreateJavaVM ************************************************************
4174 Loads and initializes a Java VM. The current thread becomes the main thread.
4175 Sets the env argument to the JNI interface pointer of the main thread.
4177 *******************************************************************************/
4179 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4181 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4183 /* actually create the JVM */
4185 if (!VM_create(p_vm, p_env, vm_args))
4195 * These are local overrides for various environment variables in Emacs.
4196 * Please do not remove this and leave it at the end of the file, where
4197 * Emacs will automagically detect them.
4198 * ---------------------------------------------------------------------
4201 * indent-tabs-mode: t
4205 * vim:noexpandtab:sw=4:ts=4: