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 return JNI_VERSION_SUPPORTED;
800 /* Class Operations ***********************************************************/
802 /* DefineClass *****************************************************************
804 Loads a class from a buffer of raw class data. The buffer
805 containing the raw class data is not referenced by the VM after the
806 DefineClass call returns, and it may be discarded if desired.
808 *******************************************************************************/
810 jclass jni_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
812 #if defined(ENABLE_JAVASE)
818 TRACEJNICALLS(("jni_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
820 u = utf_new_char(name);
821 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
823 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
825 h = LLNI_classinfo_wrap(c);
827 return (jclass) jni_NewLocalRef(env, (jobject) h);
829 vm_abort("jni_DefineClass: Not implemented in this configuration");
831 // Keep compiler happy.
838 /* FindClass *******************************************************************
840 This function loads a locally-defined class. It searches the
841 directories and zip files specified by the CLASSPATH environment
842 variable for the class with the specified name.
844 *******************************************************************************/
846 jclass jni_FindClass(JNIEnv *env, const char *name)
848 #if defined(ENABLE_JAVASE)
855 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
857 /* FIXME If name is NULL we have a problem here. */
859 u = utf_new_char_classname((char *) name);
861 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
862 exceptions_throw_noclassdeffounderror(u);
866 /* Check stacktrace for classloader, if one found use it,
867 otherwise use the system classloader. */
869 /* Quote from the JNI documentation:
871 In the Java 2 Platform, FindClass locates the class loader
872 associated with the current native method. If the native code
873 belongs to a system class, no class loader will be
874 involved. Otherwise, the proper class loader will be invoked to
875 load and link the named class. When FindClass is called through
876 the Invocation Interface, there is no current native method or
877 its associated class loader. In that case, the result of
878 ClassLoader.getBaseClassLoader is used." */
880 cc = stacktrace_get_current_class();
883 c = load_class_from_sysloader(u);
885 c = load_class_from_classloader(u, cc->classloader);
888 resolve_handle_pending_exception(true);
895 h = LLNI_classinfo_wrap(c);
897 return (jclass) jni_NewLocalRef(env, (jobject) h);
899 #elif defined(ENABLE_JAVAME_CLDC1_1)
904 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
906 u = utf_new_char_classname((char *) name);
907 c = load_class_bootstrap(u);
910 resolve_handle_pending_exception(true);
917 return (jclass) jni_NewLocalRef(env, (jobject) c);
920 vm_abort("jni_FindClass: not implemented in this configuration");
922 /* keep compiler happy */
929 /* GetSuperclass ***************************************************************
931 If clazz represents any class other than the class Object, then
932 this function returns the object that represents the superclass of
933 the class specified by clazz.
935 *******************************************************************************/
937 jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
942 TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
944 c = LLNI_classinfo_unwrap(sub);
949 super = class_get_superclass(c);
951 java_handle_t* h = LLNI_classinfo_wrap(super);
953 return (jclass) jni_NewLocalRef(env, (jobject) h);
957 /* IsAssignableFrom ************************************************************
959 Determines whether an object of sub can be safely cast to sup.
961 *******************************************************************************/
963 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
968 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
970 to = (classinfo *) sup;
971 from = (classinfo *) sub;
973 return class_is_assignable_from(to, from);
977 /* Throw ***********************************************************************
979 Causes a java.lang.Throwable object to be thrown.
981 *******************************************************************************/
983 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
987 STATISTICS(jniinvokation());
989 o = (java_handle_t *) obj;
991 exceptions_set_exception(o);
997 /* ThrowNew ********************************************************************
999 Constructs an exception object from the specified class with the
1000 message specified by message and causes that exception to be
1003 *******************************************************************************/
1005 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1011 STATISTICS(jniinvokation());
1013 c = LLNI_classinfo_unwrap(clazz);
1016 s = javastring_new_from_utf_string(msg);
1018 /* instantiate exception object */
1020 o = native_new_and_init_string(c, s);
1025 exceptions_set_exception(o);
1031 /* ExceptionOccurred ***********************************************************
1033 Determines if an exception is being thrown. The exception stays
1034 being thrown until either the native code calls ExceptionClear(),
1035 or the Java code handles the exception.
1037 *******************************************************************************/
1039 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1043 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1045 o = exceptions_get_exception();
1047 return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1051 /* ExceptionDescribe ***********************************************************
1053 Prints an exception and a backtrace of the stack to a system
1054 error-reporting channel, such as stderr. This is a convenience
1055 routine provided for debugging.
1057 *******************************************************************************/
1059 void jni_ExceptionDescribe(JNIEnv *env)
1061 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1063 exceptions_print_stacktrace();
1067 /* ExceptionClear **************************************************************
1069 Clears any exception that is currently being thrown. If no
1070 exception is currently being thrown, this routine has no effect.
1072 *******************************************************************************/
1074 void jni_ExceptionClear(JNIEnv *env)
1076 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1078 exceptions_clear_exception();
1082 /* FatalError ******************************************************************
1084 Raises a fatal error and does not expect the VM to recover. This
1085 function does not return.
1087 *******************************************************************************/
1089 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1091 STATISTICS(jniinvokation());
1093 /* this seems to be the best way */
1095 vm_abort("JNI Fatal error: %s", msg);
1099 /* PushLocalFrame **************************************************************
1101 Creates a new local reference frame, in which at least a given
1102 number of local references can be created.
1104 *******************************************************************************/
1106 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1108 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1113 /* add new local reference frame to current table */
1115 if (!localref_frame_push(capacity))
1122 /* PopLocalFrame ***************************************************************
1124 Pops off the current local reference frame, frees all the local
1125 references, and returns a local reference in the previous local
1126 reference frame for the given result object.
1128 *******************************************************************************/
1130 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1132 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1134 /* release all current local frames */
1136 localref_frame_pop_all();
1138 /* add local reference and return the value */
1140 return jni_NewLocalRef(env, result);
1144 /* DeleteLocalRef **************************************************************
1146 Deletes the local reference pointed to by localRef.
1148 *******************************************************************************/
1150 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1154 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1156 o = (java_handle_t *) localRef;
1161 /* delete the reference */
1167 /* IsSameObject ****************************************************************
1169 Tests whether two references refer to the same Java object.
1171 *******************************************************************************/
1173 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1179 STATISTICS(jniinvokation());
1181 o1 = (java_handle_t *) ref1;
1182 o2 = (java_handle_t *) ref2;
1184 LLNI_CRITICAL_START;
1186 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1197 /* NewLocalRef *****************************************************************
1199 Creates a new local reference that refers to the same object as ref.
1201 *******************************************************************************/
1203 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1206 java_handle_t *localref;
1208 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1210 o = (java_handle_t *) ref;
1215 /* insert the reference */
1217 localref = localref_add(LLNI_DIRECT(o));
1219 return (jobject) localref;
1223 /* EnsureLocalCapacity *********************************************************
1225 Ensures that at least a given number of local references can be
1226 created in the current thread
1228 *******************************************************************************/
1230 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1232 localref_table *lrt;
1234 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1236 /* get local reference table (thread specific) */
1238 lrt = LOCALREFTABLE;
1240 /* check if capacity elements are available in the local references table */
1242 if ((lrt->used + capacity) > lrt->capacity)
1243 return jni_PushLocalFrame(env, capacity);
1249 /* AllocObject *****************************************************************
1251 Allocates a new Java object without invoking any of the
1252 constructors for the object. Returns a reference to the object.
1254 *******************************************************************************/
1256 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1261 STATISTICS(jniinvokation());
1263 c = LLNI_classinfo_unwrap(clazz);
1265 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1266 exceptions_throw_instantiationexception(c);
1272 return jni_NewLocalRef(env, (jobject) o);
1276 /* NewObject *******************************************************************
1278 Programmers place all arguments that are to be passed to the
1279 constructor immediately following the methodID
1280 argument. NewObject() accepts these arguments and passes them to
1281 the Java method that the programmer wishes to invoke.
1283 *******************************************************************************/
1285 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1292 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1294 c = LLNI_classinfo_unwrap(clazz);
1295 m = (methodinfo *) methodID;
1304 /* call constructor */
1306 va_start(ap, methodID);
1307 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1310 TRACEJNICALLSEXIT(("->%p", o));
1312 return jni_NewLocalRef(env, (jobject) o);
1316 /* NewObjectV ******************************************************************
1318 Programmers place all arguments that are to be passed to the
1319 constructor in an args argument of type va_list that immediately
1320 follows the methodID argument. NewObjectV() accepts these
1321 arguments, and, in turn, passes them to the Java method that the
1322 programmer wishes to invoke.
1324 *******************************************************************************/
1326 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1333 STATISTICS(jniinvokation());
1335 c = LLNI_classinfo_unwrap(clazz);
1336 m = (methodinfo *) methodID;
1345 /* call constructor */
1347 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1349 return jni_NewLocalRef(env, (jobject) o);
1353 /* NewObjectA *****************************************************************
1355 Programmers place all arguments that are to be passed to the
1356 constructor in an args array of jvalues that immediately follows
1357 the methodID argument. NewObjectA() accepts the arguments in this
1358 array, and, in turn, passes them to the Java method that the
1359 programmer wishes to invoke.
1361 *******************************************************************************/
1363 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1370 STATISTICS(jniinvokation());
1372 c = LLNI_classinfo_unwrap(clazz);
1373 m = (methodinfo *) methodID;
1382 /* call constructor */
1384 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1386 return jni_NewLocalRef(env, (jobject) o);
1390 /* GetObjectClass **************************************************************
1392 Returns the class of an object.
1394 *******************************************************************************/
1396 jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
1401 TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
1403 o = (java_handle_t *) obj;
1405 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1408 LLNI_class_get(o, c);
1410 java_handle_t* h = LLNI_classinfo_wrap(c);
1412 return (jclass) jni_NewLocalRef(env, (jobject) h);
1416 /* IsInstanceOf ****************************************************************
1418 Tests whether an object is an instance of a class.
1420 *******************************************************************************/
1422 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1427 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1429 /* XXX Is this correct? */
1430 c = LLNI_classinfo_unwrap(clazz);
1431 h = (java_handle_t *) obj;
1433 return class_is_instance(c, h);
1437 /* Reflection Support *********************************************************/
1439 /* FromReflectedMethod *********************************************************
1441 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1442 object to a method ID.
1444 *******************************************************************************/
1446 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1448 #if defined(ENABLE_JAVASE)
1451 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1453 java_lang_Object o(method);
1458 if (o.get_Class() == class_java_lang_reflect_Constructor) {
1459 java_lang_reflect_Constructor rc(method);
1460 m = rc.get_method();
1463 assert(o.get_Class() == class_java_lang_reflect_Method);
1465 java_lang_reflect_Method rm(method);
1466 m = rm.get_method();
1469 return (jmethodID) m;
1471 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1473 // Keep compiler happy.
1479 /* FromReflectedField **********************************************************
1481 Converts a java.lang.reflect.Field to a field ID.
1483 *******************************************************************************/
1485 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1487 #if defined(ENABLE_JAVASE)
1489 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1491 java_lang_reflect_Field rf(field);
1496 fieldinfo* f = rf.get_field();
1498 return (jfieldID) f;
1500 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1502 // Keep compiler happy.
1508 /* ToReflectedMethod ***********************************************************
1510 Converts a method ID derived from cls to an instance of the
1511 java.lang.reflect.Method class or to an instance of the
1512 java.lang.reflect.Constructor class.
1514 *******************************************************************************/
1516 jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1518 #if defined(ENABLE_JAVASE)
1519 TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1521 methodinfo* m = (methodinfo *) methodID;
1523 /* HotSpot does the same assert. */
1525 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1529 if (m->name == utf_init) {
1530 h = java_lang_reflect_Constructor(m).get_handle();
1533 h = java_lang_reflect_Method(m).get_handle();
1538 vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
1540 /* keep compiler happy */
1547 /* ToReflectedField ************************************************************
1549 Converts a field ID derived from cls to an instance of the
1550 java.lang.reflect.Field class.
1552 *******************************************************************************/
1554 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1557 STATISTICS(jniinvokation());
1559 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1565 /* Calling Instance Methods ***************************************************/
1567 /* GetMethodID *****************************************************************
1569 Returns the method ID for an instance (nonstatic) method of a class
1570 or interface. The method may be defined in one of the clazz's
1571 superclasses and inherited by clazz. The method is determined by
1572 its name and signature.
1574 GetMethodID() causes an uninitialized class to be initialized.
1576 *******************************************************************************/
1578 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1586 STATISTICS(jniinvokation());
1588 c = LLNI_classinfo_unwrap(clazz);
1593 if (!(c->state & CLASS_INITIALIZED))
1594 if (!initialize_class(c))
1597 /* try to get the method of the class or one of it's superclasses */
1599 uname = utf_new_char((char *) name);
1600 udesc = utf_new_char((char *) sig);
1602 m = class_resolvemethod(c, uname, udesc);
1604 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1605 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1610 return (jmethodID) m;
1614 /* JNI-functions for calling instance methods *********************************/
1616 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1617 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1618 jmethodID methodID, ...) \
1625 o = (java_handle_t *) obj; \
1626 m = (methodinfo *) methodID; \
1628 va_start(ap, methodID); \
1629 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1635 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1636 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1637 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1638 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1639 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1640 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1641 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1642 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1645 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1646 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1647 jmethodID methodID, va_list args) \
1653 o = (java_handle_t *) obj; \
1654 m = (methodinfo *) methodID; \
1656 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1661 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1662 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1663 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1664 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1665 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1666 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1667 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1668 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1671 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1672 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1673 jmethodID methodID, \
1674 const jvalue *args) \
1680 o = (java_handle_t *) obj; \
1681 m = (methodinfo *) methodID; \
1683 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1688 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1689 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1690 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1691 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1692 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1693 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1694 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1695 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1698 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1706 o = (java_handle_t *) obj;
1707 m = (methodinfo *) methodID;
1709 va_start(ap, methodID);
1710 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1713 return jni_NewLocalRef(env, (jobject) ret);
1717 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1724 o = (java_handle_t *) obj;
1725 m = (methodinfo *) methodID;
1727 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1729 return jni_NewLocalRef(env, (jobject) ret);
1733 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1740 o = (java_handle_t *) obj;
1741 m = (methodinfo *) methodID;
1743 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1745 return jni_NewLocalRef(env, (jobject) ret);
1750 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1756 o = (java_handle_t *) obj;
1757 m = (methodinfo *) methodID;
1759 va_start(ap, methodID);
1760 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1765 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1771 o = (java_handle_t *) obj;
1772 m = (methodinfo *) methodID;
1774 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1778 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1784 o = (java_handle_t *) obj;
1785 m = (methodinfo *) methodID;
1787 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1792 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1793 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1794 jclass clazz, jmethodID methodID, \
1803 o = (java_handle_t *) obj; \
1804 c = LLNI_classinfo_unwrap(clazz); \
1805 m = (methodinfo *) methodID; \
1807 va_start(ap, methodID); \
1808 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1814 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1815 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1816 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1817 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1818 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1819 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1820 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1821 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1824 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1825 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1826 jclass clazz, jmethodID methodID, \
1834 o = (java_handle_t *) obj; \
1835 c = LLNI_classinfo_unwrap(clazz); \
1836 m = (methodinfo *) methodID; \
1838 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1843 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1844 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1845 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1846 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1847 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1848 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1849 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1850 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1853 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1854 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1855 jclass clazz, jmethodID methodID, \
1856 const jvalue *args) \
1858 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1863 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1864 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1865 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1866 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1867 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1868 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1869 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1870 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1872 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1873 jclass clazz, jmethodID methodID,
1882 o = (java_handle_t *) obj;
1883 c = LLNI_classinfo_unwrap(clazz);
1884 m = (methodinfo *) methodID;
1886 va_start(ap, methodID);
1887 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1890 return jni_NewLocalRef(env, (jobject) r);
1894 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1895 jclass clazz, jmethodID methodID,
1903 o = (java_handle_t *) obj;
1904 c = LLNI_classinfo_unwrap(clazz);
1905 m = (methodinfo *) methodID;
1907 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1909 return jni_NewLocalRef(env, (jobject) r);
1913 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1914 jclass clazz, jmethodID methodID,
1917 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1919 return jni_NewLocalRef(env, NULL);
1923 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1924 jmethodID methodID, ...)
1931 o = (java_handle_t *) obj;
1932 c = LLNI_classinfo_unwrap(clazz);
1933 m = (methodinfo *) methodID;
1935 va_start(ap, methodID);
1936 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1941 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1942 jmethodID methodID, va_list args)
1948 o = (java_handle_t *) obj;
1949 c = LLNI_classinfo_unwrap(clazz);
1950 m = (methodinfo *) methodID;
1952 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
1956 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
1957 jmethodID methodID, const jvalue * args)
1963 o = (java_handle_t *) obj;
1964 c = LLNI_classinfo_unwrap(clazz);
1965 m = (methodinfo *) methodID;
1967 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
1971 /* Accessing Fields of Objects ************************************************/
1973 /* GetFieldID ******************************************************************
1975 Returns the field ID for an instance (nonstatic) field of a
1976 class. The field is specified by its name and signature. The
1977 Get<type>Field and Set<type>Field families of accessor functions
1978 use field IDs to retrieve object fields.
1980 *******************************************************************************/
1982 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
1990 STATISTICS(jniinvokation());
1992 c = LLNI_classinfo_unwrap(clazz);
1994 /* XXX NPE check? */
1996 uname = utf_new_char((char *) name);
1997 udesc = utf_new_char((char *) sig);
1999 f = class_findfield(c, uname, udesc);
2002 exceptions_throw_nosuchfielderror(c, uname);
2004 return (jfieldID) f;
2008 /* Get<type>Field Routines *****************************************************
2010 This family of accessor routines returns the value of an instance
2011 (nonstatic) field of an object. The field to access is specified by
2012 a field ID obtained by calling GetFieldID().
2014 *******************************************************************************/
2016 #define GET_FIELD(o,type,f) \
2017 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2019 #define JNI_GET_FIELD(name, type, intern) \
2020 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2024 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2026 LLNI_CRITICAL_START; \
2028 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2030 LLNI_CRITICAL_END; \
2032 return (type) ret; \
2035 JNI_GET_FIELD(Boolean, jboolean, s4)
2036 JNI_GET_FIELD(Byte, jbyte, s4)
2037 JNI_GET_FIELD(Char, jchar, s4)
2038 JNI_GET_FIELD(Short, jshort, s4)
2039 JNI_GET_FIELD(Int, jint, s4)
2040 JNI_GET_FIELD(Long, jlong, s8)
2041 JNI_GET_FIELD(Float, jfloat, float)
2042 JNI_GET_FIELD(Double, jdouble, double)
2045 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2049 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2051 LLNI_CRITICAL_START;
2053 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2057 return jni_NewLocalRef(env, (jobject) o);
2061 /* Set<type>Field Routines *****************************************************
2063 This family of accessor routines sets the value of an instance
2064 (nonstatic) field of an object. The field to access is specified by
2065 a field ID obtained by calling GetFieldID().
2067 *******************************************************************************/
2069 #define SET_FIELD(o,type,f,value) \
2070 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2072 #define JNI_SET_FIELD(name, type, intern) \
2073 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2076 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2078 LLNI_CRITICAL_START; \
2080 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2082 LLNI_CRITICAL_START; \
2085 JNI_SET_FIELD(Boolean, jboolean, s4)
2086 JNI_SET_FIELD(Byte, jbyte, s4)
2087 JNI_SET_FIELD(Char, jchar, s4)
2088 JNI_SET_FIELD(Short, jshort, s4)
2089 JNI_SET_FIELD(Int, jint, s4)
2090 JNI_SET_FIELD(Long, jlong, s8)
2091 JNI_SET_FIELD(Float, jfloat, float)
2092 JNI_SET_FIELD(Double, jdouble, double)
2095 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2098 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2100 LLNI_CRITICAL_START;
2102 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2108 /* Calling Static Methods *****************************************************/
2110 /* GetStaticMethodID ***********************************************************
2112 Returns the method ID for a static method of a class. The method is
2113 specified by its name and signature.
2115 GetStaticMethodID() causes an uninitialized class to be
2118 *******************************************************************************/
2120 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2128 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2130 c = LLNI_classinfo_unwrap(clazz);
2135 if (!(c->state & CLASS_INITIALIZED))
2136 if (!initialize_class(c))
2139 /* try to get the static method of the class */
2141 uname = utf_new_char((char *) name);
2142 udesc = utf_new_char((char *) sig);
2144 m = class_resolvemethod(c, uname, udesc);
2146 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2147 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2152 return (jmethodID) m;
2156 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2157 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2158 jmethodID methodID, ...) \
2164 m = (methodinfo *) methodID; \
2166 va_start(ap, methodID); \
2167 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2173 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2174 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2175 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2176 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2177 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2178 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2179 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2180 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2183 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2184 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2185 jmethodID methodID, va_list args) \
2190 m = (methodinfo *) methodID; \
2192 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2197 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2198 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2199 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2200 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2201 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2202 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2203 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2204 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2207 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2208 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2209 jmethodID methodID, const jvalue *args) \
2214 m = (methodinfo *) methodID; \
2216 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2221 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2222 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2223 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2224 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2225 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2226 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2227 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2228 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2231 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2232 jmethodID methodID, ...)
2238 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2240 m = (methodinfo *) methodID;
2242 va_start(ap, methodID);
2243 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2246 return jni_NewLocalRef(env, (jobject) o);
2250 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2251 jmethodID methodID, va_list args)
2256 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2258 m = (methodinfo *) methodID;
2260 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2262 return jni_NewLocalRef(env, (jobject) o);
2266 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2267 jmethodID methodID, const jvalue *args)
2272 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2274 m = (methodinfo *) methodID;
2276 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2278 return jni_NewLocalRef(env, (jobject) o);
2282 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2283 jmethodID methodID, ...)
2288 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2290 m = (methodinfo *) methodID;
2292 va_start(ap, methodID);
2293 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2298 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2299 jmethodID methodID, va_list args)
2303 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2305 m = (methodinfo *) methodID;
2307 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2311 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2312 jmethodID methodID, const jvalue * args)
2316 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2318 m = (methodinfo *) methodID;
2320 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2324 /* Accessing Static Fields ****************************************************/
2326 /* GetStaticFieldID ************************************************************
2328 Returns the field ID for a static field of a class. The field is
2329 specified by its name and signature. The GetStatic<type>Field and
2330 SetStatic<type>Field families of accessor functions use field IDs
2331 to retrieve static fields.
2333 *******************************************************************************/
2335 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2343 STATISTICS(jniinvokation());
2345 c = LLNI_classinfo_unwrap(clazz);
2347 uname = utf_new_char((char *) name);
2348 usig = utf_new_char((char *) sig);
2350 f = class_findfield(c, uname, usig);
2353 exceptions_throw_nosuchfielderror(c, uname);
2355 return (jfieldID) f;
2359 /* GetStatic<type>Field ********************************************************
2361 This family of accessor routines returns the value of a static
2364 *******************************************************************************/
2366 #define JNI_GET_STATIC_FIELD(name, type, field) \
2367 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2373 STATISTICS(jniinvokation()); \
2375 c = LLNI_classinfo_unwrap(clazz); \
2376 f = (fieldinfo *) fieldID; \
2378 if (!(c->state & CLASS_INITIALIZED)) \
2379 if (!initialize_class(c)) \
2382 return f->value->field; \
2385 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2386 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2387 JNI_GET_STATIC_FIELD(Char, jchar, i)
2388 JNI_GET_STATIC_FIELD(Short, jshort, i)
2389 JNI_GET_STATIC_FIELD(Int, jint, i)
2390 JNI_GET_STATIC_FIELD(Long, jlong, l)
2391 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2392 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2395 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2402 STATISTICS(jniinvokation());
2404 c = LLNI_classinfo_unwrap(clazz);
2405 f = (fieldinfo *) fieldID;
2407 if (!(c->state & CLASS_INITIALIZED))
2408 if (!initialize_class(c))
2411 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2413 return jni_NewLocalRef(env, (jobject) h);
2417 /* SetStatic<type>Field *******************************************************
2419 This family of accessor routines sets the value of a static field
2422 *******************************************************************************/
2424 #define JNI_SET_STATIC_FIELD(name, type, field) \
2425 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2432 STATISTICS(jniinvokation()); \
2434 c = LLNI_classinfo_unwrap(clazz); \
2435 f = (fieldinfo *) fieldID; \
2437 if (!(c->state & CLASS_INITIALIZED)) \
2438 if (!initialize_class(c)) \
2441 f->value->field = value; \
2444 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2445 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2446 JNI_SET_STATIC_FIELD(Char, jchar, i)
2447 JNI_SET_STATIC_FIELD(Short, jshort, i)
2448 JNI_SET_STATIC_FIELD(Int, jint, i)
2449 JNI_SET_STATIC_FIELD(Long, jlong, l)
2450 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2451 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2454 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2460 STATISTICS(jniinvokation());
2462 c = LLNI_classinfo_unwrap(clazz);
2463 f = (fieldinfo *) fieldID;
2465 if (!(c->state & CLASS_INITIALIZED))
2466 if (!initialize_class(c))
2469 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2473 /* String Operations **********************************************************/
2475 /* NewString *******************************************************************
2477 Create new java.lang.String object from an array of Unicode
2480 *******************************************************************************/
2482 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
2484 TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
2486 java_handle_chararray_t* a = builtin_newarray_char(len);
2492 for (jsize i = 0; i < len; i++)
2493 LLNI_array_direct(a, i) = buf[i];
2495 java_handle_t* h = builtin_new(class_java_lang_String);
2500 java_lang_String s(h, a, len, 0);
2502 return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
2506 static jchar emptyStringJ[]={0,0};
2508 /* GetStringLength *************************************************************
2510 Returns the length (the count of Unicode characters) of a Java
2513 *******************************************************************************/
2515 jsize jni_GetStringLength(JNIEnv *env, jstring str)
2517 TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
2519 java_lang_String s(str);
2520 jsize count = s.get_count();
2522 TRACEJNICALLSEXIT(("->%d)", count));
2528 /* GetStringChars **************************************************************
2530 Returns a pointer to the array of Unicode characters of the
2531 string. This pointer is valid until ReleaseStringChars() is called.
2533 *******************************************************************************/
2535 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2540 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2543 // FIXME This is really ugly.
2544 return emptyStringJ;
2546 java_lang_String s(str);
2548 java_handle_chararray_t* ca = s.get_value();
2549 int32_t count = s.get_count();
2550 int32_t offset = s.get_offset();
2555 /* allocate memory */
2557 stringbuffer = MNEW(u2, count + 1);
2561 for (i = 0; i < count; i++)
2562 stringbuffer[i] = LLNI_array_direct(ca, offset + i);
2564 /* terminate string */
2566 stringbuffer[i] = '\0';
2571 return (jchar*) stringbuffer;
2575 /* ReleaseStringChars **********************************************************
2577 Informs the VM that the native code no longer needs access to
2578 chars. The chars argument is a pointer obtained from string using
2581 *******************************************************************************/
2583 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2585 TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
2588 if (chars == emptyStringJ)
2591 java_lang_String s(str);
2592 int32_t count = s.get_count();
2594 MFREE(((jchar*) chars), jchar, count + 1);
2598 /* NewStringUTF ****************************************************************
2600 Constructs a new java.lang.String object from an array of UTF-8
2603 *******************************************************************************/
2605 jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
2607 TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2609 java_handle_t *h = javastring_safe_new_from_utf8(bytes);
2611 return (jstring) jni_NewLocalRef(env, (jobject) h);
2615 /****************** returns the utf8 length in bytes of a string *******************/
2617 jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
2619 TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
2621 java_lang_String s(string);
2622 java_handle_chararray_t* ca = s.get_value();
2623 int32_t count = s.get_count();
2625 // FIXME GC critical section!
2626 int32_t length = u2_utflength(ca->data, count);
2632 /* GetStringUTFChars ***********************************************************
2634 Returns a pointer to an array of UTF-8 characters of the
2635 string. This array is valid until it is released by
2636 ReleaseStringUTFChars().
2638 *******************************************************************************/
2640 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2645 STATISTICS(jniinvokation());
2653 u = javastring_toutf((java_handle_t *) string, false);
2662 /* ReleaseStringUTFChars *******************************************************
2664 Informs the VM that the native code no longer needs access to
2665 utf. The utf argument is a pointer derived from string using
2666 GetStringUTFChars().
2668 *******************************************************************************/
2670 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2672 STATISTICS(jniinvokation());
2674 /* XXX we don't release utf chars right now, perhaps that should be done
2675 later. Since there is always one reference the garbage collector will
2680 /* Array Operations ***********************************************************/
2682 /* GetArrayLength **************************************************************
2684 Returns the number of elements in the array.
2686 *******************************************************************************/
2688 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2693 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2695 a = (java_handle_t *) array;
2697 size = LLNI_array_size(a);
2703 /* NewObjectArray **************************************************************
2705 Constructs a new array holding objects in class elementClass. All
2706 elements are initially set to initialElement.
2708 *******************************************************************************/
2710 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2711 jclass elementClass, jobject initialElement)
2715 java_handle_objectarray_t *oa;
2718 STATISTICS(jniinvokation());
2720 c = LLNI_classinfo_unwrap(elementClass);
2721 o = (java_handle_t *) initialElement;
2724 exceptions_throw_negativearraysizeexception();
2728 oa = builtin_anewarray(length, c);
2733 /* set all elements to initialElement */
2735 for (i = 0; i < length; i++)
2736 array_objectarray_element_set(oa, i, o);
2738 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2742 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2745 java_handle_objectarray_t *oa;
2748 STATISTICS(jniinvokation());
2750 oa = (java_handle_objectarray_t *) array;
2752 if (index >= LLNI_array_size(oa)) {
2753 exceptions_throw_arrayindexoutofboundsexception();
2757 o = array_objectarray_element_get(oa, index);
2759 return jni_NewLocalRef(env, (jobject) o);
2763 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2764 jsize index, jobject val)
2766 java_handle_objectarray_t *oa;
2769 STATISTICS(jniinvokation());
2771 oa = (java_handle_objectarray_t *) array;
2772 o = (java_handle_t *) val;
2774 if (index >= LLNI_array_size(oa)) {
2775 exceptions_throw_arrayindexoutofboundsexception();
2779 /* check if the class of value is a subclass of the element class
2782 if (!builtin_canstore(oa, o))
2785 array_objectarray_element_set(oa, index, o);
2789 #define JNI_NEW_ARRAY(name, type, intern) \
2790 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2792 java_handle_##intern##array_t *a; \
2794 STATISTICS(jniinvokation()); \
2797 exceptions_throw_negativearraysizeexception(); \
2801 a = builtin_newarray_##intern(len); \
2803 return (type) jni_NewLocalRef(env, (jobject) a); \
2806 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2807 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2808 JNI_NEW_ARRAY(Char, jcharArray, char)
2809 JNI_NEW_ARRAY(Short, jshortArray, short)
2810 JNI_NEW_ARRAY(Int, jintArray, int)
2811 JNI_NEW_ARRAY(Long, jlongArray, long)
2812 JNI_NEW_ARRAY(Float, jfloatArray, float)
2813 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2816 /* Get<PrimitiveType>ArrayElements *********************************************
2818 A family of functions that returns the body of the primitive array.
2820 *******************************************************************************/
2822 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2823 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2826 java_handle_##intern##array_t *a; \
2828 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2830 a = (java_handle_##intern##array_t *) array; \
2833 *isCopy = JNI_FALSE; \
2835 return (type *) LLNI_array_data(a); \
2838 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2839 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2840 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2841 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2842 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2843 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2844 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2845 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2848 /* Release<PrimitiveType>ArrayElements *****************************************
2850 A family of functions that informs the VM that the native code no
2851 longer needs access to elems. The elems argument is a pointer
2852 derived from array using the corresponding
2853 Get<PrimitiveType>ArrayElements() function. If necessary, this
2854 function copies back all changes made to elems to the original
2857 *******************************************************************************/
2859 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2860 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2861 type *elems, jint mode) \
2863 java_handle_##intern##array_t *a; \
2865 STATISTICS(jniinvokation()); \
2867 a = (java_handle_##intern##array_t *) array; \
2869 if (elems != (type *) LLNI_array_data(a)) { \
2872 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2875 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2876 /* XXX TWISTI how should it be freed? */ \
2879 /* XXX TWISTI how should it be freed? */ \
2885 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2886 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2887 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2888 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2889 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2890 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2891 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2892 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2895 /* Get<PrimitiveType>ArrayRegion **********************************************
2897 A family of functions that copies a region of a primitive array
2900 *******************************************************************************/
2902 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2903 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2904 jsize start, jsize len, type *buf) \
2906 java_handle_##intern##array_t *a; \
2908 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2910 a = (java_handle_##intern##array_t *) array; \
2912 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2913 exceptions_throw_arrayindexoutofboundsexception(); \
2915 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
2918 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2919 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2920 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2921 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2922 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
2923 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
2924 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
2925 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
2928 /* Set<PrimitiveType>ArrayRegion **********************************************
2930 A family of functions that copies back a region of a primitive
2931 array from a buffer.
2933 *******************************************************************************/
2935 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
2936 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
2937 jsize start, jsize len, const type *buf) \
2939 java_handle_##intern##array_t *a; \
2941 STATISTICS(jniinvokation()); \
2943 a = (java_handle_##intern##array_t *) array; \
2945 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2946 exceptions_throw_arrayindexoutofboundsexception(); \
2948 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
2951 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2952 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
2953 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
2954 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
2955 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
2956 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
2957 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
2958 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
2961 /* Registering Native Methods *************************************************/
2963 /* RegisterNatives *************************************************************
2965 Registers native methods with the class specified by the clazz
2966 argument. The methods parameter specifies an array of
2967 JNINativeMethod structures that contain the names, signatures, and
2968 function pointers of the native methods. The nMethods parameter
2969 specifies the number of native methods in the array.
2971 *******************************************************************************/
2973 jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
2975 TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
2977 classinfo* c = LLNI_classinfo_unwrap(clazz);
2979 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
2980 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
2983 NativeMethods& nm = VM::get_current()->get_nativemethods();
2984 nm.register_methods(c->name, methods, nMethods);
2990 /* UnregisterNatives ***********************************************************
2992 Unregisters native methods of a class. The class goes back to the
2993 state before it was linked or registered with its native method
2996 This function should not be used in normal native code. Instead, it
2997 provides special programs a way to reload and relink native
3000 *******************************************************************************/
3002 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3004 STATISTICS(jniinvokation());
3006 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3008 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3014 /* Monitor Operations *********************************************************/
3016 /* MonitorEnter ****************************************************************
3018 Enters the monitor associated with the underlying Java object
3021 *******************************************************************************/
3023 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3025 STATISTICS(jniinvokation());
3028 exceptions_throw_nullpointerexception();
3032 LOCK_MONITOR_ENTER(obj);
3038 /* MonitorExit *****************************************************************
3040 The current thread must be the owner of the monitor associated with
3041 the underlying Java object referred to by obj. The thread
3042 decrements the counter indicating the number of times it has
3043 entered this monitor. If the value of the counter becomes zero, the
3044 current thread releases the monitor.
3046 *******************************************************************************/
3048 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3050 STATISTICS(jniinvokation());
3053 exceptions_throw_nullpointerexception();
3057 LOCK_MONITOR_EXIT(obj);
3063 /* JavaVM Interface ***********************************************************/
3065 /* GetJavaVM *******************************************************************
3067 Returns the Java VM interface (used in the Invocation API)
3068 associated with the current thread. The result is placed at the
3069 location pointed to by the second argument, vm.
3071 *******************************************************************************/
3073 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3075 STATISTICS(jniinvokation());
3077 *javavm = VM::get_current()->get_javavm();
3083 /* GetStringRegion *************************************************************
3085 Copies len number of Unicode characters beginning at offset start
3086 to the given buffer buf.
3088 Throws StringIndexOutOfBoundsException on index overflow.
3090 *******************************************************************************/
3092 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3094 java_lang_String s(str);
3095 java_handle_chararray_t* ca = s.get_value();
3096 int32_t count = s.get_count();
3098 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3099 exceptions_throw_stringindexoutofboundsexception();
3103 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3107 /* GetStringUTFRegion **********************************************************
3109 Translates len number of Unicode characters beginning at offset
3110 start into UTF-8 format and place the result in the given buffer
3113 Throws StringIndexOutOfBoundsException on index overflow.
3115 *******************************************************************************/
3117 void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3119 TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3121 java_lang_String s(str);
3122 java_handle_chararray_t* ca = s.get_value();
3123 int32_t count = s.get_count();
3124 int32_t offset = s.get_offset();
3126 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3127 exceptions_throw_stringindexoutofboundsexception();
3133 for (i = 0; i < len; i++)
3134 buf[i] = LLNI_array_direct(ca, offset + start + i);
3140 /* GetPrimitiveArrayCritical ***************************************************
3142 Obtain a direct pointer to array elements.
3144 ATTENTION: Critical section keeps open when this function returns!
3145 See ReleasePrimitiveArrayCritical.
3147 *******************************************************************************/
3149 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3153 arraydescriptor* ad;
3156 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3158 if (isCopy != NULL) {
3159 *isCopy = JNI_FALSE;
3162 LLNI_CRITICAL_START;
3164 h = (java_handle_t*) array;
3165 a = (java_array_t*) LLNI_UNWRAP(h);
3166 ad = a->objheader.vftbl->arraydesc;
3172 data = (void*) (((intptr_t) a) + ad->dataoffset);
3178 /* ReleasePrimitiveArrayCritical ***********************************************
3180 No specific documentation.
3182 ATTENTION: This function closes the critical section opened in
3183 GetPrimitiveArrayCritical!
3185 *******************************************************************************/
3187 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3189 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3195 /* GetStringCritical ***********************************************************
3197 The semantics of these two functions are similar to the existing
3198 Get/ReleaseStringChars functions.
3200 *******************************************************************************/
3202 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3205 STATISTICS(jniinvokation());
3207 return jni_GetStringChars(env, string, isCopy);
3211 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3212 const jchar *cstring)
3214 STATISTICS(jniinvokation());
3216 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3220 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3222 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3228 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3230 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3234 /* NewGlobalRef ****************************************************************
3236 Creates a new global reference to the object referred to by the obj
3239 *******************************************************************************/
3241 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3243 hashtable_global_ref_entry *gre;
3244 u4 key; /* hashkey */
3245 u4 slot; /* slot in hashtable */
3248 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3250 o = (java_handle_t *) obj;
3252 hashtable_global_ref->mutex->lock();
3254 LLNI_CRITICAL_START;
3256 /* normally addresses are aligned to 4, 8 or 16 bytes */
3258 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3259 slot = key & (hashtable_global_ref->size - 1);
3260 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3262 /* search external hash chain for the entry */
3265 if (gre->o == LLNI_DIRECT(o)) {
3266 /* global object found, increment the reference */
3273 gre = gre->hashlink; /* next element in external chain */
3278 /* global ref not found, create a new one */
3281 gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3283 #if defined(ENABLE_GC_CACAO)
3284 /* register global ref with the GC */
3286 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3289 LLNI_CRITICAL_START;
3291 gre->o = LLNI_DIRECT(o);
3296 /* insert entry into hashtable */
3298 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3300 hashtable_global_ref->ptr[slot] = gre;
3302 /* update number of hashtable-entries */
3304 hashtable_global_ref->entries++;
3307 hashtable_global_ref->mutex->unlock();
3309 #if defined(ENABLE_HANDLES)
3317 /* DeleteGlobalRef *************************************************************
3319 Deletes the global reference pointed to by globalRef.
3321 *******************************************************************************/
3323 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3325 hashtable_global_ref_entry *gre;
3326 hashtable_global_ref_entry *prevgre;
3327 u4 key; /* hashkey */
3328 u4 slot; /* slot in hashtable */
3331 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3333 o = (java_handle_t *) globalRef;
3335 hashtable_global_ref->mutex->lock();
3337 LLNI_CRITICAL_START;
3339 /* normally addresses are aligned to 4, 8 or 16 bytes */
3341 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3342 slot = key & (hashtable_global_ref->size - 1);
3343 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3345 /* initialize prevgre */
3349 /* search external hash chain for the entry */
3352 if (gre->o == LLNI_DIRECT(o)) {
3353 /* global object found, decrement the reference count */
3357 /* if reference count is 0, remove the entry */
3359 if (gre->refs == 0) {
3360 /* special handling if it's the first in the chain */
3362 if (prevgre == NULL)
3363 hashtable_global_ref->ptr[slot] = gre->hashlink;
3365 prevgre->hashlink = gre->hashlink;
3367 #if defined(ENABLE_GC_CACAO)
3368 /* unregister global ref with the GC */
3370 gc_reference_unregister(&(gre->o));
3378 hashtable_global_ref->mutex->unlock();
3383 prevgre = gre; /* save current pointer for removal */
3384 gre = gre->hashlink; /* next element in external chain */
3387 log_println("jni_DeleteGlobalRef: Global reference not found.");
3391 hashtable_global_ref->mutex->unlock();
3395 /* ExceptionCheck **************************************************************
3397 Returns JNI_TRUE when there is a pending exception; otherwise,
3400 *******************************************************************************/
3402 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3406 STATISTICS(jniinvokation());
3408 o = exceptions_get_exception();
3410 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3414 /* New JNI 1.4 functions ******************************************************/
3416 /* NewDirectByteBuffer *********************************************************
3418 Allocates and returns a direct java.nio.ByteBuffer referring to the
3419 block of memory starting at the memory address address and
3420 extending capacity bytes.
3422 *******************************************************************************/
3424 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3426 #if defined(ENABLE_JAVASE)
3427 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3428 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3430 // Allocate a gnu.classpath.Pointer{32,64} object.
3432 # if SIZEOF_VOID_P == 8
3433 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
3435 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
3441 gnu_classpath_Pointer p(h, address);
3443 // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
3445 java_handle_t* nbuf =
3446 (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3447 (jmethodID) dbbirw_init, NULL, p.get_handle(),
3448 (jint) capacity, (jint) capacity, (jint) 0);
3450 // Add a local reference and return the value.
3452 TRACEJNICALLSEXIT(("->%p", nbuf));
3454 return jni_NewLocalRef(env, (jobject) nbuf);
3456 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3462 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3464 /* Be paranoid about address sign-extension. */
3466 addr = (int64_t) ((uintptr_t) address);
3467 cap = (int32_t) capacity;
3469 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3470 (jmethodID) dbb_init, addr, cap);
3472 /* Add local reference and return the value. */
3474 TRACEJNICALLSEXIT(("->%p", o));
3476 return jni_NewLocalRef(env, o);
3479 # error unknown classpath configuration
3483 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3485 /* keep compiler happy */
3492 /* GetDirectBufferAddress ******************************************************
3494 Fetches and returns the starting address of the memory region
3495 referenced by the given direct java.nio.Buffer.
3497 *******************************************************************************/
3499 void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3501 #if defined(ENABLE_JAVASE)
3502 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3504 TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3506 /* Prevent compiler warning. */
3508 java_handle_t* h = (java_handle_t *) buf;
3510 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3513 java_nio_DirectByteBufferImpl dbb(buf);
3514 java_handle_t* address = dbb.get_address();
3516 if (address == NULL) {
3517 TRACEJNICALLSEXIT(("->%p", NULL));
3521 gnu_classpath_Pointer p(address);
3522 void* data = p.get_data();
3524 TRACEJNICALLSEXIT(("->%p", data));
3528 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3530 TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3532 java_nio_Buffer jnb(buf);
3534 if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3537 void* address = jnb.get_address();
3542 # error unknown classpath configuration
3547 vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
3549 // Keep compiler happy.
3556 /* GetDirectBufferCapacity *****************************************************
3558 Fetches and returns the capacity in bytes of the memory region
3559 referenced by the given direct java.nio.Buffer.
3561 *******************************************************************************/
3563 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3565 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3566 TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3568 java_handle_t* h = (java_handle_t *) buf;
3570 if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
3573 java_nio_Buffer b(h);
3574 jlong capacity = b.get_cap();
3578 vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
3580 // Keep compiler happy.
3587 /* GetObjectRefType ************************************************************
3589 Returns the type of the object referred to by the obj argument. The
3590 argument obj can either be a local, global or weak global
3593 *******************************************************************************/
3595 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3597 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3599 return (jobjectRefType) NULL;
3603 /* DestroyJavaVM ***************************************************************
3605 Unloads a Java VM and reclaims its resources. Only the main thread
3606 can unload the VM. The system waits until the main thread is only
3607 remaining user thread before it destroys the VM.
3609 *******************************************************************************/
3611 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3615 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3617 if (VM::get_current()->is_created() == false)
3620 status = vm_destroy(javavm);
3626 /* AttachCurrentThread *********************************************************
3628 Attaches the current thread to a Java VM. Returns a JNI interface
3629 pointer in the JNIEnv argument.
3631 Trying to attach a thread that is already attached is a no-op.
3633 A native thread cannot be attached simultaneously to two Java VMs.
3635 When a thread is attached to the VM, the context class loader is
3636 the bootstrap loader.
3638 *******************************************************************************/
3640 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3642 #if defined(ENABLE_THREADS)
3643 JavaVMAttachArgs *vm_aargs;
3646 /* If the current thread has already been attached, this operation
3649 result = thread_current_is_attached();
3651 if (result == true) {
3652 *p_env = VM::get_current()->get_jnienv();
3656 vm_aargs = (JavaVMAttachArgs *) thr_args;
3658 if (vm_aargs != NULL) {
3659 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3660 (vm_aargs->version != JNI_VERSION_1_4))
3661 return JNI_EVERSION;
3664 if (!thread_attach_current_external_thread(vm_aargs, false))
3667 if (!localref_table_init())
3671 *p_env = VM::get_current()->get_jnienv();
3677 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3681 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3683 if (VM::get_current()->is_created() == false)
3686 result = jni_attach_current_thread(p_env, thr_args, false);
3692 /* DetachCurrentThread *********************************************************
3694 Detaches the current thread from a Java VM. All Java monitors held
3695 by this thread are released. All Java threads waiting for this
3696 thread to die are notified.
3698 In JDK 1.1, the main thread cannot be detached from the VM. It must
3699 call DestroyJavaVM to unload the entire VM.
3701 In the JDK, the main thread can be detached from the VM.
3703 The main thread, which is the thread that created the Java VM,
3704 cannot be detached from the VM. Instead, the main thread must call
3705 JNI_DestroyJavaVM() to unload the entire VM.
3707 *******************************************************************************/
3709 jint jni_DetachCurrentThread(JavaVM *vm)
3711 #if defined(ENABLE_THREADS)
3714 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3716 /* If the current thread has already been detached, this operation
3719 result = thread_current_is_attached();
3721 if (result == false)
3724 /* We need to pop all frames before we can destroy the table. */
3726 localref_frame_pop_all();
3728 if (!localref_table_destroy())
3731 if (!thread_detach_current_external_thread())
3739 /* GetEnv **********************************************************************
3741 If the current thread is not attached to the VM, sets *env to NULL,
3742 and returns JNI_EDETACHED. If the specified version is not
3743 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3744 sets *env to the appropriate interface, and returns JNI_OK.
3746 *******************************************************************************/
3748 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3750 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3752 if (VM::get_current()->is_created() == false) {
3754 return JNI_EDETACHED;
3757 #if defined(ENABLE_THREADS)
3758 if (thread_get_current() == NULL) {
3761 return JNI_EDETACHED;
3765 /* Check the JNI version. */
3767 if (jni_version_check(version) == true) {
3768 *env = VM::get_current()->get_jnienv();
3772 #if defined(ENABLE_JVMTI)
3773 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3774 == JVMTI_VERSION_INTERFACE_JVMTI) {
3776 *env = (void *) jvmti_new_environment();
3785 return JNI_EVERSION;
3789 /* AttachCurrentThreadAsDaemon *************************************************
3791 Same semantics as AttachCurrentThread, but the newly-created
3792 java.lang.Thread instance is a daemon.
3794 If the thread has already been attached via either
3795 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3796 simply sets the value pointed to by penv to the JNIEnv of the
3797 current thread. In this case neither AttachCurrentThread nor this
3798 routine have any effect on the daemon status of the thread.
3800 *******************************************************************************/
3802 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3806 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
3808 if (VM::get_current()->is_created() == false)
3811 result = jni_attach_current_thread(penv, args, true);
3817 /* JNI invocation table *******************************************************/
3819 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3824 _Jv_JNI_DestroyJavaVM,
3825 jni_AttachCurrentThread,
3826 jni_DetachCurrentThread,
3828 jni_AttachCurrentThreadAsDaemon
3832 /* JNI function table *********************************************************/
3834 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3843 jni_FromReflectedMethod,
3844 jni_FromReflectedField,
3845 jni_ToReflectedMethod,
3847 _Jv_JNI_IsAssignableFrom,
3848 _Jv_JNI_ToReflectedField,
3852 _Jv_JNI_ExceptionOccurred,
3853 jni_ExceptionDescribe,
3860 jni_DeleteGlobalRef,
3862 _Jv_JNI_IsSameObject,
3864 jni_EnsureLocalCapacity,
3866 _Jv_JNI_AllocObject,
3872 _Jv_JNI_IsInstanceOf,
3874 _Jv_JNI_GetMethodID,
3876 _Jv_JNI_CallObjectMethod,
3877 _Jv_JNI_CallObjectMethodV,
3878 _Jv_JNI_CallObjectMethodA,
3879 _Jv_JNI_CallBooleanMethod,
3880 _Jv_JNI_CallBooleanMethodV,
3881 _Jv_JNI_CallBooleanMethodA,
3882 _Jv_JNI_CallByteMethod,
3883 _Jv_JNI_CallByteMethodV,
3884 _Jv_JNI_CallByteMethodA,
3885 _Jv_JNI_CallCharMethod,
3886 _Jv_JNI_CallCharMethodV,
3887 _Jv_JNI_CallCharMethodA,
3888 _Jv_JNI_CallShortMethod,
3889 _Jv_JNI_CallShortMethodV,
3890 _Jv_JNI_CallShortMethodA,
3891 _Jv_JNI_CallIntMethod,
3892 _Jv_JNI_CallIntMethodV,
3893 _Jv_JNI_CallIntMethodA,
3894 _Jv_JNI_CallLongMethod,
3895 _Jv_JNI_CallLongMethodV,
3896 _Jv_JNI_CallLongMethodA,
3897 _Jv_JNI_CallFloatMethod,
3898 _Jv_JNI_CallFloatMethodV,
3899 _Jv_JNI_CallFloatMethodA,
3900 _Jv_JNI_CallDoubleMethod,
3901 _Jv_JNI_CallDoubleMethodV,
3902 _Jv_JNI_CallDoubleMethodA,
3903 _Jv_JNI_CallVoidMethod,
3904 _Jv_JNI_CallVoidMethodV,
3905 _Jv_JNI_CallVoidMethodA,
3907 _Jv_JNI_CallNonvirtualObjectMethod,
3908 _Jv_JNI_CallNonvirtualObjectMethodV,
3909 _Jv_JNI_CallNonvirtualObjectMethodA,
3910 _Jv_JNI_CallNonvirtualBooleanMethod,
3911 _Jv_JNI_CallNonvirtualBooleanMethodV,
3912 _Jv_JNI_CallNonvirtualBooleanMethodA,
3913 _Jv_JNI_CallNonvirtualByteMethod,
3914 _Jv_JNI_CallNonvirtualByteMethodV,
3915 _Jv_JNI_CallNonvirtualByteMethodA,
3916 _Jv_JNI_CallNonvirtualCharMethod,
3917 _Jv_JNI_CallNonvirtualCharMethodV,
3918 _Jv_JNI_CallNonvirtualCharMethodA,
3919 _Jv_JNI_CallNonvirtualShortMethod,
3920 _Jv_JNI_CallNonvirtualShortMethodV,
3921 _Jv_JNI_CallNonvirtualShortMethodA,
3922 _Jv_JNI_CallNonvirtualIntMethod,
3923 _Jv_JNI_CallNonvirtualIntMethodV,
3924 _Jv_JNI_CallNonvirtualIntMethodA,
3925 _Jv_JNI_CallNonvirtualLongMethod,
3926 _Jv_JNI_CallNonvirtualLongMethodV,
3927 _Jv_JNI_CallNonvirtualLongMethodA,
3928 _Jv_JNI_CallNonvirtualFloatMethod,
3929 _Jv_JNI_CallNonvirtualFloatMethodV,
3930 _Jv_JNI_CallNonvirtualFloatMethodA,
3931 _Jv_JNI_CallNonvirtualDoubleMethod,
3932 _Jv_JNI_CallNonvirtualDoubleMethodV,
3933 _Jv_JNI_CallNonvirtualDoubleMethodA,
3934 _Jv_JNI_CallNonvirtualVoidMethod,
3935 _Jv_JNI_CallNonvirtualVoidMethodV,
3936 _Jv_JNI_CallNonvirtualVoidMethodA,
3940 _Jv_JNI_GetObjectField,
3941 _Jv_JNI_GetBooleanField,
3942 _Jv_JNI_GetByteField,
3943 _Jv_JNI_GetCharField,
3944 _Jv_JNI_GetShortField,
3945 _Jv_JNI_GetIntField,
3946 _Jv_JNI_GetLongField,
3947 _Jv_JNI_GetFloatField,
3948 _Jv_JNI_GetDoubleField,
3949 _Jv_JNI_SetObjectField,
3950 _Jv_JNI_SetBooleanField,
3951 _Jv_JNI_SetByteField,
3952 _Jv_JNI_SetCharField,
3953 _Jv_JNI_SetShortField,
3954 _Jv_JNI_SetIntField,
3955 _Jv_JNI_SetLongField,
3956 _Jv_JNI_SetFloatField,
3957 _Jv_JNI_SetDoubleField,
3959 _Jv_JNI_GetStaticMethodID,
3961 _Jv_JNI_CallStaticObjectMethod,
3962 _Jv_JNI_CallStaticObjectMethodV,
3963 _Jv_JNI_CallStaticObjectMethodA,
3964 _Jv_JNI_CallStaticBooleanMethod,
3965 _Jv_JNI_CallStaticBooleanMethodV,
3966 _Jv_JNI_CallStaticBooleanMethodA,
3967 _Jv_JNI_CallStaticByteMethod,
3968 _Jv_JNI_CallStaticByteMethodV,
3969 _Jv_JNI_CallStaticByteMethodA,
3970 _Jv_JNI_CallStaticCharMethod,
3971 _Jv_JNI_CallStaticCharMethodV,
3972 _Jv_JNI_CallStaticCharMethodA,
3973 _Jv_JNI_CallStaticShortMethod,
3974 _Jv_JNI_CallStaticShortMethodV,
3975 _Jv_JNI_CallStaticShortMethodA,
3976 _Jv_JNI_CallStaticIntMethod,
3977 _Jv_JNI_CallStaticIntMethodV,
3978 _Jv_JNI_CallStaticIntMethodA,
3979 _Jv_JNI_CallStaticLongMethod,
3980 _Jv_JNI_CallStaticLongMethodV,
3981 _Jv_JNI_CallStaticLongMethodA,
3982 _Jv_JNI_CallStaticFloatMethod,
3983 _Jv_JNI_CallStaticFloatMethodV,
3984 _Jv_JNI_CallStaticFloatMethodA,
3985 _Jv_JNI_CallStaticDoubleMethod,
3986 _Jv_JNI_CallStaticDoubleMethodV,
3987 _Jv_JNI_CallStaticDoubleMethodA,
3988 _Jv_JNI_CallStaticVoidMethod,
3989 _Jv_JNI_CallStaticVoidMethodV,
3990 _Jv_JNI_CallStaticVoidMethodA,
3992 _Jv_JNI_GetStaticFieldID,
3994 _Jv_JNI_GetStaticObjectField,
3995 _Jv_JNI_GetStaticBooleanField,
3996 _Jv_JNI_GetStaticByteField,
3997 _Jv_JNI_GetStaticCharField,
3998 _Jv_JNI_GetStaticShortField,
3999 _Jv_JNI_GetStaticIntField,
4000 _Jv_JNI_GetStaticLongField,
4001 _Jv_JNI_GetStaticFloatField,
4002 _Jv_JNI_GetStaticDoubleField,
4003 _Jv_JNI_SetStaticObjectField,
4004 _Jv_JNI_SetStaticBooleanField,
4005 _Jv_JNI_SetStaticByteField,
4006 _Jv_JNI_SetStaticCharField,
4007 _Jv_JNI_SetStaticShortField,
4008 _Jv_JNI_SetStaticIntField,
4009 _Jv_JNI_SetStaticLongField,
4010 _Jv_JNI_SetStaticFloatField,
4011 _Jv_JNI_SetStaticDoubleField,
4014 jni_GetStringLength,
4016 _Jv_JNI_ReleaseStringChars,
4019 jni_GetStringUTFLength,
4020 _Jv_JNI_GetStringUTFChars,
4021 _Jv_JNI_ReleaseStringUTFChars,
4023 _Jv_JNI_GetArrayLength,
4025 _Jv_JNI_NewObjectArray,
4026 _Jv_JNI_GetObjectArrayElement,
4027 _Jv_JNI_SetObjectArrayElement,
4029 _Jv_JNI_NewBooleanArray,
4030 _Jv_JNI_NewByteArray,
4031 _Jv_JNI_NewCharArray,
4032 _Jv_JNI_NewShortArray,
4033 _Jv_JNI_NewIntArray,
4034 _Jv_JNI_NewLongArray,
4035 _Jv_JNI_NewFloatArray,
4036 _Jv_JNI_NewDoubleArray,
4038 _Jv_JNI_GetBooleanArrayElements,
4039 _Jv_JNI_GetByteArrayElements,
4040 _Jv_JNI_GetCharArrayElements,
4041 _Jv_JNI_GetShortArrayElements,
4042 _Jv_JNI_GetIntArrayElements,
4043 _Jv_JNI_GetLongArrayElements,
4044 _Jv_JNI_GetFloatArrayElements,
4045 _Jv_JNI_GetDoubleArrayElements,
4047 _Jv_JNI_ReleaseBooleanArrayElements,
4048 _Jv_JNI_ReleaseByteArrayElements,
4049 _Jv_JNI_ReleaseCharArrayElements,
4050 _Jv_JNI_ReleaseShortArrayElements,
4051 _Jv_JNI_ReleaseIntArrayElements,
4052 _Jv_JNI_ReleaseLongArrayElements,
4053 _Jv_JNI_ReleaseFloatArrayElements,
4054 _Jv_JNI_ReleaseDoubleArrayElements,
4056 _Jv_JNI_GetBooleanArrayRegion,
4057 _Jv_JNI_GetByteArrayRegion,
4058 _Jv_JNI_GetCharArrayRegion,
4059 _Jv_JNI_GetShortArrayRegion,
4060 _Jv_JNI_GetIntArrayRegion,
4061 _Jv_JNI_GetLongArrayRegion,
4062 _Jv_JNI_GetFloatArrayRegion,
4063 _Jv_JNI_GetDoubleArrayRegion,
4064 _Jv_JNI_SetBooleanArrayRegion,
4065 _Jv_JNI_SetByteArrayRegion,
4066 _Jv_JNI_SetCharArrayRegion,
4067 _Jv_JNI_SetShortArrayRegion,
4068 _Jv_JNI_SetIntArrayRegion,
4069 _Jv_JNI_SetLongArrayRegion,
4070 _Jv_JNI_SetFloatArrayRegion,
4071 _Jv_JNI_SetDoubleArrayRegion,
4073 jni_RegisterNatives,
4074 _Jv_JNI_UnregisterNatives,
4076 _Jv_JNI_MonitorEnter,
4077 _Jv_JNI_MonitorExit,
4081 /* New JNI 1.2 functions. */
4083 jni_GetStringRegion,
4084 jni_GetStringUTFRegion,
4086 jni_GetPrimitiveArrayCritical,
4087 jni_ReleasePrimitiveArrayCritical,
4089 _Jv_JNI_GetStringCritical,
4090 _Jv_JNI_ReleaseStringCritical,
4092 _Jv_JNI_NewWeakGlobalRef,
4093 _Jv_JNI_DeleteWeakGlobalRef,
4095 _Jv_JNI_ExceptionCheck,
4097 /* New JNI 1.4 functions. */
4099 jni_NewDirectByteBuffer,
4100 jni_GetDirectBufferAddress,
4101 jni_GetDirectBufferCapacity,
4103 /* New JNI 1.6 functions. */
4105 jni_GetObjectRefType
4109 /* Invocation API Functions ***************************************************/
4111 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4113 Returns a default configuration for the Java VM.
4115 *******************************************************************************/
4117 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4119 JavaVMInitArgs *_vm_args;
4121 _vm_args = (JavaVMInitArgs *) vm_args;
4123 /* GNU classpath currently supports JNI 1.2 */
4125 switch (_vm_args->version) {
4126 case JNI_VERSION_1_1:
4127 _vm_args->version = JNI_VERSION_1_1;
4130 case JNI_VERSION_1_2:
4131 case JNI_VERSION_1_4:
4132 _vm_args->ignoreUnrecognized = JNI_FALSE;
4133 _vm_args->options = NULL;
4134 _vm_args->nOptions = 0;
4137 case JNI_VERSION_CACAO:
4138 // We reveal ourselves by accepting this version number,
4139 // this actually means we are using the supported JNI version.
4140 _vm_args->version = JNI_VERSION_SUPPORTED;
4151 /* JNI_GetCreatedJavaVMs *******************************************************
4153 Returns all Java VMs that have been created. Pointers to VMs are written in
4154 the buffer vmBuf in the order they are created. At most bufLen number of
4155 entries will be written. The total number of created VMs is returned in
4158 *******************************************************************************/
4160 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4162 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4167 // We currently only support 1 VM running.
4169 vmBuf[0] = VM::get_current()->get_javavm();
4176 /* JNI_CreateJavaVM ************************************************************
4178 Loads and initializes a Java VM. The current thread becomes the main thread.
4179 Sets the env argument to the JNI interface pointer of the main thread.
4181 *******************************************************************************/
4183 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4185 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4187 /* actually create the JVM */
4189 if (!VM_create(p_vm, p_env, vm_args))
4199 * These are local overrides for various environment variables in Emacs.
4200 * Please do not remove this and leave it at the end of the file, where
4201 * Emacs will automagically detect them.
4202 * ---------------------------------------------------------------------
4205 * indent-tabs-mode: t
4209 * vim:noexpandtab:sw=4:ts=4: