1 /* src/native/jni.cpp - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2011
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 classloader_t *cl = cc->classloader;
886 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
887 /* See jni_FindClass in Hotspot's src/share/vm/prims/jni.cpp */
888 if (!cl && cc->name == utf_java_lang_ClassLoader_NativeLibrary)
890 methodinfo *m = class_resolveclassmethod(
892 utf_new_char("getFromClass"),
893 utf_new_char("()Ljava/lang/Class;"),
899 h = vm_call_method(m, NULL);
901 if (m && exceptions_get_exception() == NULL)
902 cl = ((classinfo *) LLNI_UNWRAP(h))->classloader;
907 c = load_class_from_classloader(u, cl);
911 resolve_handle_pending_exception(true);
918 h = LLNI_classinfo_wrap(c);
920 return (jclass) jni_NewLocalRef(env, (jobject) h);
922 #elif defined(ENABLE_JAVAME_CLDC1_1)
927 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
929 u = utf_new_char_classname((char *) name);
930 c = load_class_bootstrap(u);
933 resolve_handle_pending_exception(true);
940 return (jclass) jni_NewLocalRef(env, (jobject) c);
943 vm_abort("jni_FindClass: not implemented in this configuration");
945 /* keep compiler happy */
952 /* GetSuperclass ***************************************************************
954 If clazz represents any class other than the class Object, then
955 this function returns the object that represents the superclass of
956 the class specified by clazz.
958 *******************************************************************************/
960 jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
965 TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
967 c = LLNI_classinfo_unwrap(sub);
972 super = class_get_superclass(c);
974 java_handle_t* h = LLNI_classinfo_wrap(super);
976 return (jclass) jni_NewLocalRef(env, (jobject) h);
980 /* IsAssignableFrom ************************************************************
982 Determines whether an object of sub can be safely cast to sup.
984 *******************************************************************************/
986 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
991 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
993 to = (classinfo *) sup;
994 from = (classinfo *) sub;
996 return class_is_assignable_from(to, from);
1000 /* Throw ***********************************************************************
1002 Causes a java.lang.Throwable object to be thrown.
1004 *******************************************************************************/
1006 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1010 STATISTICS(jniinvokation());
1012 o = (java_handle_t *) obj;
1014 exceptions_set_exception(o);
1020 /* ThrowNew ********************************************************************
1022 Constructs an exception object from the specified class with the
1023 message specified by message and causes that exception to be
1026 *******************************************************************************/
1028 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1034 STATISTICS(jniinvokation());
1036 c = LLNI_classinfo_unwrap(clazz);
1039 s = javastring_new_from_utf_string(msg);
1041 /* instantiate exception object */
1043 o = native_new_and_init_string(c, s);
1048 exceptions_set_exception(o);
1054 /* ExceptionOccurred ***********************************************************
1056 Determines if an exception is being thrown. The exception stays
1057 being thrown until either the native code calls ExceptionClear(),
1058 or the Java code handles the exception.
1060 *******************************************************************************/
1062 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1066 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1068 o = exceptions_get_exception();
1070 return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1074 /* ExceptionDescribe ***********************************************************
1076 Prints an exception and a backtrace of the stack to a system
1077 error-reporting channel, such as stderr. This is a convenience
1078 routine provided for debugging.
1080 *******************************************************************************/
1082 void jni_ExceptionDescribe(JNIEnv *env)
1084 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1086 exceptions_print_stacktrace();
1090 /* ExceptionClear **************************************************************
1092 Clears any exception that is currently being thrown. If no
1093 exception is currently being thrown, this routine has no effect.
1095 *******************************************************************************/
1097 void jni_ExceptionClear(JNIEnv *env)
1099 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1101 exceptions_clear_exception();
1105 /* FatalError ******************************************************************
1107 Raises a fatal error and does not expect the VM to recover. This
1108 function does not return.
1110 *******************************************************************************/
1112 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1114 STATISTICS(jniinvokation());
1116 /* this seems to be the best way */
1118 vm_abort("JNI Fatal error: %s", msg);
1122 /* PushLocalFrame **************************************************************
1124 Creates a new local reference frame, in which at least a given
1125 number of local references can be created.
1127 *******************************************************************************/
1129 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1131 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1136 /* add new local reference frame to current table */
1138 if (!localref_frame_push(capacity))
1145 /* PopLocalFrame ***************************************************************
1147 Pops off the current local reference frame, frees all the local
1148 references, and returns a local reference in the previous local
1149 reference frame for the given result object.
1151 *******************************************************************************/
1153 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1155 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1157 /* release all current local frames */
1159 localref_frame_pop_all();
1161 /* add local reference and return the value */
1163 return jni_NewLocalRef(env, result);
1167 /* DeleteLocalRef **************************************************************
1169 Deletes the local reference pointed to by localRef.
1171 *******************************************************************************/
1173 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1177 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1179 o = (java_handle_t *) localRef;
1184 /* delete the reference */
1190 /* IsSameObject ****************************************************************
1192 Tests whether two references refer to the same Java object.
1194 *******************************************************************************/
1196 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1202 STATISTICS(jniinvokation());
1204 o1 = (java_handle_t *) ref1;
1205 o2 = (java_handle_t *) ref2;
1207 LLNI_CRITICAL_START;
1209 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1220 /* NewLocalRef *****************************************************************
1222 Creates a new local reference that refers to the same object as ref.
1224 *******************************************************************************/
1226 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1229 java_handle_t *localref;
1231 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1233 o = (java_handle_t *) ref;
1238 /* insert the reference */
1240 localref = localref_add(LLNI_DIRECT(o));
1242 return (jobject) localref;
1246 /* EnsureLocalCapacity *********************************************************
1248 Ensures that at least a given number of local references can be
1249 created in the current thread
1251 *******************************************************************************/
1253 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1255 localref_table *lrt;
1257 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1259 /* get local reference table (thread specific) */
1261 lrt = LOCALREFTABLE;
1263 /* check if capacity elements are available in the local references table */
1265 if ((lrt->used + capacity) > lrt->capacity)
1266 return jni_PushLocalFrame(env, capacity);
1272 /* AllocObject *****************************************************************
1274 Allocates a new Java object without invoking any of the
1275 constructors for the object. Returns a reference to the object.
1277 *******************************************************************************/
1279 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1284 STATISTICS(jniinvokation());
1286 c = LLNI_classinfo_unwrap(clazz);
1288 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1289 exceptions_throw_instantiationexception(c);
1295 return jni_NewLocalRef(env, (jobject) o);
1299 /* NewObject *******************************************************************
1301 Programmers place all arguments that are to be passed to the
1302 constructor immediately following the methodID
1303 argument. NewObject() accepts these arguments and passes them to
1304 the Java method that the programmer wishes to invoke.
1306 *******************************************************************************/
1308 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1315 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1317 c = LLNI_classinfo_unwrap(clazz);
1318 m = (methodinfo *) methodID;
1327 /* call constructor */
1329 va_start(ap, methodID);
1330 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1333 TRACEJNICALLSEXIT(("->%p", o));
1335 return jni_NewLocalRef(env, (jobject) o);
1339 /* NewObjectV ******************************************************************
1341 Programmers place all arguments that are to be passed to the
1342 constructor in an args argument of type va_list that immediately
1343 follows the methodID argument. NewObjectV() accepts these
1344 arguments, and, in turn, passes them to the Java method that the
1345 programmer wishes to invoke.
1347 *******************************************************************************/
1349 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1356 STATISTICS(jniinvokation());
1358 c = LLNI_classinfo_unwrap(clazz);
1359 m = (methodinfo *) methodID;
1368 /* call constructor */
1370 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1372 return jni_NewLocalRef(env, (jobject) o);
1376 /* NewObjectA *****************************************************************
1378 Programmers place all arguments that are to be passed to the
1379 constructor in an args array of jvalues that immediately follows
1380 the methodID argument. NewObjectA() accepts the arguments in this
1381 array, and, in turn, passes them to the Java method that the
1382 programmer wishes to invoke.
1384 *******************************************************************************/
1386 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1393 STATISTICS(jniinvokation());
1395 c = LLNI_classinfo_unwrap(clazz);
1396 m = (methodinfo *) methodID;
1405 /* call constructor */
1407 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1409 return jni_NewLocalRef(env, (jobject) o);
1413 /* GetObjectClass **************************************************************
1415 Returns the class of an object.
1417 *******************************************************************************/
1419 jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
1424 TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
1426 o = (java_handle_t *) obj;
1428 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1431 LLNI_class_get(o, c);
1433 java_handle_t* h = LLNI_classinfo_wrap(c);
1435 return (jclass) jni_NewLocalRef(env, (jobject) h);
1439 /* IsInstanceOf ****************************************************************
1441 Tests whether an object is an instance of a class.
1443 *******************************************************************************/
1445 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1450 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1452 /* XXX Is this correct? */
1453 c = LLNI_classinfo_unwrap(clazz);
1454 h = (java_handle_t *) obj;
1456 return class_is_instance(c, h);
1460 /* Reflection Support *********************************************************/
1462 /* FromReflectedMethod *********************************************************
1464 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1465 object to a method ID.
1467 *******************************************************************************/
1469 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1471 #if defined(ENABLE_JAVASE)
1474 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1476 java_lang_Object o(method);
1481 if (o.get_Class() == class_java_lang_reflect_Constructor) {
1482 java_lang_reflect_Constructor rc(method);
1483 m = rc.get_method();
1486 assert(o.get_Class() == class_java_lang_reflect_Method);
1488 java_lang_reflect_Method rm(method);
1489 m = rm.get_method();
1492 return (jmethodID) m;
1494 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1496 // Keep compiler happy.
1502 /* FromReflectedField **********************************************************
1504 Converts a java.lang.reflect.Field to a field ID.
1506 *******************************************************************************/
1508 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1510 #if defined(ENABLE_JAVASE)
1512 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1514 java_lang_reflect_Field rf(field);
1519 fieldinfo* f = rf.get_field();
1521 return (jfieldID) f;
1523 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1525 // Keep compiler happy.
1531 /* ToReflectedMethod ***********************************************************
1533 Converts a method ID derived from cls to an instance of the
1534 java.lang.reflect.Method class or to an instance of the
1535 java.lang.reflect.Constructor class.
1537 *******************************************************************************/
1539 jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1541 #if defined(ENABLE_JAVASE)
1542 TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1544 methodinfo* m = (methodinfo *) methodID;
1546 /* HotSpot does the same assert. */
1548 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1552 if (m->name == utf_init) {
1553 h = java_lang_reflect_Constructor(m).get_handle();
1556 h = java_lang_reflect_Method(m).get_handle();
1561 vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
1563 /* keep compiler happy */
1570 /* ToReflectedField ************************************************************
1572 Converts a field ID derived from cls to an instance of the
1573 java.lang.reflect.Field class.
1575 *******************************************************************************/
1577 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1580 STATISTICS(jniinvokation());
1582 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1588 /* Calling Instance Methods ***************************************************/
1590 /* GetMethodID *****************************************************************
1592 Returns the method ID for an instance (nonstatic) method of a class
1593 or interface. The method may be defined in one of the clazz's
1594 superclasses and inherited by clazz. The method is determined by
1595 its name and signature.
1597 GetMethodID() causes an uninitialized class to be initialized.
1599 *******************************************************************************/
1601 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1609 STATISTICS(jniinvokation());
1611 c = LLNI_classinfo_unwrap(clazz);
1616 if (!(c->state & CLASS_INITIALIZED))
1617 if (!initialize_class(c))
1620 /* try to get the method of the class or one of it's superclasses */
1622 uname = utf_new_char((char *) name);
1623 udesc = utf_new_char((char *) sig);
1625 m = class_resolvemethod(c, uname, udesc);
1627 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1628 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1633 return (jmethodID) m;
1637 /* JNI-functions for calling instance methods *********************************/
1639 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1640 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1641 jmethodID methodID, ...) \
1648 o = (java_handle_t *) obj; \
1649 m = (methodinfo *) methodID; \
1651 va_start(ap, methodID); \
1652 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1658 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1659 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1660 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1661 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1662 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1663 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1664 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1665 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1668 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1669 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1670 jmethodID methodID, va_list args) \
1676 o = (java_handle_t *) obj; \
1677 m = (methodinfo *) methodID; \
1679 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1684 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1685 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1686 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1687 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1688 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1689 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1690 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1691 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1694 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1695 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1696 jmethodID methodID, \
1697 const jvalue *args) \
1703 o = (java_handle_t *) obj; \
1704 m = (methodinfo *) methodID; \
1706 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1711 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1712 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1713 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1714 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1715 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1716 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1717 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1718 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1721 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1729 o = (java_handle_t *) obj;
1730 m = (methodinfo *) methodID;
1732 va_start(ap, methodID);
1733 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1736 return jni_NewLocalRef(env, (jobject) ret);
1740 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1747 o = (java_handle_t *) obj;
1748 m = (methodinfo *) methodID;
1750 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1752 return jni_NewLocalRef(env, (jobject) ret);
1756 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1763 o = (java_handle_t *) obj;
1764 m = (methodinfo *) methodID;
1766 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1768 return jni_NewLocalRef(env, (jobject) ret);
1773 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1779 o = (java_handle_t *) obj;
1780 m = (methodinfo *) methodID;
1782 va_start(ap, methodID);
1783 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1788 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1794 o = (java_handle_t *) obj;
1795 m = (methodinfo *) methodID;
1797 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1801 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1807 o = (java_handle_t *) obj;
1808 m = (methodinfo *) methodID;
1810 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1815 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1816 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1817 jclass clazz, jmethodID methodID, \
1826 o = (java_handle_t *) obj; \
1827 c = LLNI_classinfo_unwrap(clazz); \
1828 m = (methodinfo *) methodID; \
1830 va_start(ap, methodID); \
1831 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1837 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1838 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1839 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1840 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1841 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1842 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1843 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1844 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1847 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1848 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1849 jclass clazz, jmethodID methodID, \
1857 o = (java_handle_t *) obj; \
1858 c = LLNI_classinfo_unwrap(clazz); \
1859 m = (methodinfo *) methodID; \
1861 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1866 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1867 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1868 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1869 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1870 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1871 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1872 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1873 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1876 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1877 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1878 jclass clazz, jmethodID methodID, \
1879 const jvalue *args) \
1881 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1886 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1887 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1888 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1889 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1890 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1891 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1892 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1893 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1895 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1896 jclass clazz, jmethodID methodID,
1905 o = (java_handle_t *) obj;
1906 c = LLNI_classinfo_unwrap(clazz);
1907 m = (methodinfo *) methodID;
1909 va_start(ap, methodID);
1910 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1913 return jni_NewLocalRef(env, (jobject) r);
1917 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1918 jclass clazz, jmethodID methodID,
1926 o = (java_handle_t *) obj;
1927 c = LLNI_classinfo_unwrap(clazz);
1928 m = (methodinfo *) methodID;
1930 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1932 return jni_NewLocalRef(env, (jobject) r);
1936 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1937 jclass clazz, jmethodID methodID,
1940 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1942 return jni_NewLocalRef(env, NULL);
1946 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1947 jmethodID methodID, ...)
1954 o = (java_handle_t *) obj;
1955 c = LLNI_classinfo_unwrap(clazz);
1956 m = (methodinfo *) methodID;
1958 va_start(ap, methodID);
1959 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1964 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1965 jmethodID methodID, va_list args)
1971 o = (java_handle_t *) obj;
1972 c = LLNI_classinfo_unwrap(clazz);
1973 m = (methodinfo *) methodID;
1975 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
1979 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
1980 jmethodID methodID, const jvalue * args)
1986 o = (java_handle_t *) obj;
1987 c = LLNI_classinfo_unwrap(clazz);
1988 m = (methodinfo *) methodID;
1990 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
1994 /* Accessing Fields of Objects ************************************************/
1996 /* GetFieldID ******************************************************************
1998 Returns the field ID for an instance (nonstatic) field of a
1999 class. The field is specified by its name and signature. The
2000 Get<type>Field and Set<type>Field families of accessor functions
2001 use field IDs to retrieve object fields.
2003 *******************************************************************************/
2005 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2013 STATISTICS(jniinvokation());
2015 c = LLNI_classinfo_unwrap(clazz);
2017 /* XXX NPE check? */
2019 uname = utf_new_char((char *) name);
2020 udesc = utf_new_char((char *) sig);
2022 f = class_findfield(c, uname, udesc);
2025 exceptions_throw_nosuchfielderror(c, uname);
2027 return (jfieldID) f;
2031 /* Get<type>Field Routines *****************************************************
2033 This family of accessor routines returns the value of an instance
2034 (nonstatic) field of an object. The field to access is specified by
2035 a field ID obtained by calling GetFieldID().
2037 *******************************************************************************/
2039 #define GET_FIELD(o,type,f) \
2040 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2042 #define JNI_GET_FIELD(name, type, intern) \
2043 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2047 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2049 LLNI_CRITICAL_START; \
2051 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2053 LLNI_CRITICAL_END; \
2055 return (type) ret; \
2058 JNI_GET_FIELD(Boolean, jboolean, s4)
2059 JNI_GET_FIELD(Byte, jbyte, s4)
2060 JNI_GET_FIELD(Char, jchar, s4)
2061 JNI_GET_FIELD(Short, jshort, s4)
2062 JNI_GET_FIELD(Int, jint, s4)
2063 JNI_GET_FIELD(Long, jlong, s8)
2064 JNI_GET_FIELD(Float, jfloat, float)
2065 JNI_GET_FIELD(Double, jdouble, double)
2068 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2072 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2074 LLNI_CRITICAL_START;
2076 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2080 return jni_NewLocalRef(env, (jobject) o);
2084 /* Set<type>Field Routines *****************************************************
2086 This family of accessor routines sets the value of an instance
2087 (nonstatic) field of an object. The field to access is specified by
2088 a field ID obtained by calling GetFieldID().
2090 *******************************************************************************/
2092 #define SET_FIELD(o,type,f,value) \
2093 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2095 #define GET_FIELDINFO(f) ((fieldinfo*) (f))
2097 #define JNI_SET_FIELD(name, type, intern) \
2098 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2101 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2103 LLNI_CRITICAL_START; \
2105 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2107 LLNI_CRITICAL_END; \
2109 if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE) \
2110 Atomic::memory_barrier(); \
2113 JNI_SET_FIELD(Boolean, jboolean, s4)
2114 JNI_SET_FIELD(Byte, jbyte, s4)
2115 JNI_SET_FIELD(Char, jchar, s4)
2116 JNI_SET_FIELD(Short, jshort, s4)
2117 JNI_SET_FIELD(Int, jint, s4)
2118 JNI_SET_FIELD(Long, jlong, s8)
2119 JNI_SET_FIELD(Float, jfloat, float)
2120 JNI_SET_FIELD(Double, jdouble, double)
2123 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2126 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2128 LLNI_CRITICAL_START;
2130 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2134 if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)
2135 Atomic::memory_barrier();
2139 /* Calling Static Methods *****************************************************/
2141 /* GetStaticMethodID ***********************************************************
2143 Returns the method ID for a static method of a class. The method is
2144 specified by its name and signature.
2146 GetStaticMethodID() causes an uninitialized class to be
2149 *******************************************************************************/
2151 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2159 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2161 c = LLNI_classinfo_unwrap(clazz);
2166 if (!(c->state & CLASS_INITIALIZED))
2167 if (!initialize_class(c))
2170 /* try to get the static method of the class */
2172 uname = utf_new_char((char *) name);
2173 udesc = utf_new_char((char *) sig);
2175 m = class_resolvemethod(c, uname, udesc);
2177 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2178 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2183 return (jmethodID) m;
2187 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2188 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2189 jmethodID methodID, ...) \
2195 m = (methodinfo *) methodID; \
2197 va_start(ap, methodID); \
2198 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2204 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2205 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2206 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2207 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2208 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2209 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2210 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2211 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2214 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2215 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2216 jmethodID methodID, va_list args) \
2221 m = (methodinfo *) methodID; \
2223 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2228 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2229 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2230 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2231 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2232 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2233 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2234 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2235 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2238 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2239 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2240 jmethodID methodID, const jvalue *args) \
2245 m = (methodinfo *) methodID; \
2247 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2252 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2253 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2254 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2255 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2256 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2257 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2258 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2259 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2262 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2263 jmethodID methodID, ...)
2269 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2271 m = (methodinfo *) methodID;
2273 va_start(ap, methodID);
2274 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2277 return jni_NewLocalRef(env, (jobject) o);
2281 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2282 jmethodID methodID, va_list args)
2287 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
2289 m = (methodinfo *) methodID;
2291 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2293 return jni_NewLocalRef(env, (jobject) o);
2297 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2298 jmethodID methodID, const jvalue *args)
2303 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2305 m = (methodinfo *) methodID;
2307 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2309 return jni_NewLocalRef(env, (jobject) o);
2313 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2314 jmethodID methodID, ...)
2319 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2321 m = (methodinfo *) methodID;
2323 va_start(ap, methodID);
2324 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2329 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2330 jmethodID methodID, va_list args)
2334 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
2336 m = (methodinfo *) methodID;
2338 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2342 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2343 jmethodID methodID, const jvalue * args)
2347 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2349 m = (methodinfo *) methodID;
2351 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2355 /* Accessing Static Fields ****************************************************/
2357 /* GetStaticFieldID ************************************************************
2359 Returns the field ID for a static field of a class. The field is
2360 specified by its name and signature. The GetStatic<type>Field and
2361 SetStatic<type>Field families of accessor functions use field IDs
2362 to retrieve static fields.
2364 *******************************************************************************/
2366 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2374 STATISTICS(jniinvokation());
2376 c = LLNI_classinfo_unwrap(clazz);
2378 uname = utf_new_char((char *) name);
2379 usig = utf_new_char((char *) sig);
2381 f = class_findfield(c, uname, usig);
2384 exceptions_throw_nosuchfielderror(c, uname);
2386 return (jfieldID) f;
2390 /* GetStatic<type>Field ********************************************************
2392 This family of accessor routines returns the value of a static
2395 *******************************************************************************/
2397 #define JNI_GET_STATIC_FIELD(name, type, field) \
2398 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2404 STATISTICS(jniinvokation()); \
2406 c = LLNI_classinfo_unwrap(clazz); \
2407 f = (fieldinfo *) fieldID; \
2409 if (!(c->state & CLASS_INITIALIZED)) \
2410 if (!initialize_class(c)) \
2413 return f->value->field; \
2416 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2417 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2418 JNI_GET_STATIC_FIELD(Char, jchar, i)
2419 JNI_GET_STATIC_FIELD(Short, jshort, i)
2420 JNI_GET_STATIC_FIELD(Int, jint, i)
2421 JNI_GET_STATIC_FIELD(Long, jlong, l)
2422 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2423 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2426 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2433 STATISTICS(jniinvokation());
2435 c = LLNI_classinfo_unwrap(clazz);
2436 f = (fieldinfo *) fieldID;
2438 if (!(c->state & CLASS_INITIALIZED))
2439 if (!initialize_class(c))
2442 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2444 return jni_NewLocalRef(env, (jobject) h);
2448 /* SetStatic<type>Field *******************************************************
2450 This family of accessor routines sets the value of a static field
2453 *******************************************************************************/
2455 #define JNI_SET_STATIC_FIELD(name, type, field) \
2456 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2463 STATISTICS(jniinvokation()); \
2465 c = LLNI_classinfo_unwrap(clazz); \
2466 f = (fieldinfo *) fieldID; \
2468 if (!(c->state & CLASS_INITIALIZED)) \
2469 if (!initialize_class(c)) \
2472 f->value->field = value; \
2474 if (f->flags & ACC_VOLATILE) \
2475 Atomic::memory_barrier(); \
2478 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2479 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2480 JNI_SET_STATIC_FIELD(Char, jchar, i)
2481 JNI_SET_STATIC_FIELD(Short, jshort, i)
2482 JNI_SET_STATIC_FIELD(Int, jint, i)
2483 JNI_SET_STATIC_FIELD(Long, jlong, l)
2484 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2485 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2488 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2494 STATISTICS(jniinvokation());
2496 c = LLNI_classinfo_unwrap(clazz);
2497 f = (fieldinfo *) fieldID;
2499 if (!(c->state & CLASS_INITIALIZED))
2500 if (!initialize_class(c))
2503 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2505 if (f->flags & ACC_VOLATILE)
2506 Atomic::memory_barrier();
2510 /* String Operations **********************************************************/
2512 /* NewString *******************************************************************
2514 Create new java.lang.String object from an array of Unicode
2517 *******************************************************************************/
2519 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
2521 TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
2531 uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
2532 for (jsize i = 0; i < len; i++)
2535 java_handle_t* h = builtin_new(class_java_lang_String);
2540 java_lang_String s(h, ca.get_handle(), len, 0);
2542 return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
2546 static jchar emptyStringJ[]={0,0};
2548 /* GetStringLength *************************************************************
2550 Returns the length (the count of Unicode characters) of a Java
2553 *******************************************************************************/
2555 jsize jni_GetStringLength(JNIEnv *env, jstring str)
2557 TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
2559 java_lang_String s(str);
2560 jsize count = s.get_count();
2562 TRACEJNICALLSEXIT(("->%d)", count));
2568 /* GetStringChars **************************************************************
2570 Returns a pointer to the array of Unicode characters of the
2571 string. This pointer is valid until ReleaseStringChars() is called.
2573 *******************************************************************************/
2575 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2580 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2583 // FIXME This is really ugly.
2584 return emptyStringJ;
2586 java_lang_String s(str);
2588 CharArray ca(s.get_value());
2590 int32_t count = s.get_count();
2591 int32_t offset = s.get_offset();
2596 /* allocate memory */
2598 stringbuffer = MNEW(u2, count + 1);
2603 uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
2604 for (i = 0; i < count; i++)
2605 stringbuffer[i] = ptr[offset + i];
2607 /* terminate string */
2609 stringbuffer[i] = '\0';
2614 return (jchar*) stringbuffer;
2618 /* ReleaseStringChars **********************************************************
2620 Informs the VM that the native code no longer needs access to
2621 chars. The chars argument is a pointer obtained from string using
2624 *******************************************************************************/
2626 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2628 TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
2631 if (chars == emptyStringJ)
2634 java_lang_String s(str);
2635 int32_t count = s.get_count();
2637 MFREE(((jchar*) chars), jchar, count + 1);
2641 /* NewStringUTF ****************************************************************
2643 Constructs a new java.lang.String object from an array of UTF-8
2646 *******************************************************************************/
2648 jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
2650 TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2652 java_handle_t *h = javastring_safe_new_from_utf8(bytes);
2654 return (jstring) jni_NewLocalRef(env, (jobject) h);
2658 /****************** returns the utf8 length in bytes of a string *******************/
2660 jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
2662 TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
2664 java_lang_String s(string);
2665 CharArray ca(s.get_value());
2666 int32_t count = s.get_count();
2668 // FIXME GC critical section!
2669 uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
2670 int32_t length = u2_utflength(ptr, count);
2676 /* GetStringUTFChars ***********************************************************
2678 Returns a pointer to an array of UTF-8 characters of the
2679 string. This array is valid until it is released by
2680 ReleaseStringUTFChars().
2682 *******************************************************************************/
2684 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2689 STATISTICS(jniinvokation());
2697 u = javastring_toutf((java_handle_t *) string, false);
2706 /* ReleaseStringUTFChars *******************************************************
2708 Informs the VM that the native code no longer needs access to
2709 utf. The utf argument is a pointer derived from string using
2710 GetStringUTFChars().
2712 *******************************************************************************/
2714 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2716 STATISTICS(jniinvokation());
2718 /* XXX we don't release utf chars right now, perhaps that should be done
2719 later. Since there is always one reference the garbage collector will
2724 /* Array Operations ***********************************************************/
2726 /* GetArrayLength **************************************************************
2728 Returns the number of elements in the array.
2730 *******************************************************************************/
2732 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2734 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2738 jsize size = a.get_length();
2744 /* NewObjectArray **************************************************************
2746 Constructs a new array holding objects in class elementClass. All
2747 elements are initially set to initialElement.
2749 *******************************************************************************/
2751 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2752 jclass elementClass, jobject initialElement)
2758 STATISTICS(jniinvokation());
2760 c = LLNI_classinfo_unwrap(elementClass);
2761 o = (java_handle_t *) initialElement;
2764 exceptions_throw_negativearraysizeexception();
2768 ObjectArray oa(length, c);
2773 /* set all elements to initialElement */
2775 for (i = 0; i < length; i++)
2776 oa.set_element(i, o);
2778 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa.get_handle());
2782 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2785 STATISTICS(jniinvokation());
2787 ObjectArray oa(array);
2789 if (index >= oa.get_length()) {
2790 exceptions_throw_arrayindexoutofboundsexception();
2794 java_handle_t* o = oa.get_element(index);
2796 return jni_NewLocalRef(env, (jobject) o);
2800 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2801 jsize index, jobject val)
2803 STATISTICS(jniinvokation());
2805 ObjectArray oa(array);
2807 if (index >= oa.get_length()) {
2808 exceptions_throw_arrayindexoutofboundsexception();
2812 /* check if the class of value is a subclass of the element class
2815 java_handle_t* o = (java_handle_t *) val;
2817 if (!builtin_canstore(oa.get_handle(), o))
2820 oa.set_element(index, o);
2824 #define JNI_NEW_ARRAY(name, type) \
2825 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2827 STATISTICS(jniinvokation()); \
2830 exceptions_throw_negativearraysizeexception(); \
2834 name##Array a(len); \
2836 return (type) jni_NewLocalRef(env, \
2837 (jobject) a.get_handle()); \
2840 JNI_NEW_ARRAY(Boolean, jbooleanArray)
2841 JNI_NEW_ARRAY(Byte, jbyteArray)
2842 JNI_NEW_ARRAY(Char, jcharArray)
2843 JNI_NEW_ARRAY(Short, jshortArray)
2844 JNI_NEW_ARRAY(Int, jintArray)
2845 JNI_NEW_ARRAY(Long, jlongArray)
2846 JNI_NEW_ARRAY(Float, jfloatArray)
2847 JNI_NEW_ARRAY(Double, jdoubleArray)
2850 /* Get<PrimitiveType>ArrayElements *********************************************
2852 A family of functions that returns the body of the primitive array.
2854 *******************************************************************************/
2856 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2857 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2860 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2862 name##Array a(array); \
2865 *isCopy = JNI_FALSE; \
2867 return (type *) a.get_raw_data_ptr(); \
2870 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2871 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2872 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2873 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2874 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2875 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2876 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2877 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2880 /* Release<PrimitiveType>ArrayElements *****************************************
2882 A family of functions that informs the VM that the native code no
2883 longer needs access to elems. The elems argument is a pointer
2884 derived from array using the corresponding
2885 Get<PrimitiveType>ArrayElements() function. If necessary, this
2886 function copies back all changes made to elems to the original
2889 *******************************************************************************/
2891 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2892 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2893 type *elems, jint mode) \
2895 STATISTICS(jniinvokation()); \
2897 name##Array a(array); \
2899 if (elems != (type *) a.get_raw_data_ptr()) { \
2902 a.set_region(0, a.get_length(), (intern2 *) elems); \
2905 a.set_region(0, a.get_length(), (intern2 *) elems); \
2906 /* XXX TWISTI how should it be freed? */ \
2909 /* XXX TWISTI how should it be freed? */ \
2915 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2916 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2917 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2918 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2919 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2920 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2921 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2922 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2925 /* Get<PrimitiveType>ArrayRegion **********************************************
2927 A family of functions that copies a region of a primitive array
2930 *******************************************************************************/
2932 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2933 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2934 jsize start, jsize len, type *buf) \
2936 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2938 name##Array a(array); \
2940 if ((start < 0) || (len < 0) || (start + len > a.get_length())) \
2941 exceptions_throw_arrayindexoutofboundsexception(); \
2943 a.get_region(start, len, (intern2 *) buf); \
2946 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2947 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2948 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2949 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2950 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
2951 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
2952 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
2953 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
2956 /* Set<PrimitiveType>ArrayRegion **********************************************
2958 A family of functions that copies back a region of a primitive
2959 array from a buffer.
2961 *******************************************************************************/
2963 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
2964 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
2965 jsize start, jsize len, const type *buf) \
2967 STATISTICS(jniinvokation()); \
2969 name##Array a(array); \
2971 if ((start < 0) || (len < 0) || (start + len > a.get_length())) \
2972 exceptions_throw_arrayindexoutofboundsexception(); \
2974 a.set_region(start, len, (intern2 *) buf); \
2977 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2978 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
2979 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
2980 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
2981 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
2982 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
2983 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
2984 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
2987 /* Registering Native Methods *************************************************/
2989 /* RegisterNatives *************************************************************
2991 Registers native methods with the class specified by the clazz
2992 argument. The methods parameter specifies an array of
2993 JNINativeMethod structures that contain the names, signatures, and
2994 function pointers of the native methods. The nMethods parameter
2995 specifies the number of native methods in the array.
2997 *******************************************************************************/
2999 jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
3001 TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
3003 classinfo* c = LLNI_classinfo_unwrap(clazz);
3005 NativeMethods& nm = VM::get_current()->get_nativemethods();
3006 nm.register_methods(c->name, methods, nMethods);
3012 /* UnregisterNatives ***********************************************************
3014 Unregisters native methods of a class. The class goes back to the
3015 state before it was linked or registered with its native method
3018 This function should not be used in normal native code. Instead, it
3019 provides special programs a way to reload and relink native
3022 *******************************************************************************/
3024 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3026 STATISTICS(jniinvokation());
3028 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3030 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3036 /* Monitor Operations *********************************************************/
3038 /* MonitorEnter ****************************************************************
3040 Enters the monitor associated with the underlying Java object
3043 *******************************************************************************/
3045 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3047 STATISTICS(jniinvokation());
3050 exceptions_throw_nullpointerexception();
3054 LOCK_MONITOR_ENTER(obj);
3060 /* MonitorExit *****************************************************************
3062 The current thread must be the owner of the monitor associated with
3063 the underlying Java object referred to by obj. The thread
3064 decrements the counter indicating the number of times it has
3065 entered this monitor. If the value of the counter becomes zero, the
3066 current thread releases the monitor.
3068 *******************************************************************************/
3070 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3072 STATISTICS(jniinvokation());
3075 exceptions_throw_nullpointerexception();
3079 LOCK_MONITOR_EXIT(obj);
3085 /* JavaVM Interface ***********************************************************/
3087 /* GetJavaVM *******************************************************************
3089 Returns the Java VM interface (used in the Invocation API)
3090 associated with the current thread. The result is placed at the
3091 location pointed to by the second argument, vm.
3093 *******************************************************************************/
3095 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3097 STATISTICS(jniinvokation());
3099 *javavm = VM::get_current()->get_javavm();
3105 /* GetStringRegion *************************************************************
3107 Copies len number of Unicode characters beginning at offset start
3108 to the given buffer buf.
3110 Throws StringIndexOutOfBoundsException on index overflow.
3112 *******************************************************************************/
3114 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3116 java_lang_String s(str);
3117 CharArray ca(s.get_value());
3118 int32_t count = s.get_count();
3120 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3121 exceptions_throw_stringindexoutofboundsexception();
3125 ca.get_region(start, len, buf);
3129 /* GetStringUTFRegion **********************************************************
3131 Translates len number of Unicode characters beginning at offset
3132 start into UTF-8 format and place the result in the given buffer
3135 Throws StringIndexOutOfBoundsException on index overflow.
3137 *******************************************************************************/
3139 void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3141 TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3143 java_lang_String s(str);
3145 CharArray ca(s.get_value());
3147 int32_t count = s.get_count();
3148 int32_t offset = s.get_offset();
3150 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3151 exceptions_throw_stringindexoutofboundsexception();
3158 uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
3159 for (i = 0; i < len; i++)
3160 buf[i] = ptr[offset + start + i];
3166 /* GetPrimitiveArrayCritical ***************************************************
3168 Obtain a direct pointer to array elements.
3170 ATTENTION: Critical section keeps open when this function returns!
3171 See ReleasePrimitiveArrayCritical.
3173 *******************************************************************************/
3175 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3179 arraydescriptor* ad;
3182 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3184 if (isCopy != NULL) {
3185 *isCopy = JNI_FALSE;
3188 LLNI_CRITICAL_START;
3190 h = (java_handle_t*) array;
3191 a = (java_array_t*) LLNI_UNWRAP(h);
3192 ad = a->objheader.vftbl->arraydesc;
3198 data = (void*) (((intptr_t) a) + ad->dataoffset);
3204 /* ReleasePrimitiveArrayCritical ***********************************************
3206 No specific documentation.
3208 ATTENTION: This function closes the critical section opened in
3209 GetPrimitiveArrayCritical!
3211 *******************************************************************************/
3213 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3215 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3221 /* GetStringCritical ***********************************************************
3223 The semantics of these two functions are similar to the existing
3224 Get/ReleaseStringChars functions.
3226 *******************************************************************************/
3228 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3231 STATISTICS(jniinvokation());
3233 return jni_GetStringChars(env, string, isCopy);
3237 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3238 const jchar *cstring)
3240 STATISTICS(jniinvokation());
3242 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3246 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3248 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3254 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3256 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3260 /* NewGlobalRef ****************************************************************
3262 Creates a new global reference to the object referred to by the obj
3265 *******************************************************************************/
3267 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3269 hashtable_global_ref_entry *gre;
3270 u4 key; /* hashkey */
3271 u4 slot; /* slot in hashtable */
3274 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3276 o = (java_handle_t *) obj;
3278 hashtable_global_ref->mutex->lock();
3280 LLNI_CRITICAL_START;
3282 /* normally addresses are aligned to 4, 8 or 16 bytes */
3284 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3285 slot = key & (hashtable_global_ref->size - 1);
3286 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3288 /* search external hash chain for the entry */
3291 if (gre->o == LLNI_DIRECT(o)) {
3292 /* global object found, increment the reference */
3299 gre = gre->hashlink; /* next element in external chain */
3304 /* global ref not found, create a new one */
3307 gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3309 #if defined(ENABLE_GC_CACAO)
3310 /* register global ref with the GC */
3312 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3315 LLNI_CRITICAL_START;
3317 gre->o = LLNI_DIRECT(o);
3322 /* insert entry into hashtable */
3324 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3326 hashtable_global_ref->ptr[slot] = gre;
3328 /* update number of hashtable-entries */
3330 hashtable_global_ref->entries++;
3333 hashtable_global_ref->mutex->unlock();
3335 #if defined(ENABLE_HANDLES)
3343 /* DeleteGlobalRef *************************************************************
3345 Deletes the global reference pointed to by globalRef.
3347 *******************************************************************************/
3349 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3351 hashtable_global_ref_entry *gre;
3352 hashtable_global_ref_entry *prevgre;
3353 u4 key; /* hashkey */
3354 u4 slot; /* slot in hashtable */
3357 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3359 o = (java_handle_t *) globalRef;
3361 hashtable_global_ref->mutex->lock();
3363 LLNI_CRITICAL_START;
3365 /* normally addresses are aligned to 4, 8 or 16 bytes */
3367 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3368 slot = key & (hashtable_global_ref->size - 1);
3369 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3371 /* initialize prevgre */
3375 /* search external hash chain for the entry */
3378 if (gre->o == LLNI_DIRECT(o)) {
3379 /* global object found, decrement the reference count */
3383 /* if reference count is 0, remove the entry */
3385 if (gre->refs == 0) {
3386 /* special handling if it's the first in the chain */
3388 if (prevgre == NULL)
3389 hashtable_global_ref->ptr[slot] = gre->hashlink;
3391 prevgre->hashlink = gre->hashlink;
3393 #if defined(ENABLE_GC_CACAO)
3394 /* unregister global ref with the GC */
3396 gc_reference_unregister(&(gre->o));
3404 hashtable_global_ref->mutex->unlock();
3409 prevgre = gre; /* save current pointer for removal */
3410 gre = gre->hashlink; /* next element in external chain */
3413 log_println("jni_DeleteGlobalRef: Global reference not found.");
3417 hashtable_global_ref->mutex->unlock();
3421 /* ExceptionCheck **************************************************************
3423 Returns JNI_TRUE when there is a pending exception; otherwise,
3426 *******************************************************************************/
3428 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3432 STATISTICS(jniinvokation());
3434 o = exceptions_get_exception();
3436 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3440 /* New JNI 1.4 functions ******************************************************/
3442 /* NewDirectByteBuffer *********************************************************
3444 Allocates and returns a direct java.nio.ByteBuffer referring to the
3445 block of memory starting at the memory address address and
3446 extending capacity bytes.
3448 *******************************************************************************/
3450 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3452 #if defined(ENABLE_JAVASE)
3453 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3454 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3456 // Allocate a gnu.classpath.Pointer{32,64} object.
3458 # if SIZEOF_VOID_P == 8
3459 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
3461 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
3467 gnu_classpath_Pointer p(h, address);
3469 // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
3471 java_handle_t* nbuf =
3472 (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3473 (jmethodID) dbbirw_init, NULL, p.get_handle(),
3474 (jint) capacity, (jint) capacity, (jint) 0);
3476 // Add a local reference and return the value.
3478 TRACEJNICALLSEXIT(("->%p", nbuf));
3480 return jni_NewLocalRef(env, (jobject) nbuf);
3482 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3488 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3490 /* Be paranoid about address sign-extension. */
3492 addr = (int64_t) ((uintptr_t) address);
3493 cap = (int32_t) capacity;
3495 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3496 (jmethodID) dbb_init, addr, cap);
3498 /* Add local reference and return the value. */
3500 TRACEJNICALLSEXIT(("->%p", o));
3502 return jni_NewLocalRef(env, o);
3505 # error unknown classpath configuration
3509 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3511 /* keep compiler happy */
3518 /* GetDirectBufferAddress ******************************************************
3520 Fetches and returns the starting address of the memory region
3521 referenced by the given direct java.nio.Buffer.
3523 *******************************************************************************/
3525 void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3527 #if defined(ENABLE_JAVASE)
3528 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3530 TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3532 /* Prevent compiler warning. */
3534 java_handle_t* h = (java_handle_t *) buf;
3536 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3539 java_nio_DirectByteBufferImpl dbb(buf);
3540 java_handle_t* address = dbb.get_address();
3542 if (address == NULL) {
3543 TRACEJNICALLSEXIT(("->%p", NULL));
3547 gnu_classpath_Pointer p(address);
3548 void* data = p.get_data();
3550 TRACEJNICALLSEXIT(("->%p", data));
3554 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3556 TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3558 java_nio_Buffer jnb(buf);
3560 if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3563 void* address = jnb.get_address();
3568 # error unknown classpath configuration
3573 vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
3575 // Keep compiler happy.
3582 /* GetDirectBufferCapacity *****************************************************
3584 Fetches and returns the capacity in bytes of the memory region
3585 referenced by the given direct java.nio.Buffer.
3587 *******************************************************************************/
3589 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3591 #if defined(ENABLE_JAVASE)
3592 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3593 TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3595 java_handle_t* h = (java_handle_t *) buf;
3597 if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
3600 java_nio_Buffer b(h);
3601 jlong capacity = b.get_cap();
3604 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3606 TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3608 java_nio_Buffer jnb(buf);
3610 if (!builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3613 jlong capacity = jnb.get_capacity();
3618 # error unknown classpath configuration
3622 vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
3624 // Keep compiler happy.
3631 /* GetObjectRefType ************************************************************
3633 Returns the type of the object referred to by the obj argument. The
3634 argument obj can either be a local, global or weak global
3637 *******************************************************************************/
3639 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3641 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3643 return (jobjectRefType) NULL;
3647 /* DestroyJavaVM ***************************************************************
3649 Unloads a Java VM and reclaims its resources. Only the main thread
3650 can unload the VM. The system waits until the main thread is only
3651 remaining user thread before it destroys the VM.
3653 *******************************************************************************/
3655 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3659 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3661 if (VM::get_current()->is_created() == false)
3664 status = vm_destroy(javavm);
3670 /* AttachCurrentThread *********************************************************
3672 Attaches the current thread to a Java VM. Returns a JNI interface
3673 pointer in the JNIEnv argument.
3675 Trying to attach a thread that is already attached is a no-op.
3677 A native thread cannot be attached simultaneously to two Java VMs.
3679 When a thread is attached to the VM, the context class loader is
3680 the bootstrap loader.
3682 *******************************************************************************/
3684 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3686 #if defined(ENABLE_THREADS)
3687 JavaVMAttachArgs *vm_aargs;
3690 /* If the current thread has already been attached, this operation
3693 result = thread_current_is_attached();
3695 if (result == true) {
3696 *p_env = VM::get_current()->get_jnienv();
3700 vm_aargs = (JavaVMAttachArgs *) thr_args;
3702 if (vm_aargs != NULL) {
3703 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3704 (vm_aargs->version != JNI_VERSION_1_4))
3705 return JNI_EVERSION;
3708 if (!thread_attach_current_external_thread(vm_aargs, false))
3711 if (!localref_table_init())
3715 *p_env = VM::get_current()->get_jnienv();
3721 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3725 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3727 if (VM::get_current()->is_created() == false)
3730 result = jni_attach_current_thread(p_env, thr_args, false);
3736 /* DetachCurrentThread *********************************************************
3738 Detaches the current thread from a Java VM. All Java monitors held
3739 by this thread are released. All Java threads waiting for this
3740 thread to die are notified.
3742 In JDK 1.1, the main thread cannot be detached from the VM. It must
3743 call DestroyJavaVM to unload the entire VM.
3745 In the JDK, the main thread can be detached from the VM.
3747 The main thread, which is the thread that created the Java VM,
3748 cannot be detached from the VM. Instead, the main thread must call
3749 JNI_DestroyJavaVM() to unload the entire VM.
3751 *******************************************************************************/
3753 jint jni_DetachCurrentThread(JavaVM *vm)
3755 #if defined(ENABLE_THREADS)
3758 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3760 /* If the current thread has already been detached, this operation
3763 result = thread_current_is_attached();
3765 if (result == false)
3768 /* We need to pop all frames before we can destroy the table. */
3770 localref_frame_pop_all();
3772 if (!localref_table_destroy())
3775 if (!thread_detach_current_external_thread())
3783 /* GetEnv **********************************************************************
3785 If the current thread is not attached to the VM, sets *env to NULL,
3786 and returns JNI_EDETACHED. If the specified version is not
3787 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3788 sets *env to the appropriate interface, and returns JNI_OK.
3790 *******************************************************************************/
3792 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3794 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3796 if (VM::get_current()->is_created() == false) {
3798 return JNI_EDETACHED;
3801 #if defined(ENABLE_THREADS)
3802 if (thread_get_current() == NULL) {
3805 return JNI_EDETACHED;
3809 /* Check the JNI version. */
3811 if (jni_version_check(version) == true) {
3812 *env = VM::get_current()->get_jnienv();
3816 #if defined(ENABLE_JVMTI)
3817 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3818 == JVMTI_VERSION_INTERFACE_JVMTI) {
3820 *env = (void *) jvmti_new_environment();
3829 return JNI_EVERSION;
3833 /* AttachCurrentThreadAsDaemon *************************************************
3835 Same semantics as AttachCurrentThread, but the newly-created
3836 java.lang.Thread instance is a daemon.
3838 If the thread has already been attached via either
3839 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3840 simply sets the value pointed to by penv to the JNIEnv of the
3841 current thread. In this case neither AttachCurrentThread nor this
3842 routine have any effect on the daemon status of the thread.
3844 *******************************************************************************/
3846 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3850 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
3852 if (VM::get_current()->is_created() == false)
3855 result = jni_attach_current_thread(penv, args, true);
3861 /* JNI invocation table *******************************************************/
3863 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3868 _Jv_JNI_DestroyJavaVM,
3869 jni_AttachCurrentThread,
3870 jni_DetachCurrentThread,
3872 jni_AttachCurrentThreadAsDaemon
3876 /* JNI function table *********************************************************/
3878 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3887 jni_FromReflectedMethod,
3888 jni_FromReflectedField,
3889 jni_ToReflectedMethod,
3891 _Jv_JNI_IsAssignableFrom,
3892 _Jv_JNI_ToReflectedField,
3896 _Jv_JNI_ExceptionOccurred,
3897 jni_ExceptionDescribe,
3904 jni_DeleteGlobalRef,
3906 _Jv_JNI_IsSameObject,
3908 jni_EnsureLocalCapacity,
3910 _Jv_JNI_AllocObject,
3916 _Jv_JNI_IsInstanceOf,
3918 _Jv_JNI_GetMethodID,
3920 _Jv_JNI_CallObjectMethod,
3921 _Jv_JNI_CallObjectMethodV,
3922 _Jv_JNI_CallObjectMethodA,
3923 _Jv_JNI_CallBooleanMethod,
3924 _Jv_JNI_CallBooleanMethodV,
3925 _Jv_JNI_CallBooleanMethodA,
3926 _Jv_JNI_CallByteMethod,
3927 _Jv_JNI_CallByteMethodV,
3928 _Jv_JNI_CallByteMethodA,
3929 _Jv_JNI_CallCharMethod,
3930 _Jv_JNI_CallCharMethodV,
3931 _Jv_JNI_CallCharMethodA,
3932 _Jv_JNI_CallShortMethod,
3933 _Jv_JNI_CallShortMethodV,
3934 _Jv_JNI_CallShortMethodA,
3935 _Jv_JNI_CallIntMethod,
3936 _Jv_JNI_CallIntMethodV,
3937 _Jv_JNI_CallIntMethodA,
3938 _Jv_JNI_CallLongMethod,
3939 _Jv_JNI_CallLongMethodV,
3940 _Jv_JNI_CallLongMethodA,
3941 _Jv_JNI_CallFloatMethod,
3942 _Jv_JNI_CallFloatMethodV,
3943 _Jv_JNI_CallFloatMethodA,
3944 _Jv_JNI_CallDoubleMethod,
3945 _Jv_JNI_CallDoubleMethodV,
3946 _Jv_JNI_CallDoubleMethodA,
3947 _Jv_JNI_CallVoidMethod,
3948 _Jv_JNI_CallVoidMethodV,
3949 _Jv_JNI_CallVoidMethodA,
3951 _Jv_JNI_CallNonvirtualObjectMethod,
3952 _Jv_JNI_CallNonvirtualObjectMethodV,
3953 _Jv_JNI_CallNonvirtualObjectMethodA,
3954 _Jv_JNI_CallNonvirtualBooleanMethod,
3955 _Jv_JNI_CallNonvirtualBooleanMethodV,
3956 _Jv_JNI_CallNonvirtualBooleanMethodA,
3957 _Jv_JNI_CallNonvirtualByteMethod,
3958 _Jv_JNI_CallNonvirtualByteMethodV,
3959 _Jv_JNI_CallNonvirtualByteMethodA,
3960 _Jv_JNI_CallNonvirtualCharMethod,
3961 _Jv_JNI_CallNonvirtualCharMethodV,
3962 _Jv_JNI_CallNonvirtualCharMethodA,
3963 _Jv_JNI_CallNonvirtualShortMethod,
3964 _Jv_JNI_CallNonvirtualShortMethodV,
3965 _Jv_JNI_CallNonvirtualShortMethodA,
3966 _Jv_JNI_CallNonvirtualIntMethod,
3967 _Jv_JNI_CallNonvirtualIntMethodV,
3968 _Jv_JNI_CallNonvirtualIntMethodA,
3969 _Jv_JNI_CallNonvirtualLongMethod,
3970 _Jv_JNI_CallNonvirtualLongMethodV,
3971 _Jv_JNI_CallNonvirtualLongMethodA,
3972 _Jv_JNI_CallNonvirtualFloatMethod,
3973 _Jv_JNI_CallNonvirtualFloatMethodV,
3974 _Jv_JNI_CallNonvirtualFloatMethodA,
3975 _Jv_JNI_CallNonvirtualDoubleMethod,
3976 _Jv_JNI_CallNonvirtualDoubleMethodV,
3977 _Jv_JNI_CallNonvirtualDoubleMethodA,
3978 _Jv_JNI_CallNonvirtualVoidMethod,
3979 _Jv_JNI_CallNonvirtualVoidMethodV,
3980 _Jv_JNI_CallNonvirtualVoidMethodA,
3984 _Jv_JNI_GetObjectField,
3985 _Jv_JNI_GetBooleanField,
3986 _Jv_JNI_GetByteField,
3987 _Jv_JNI_GetCharField,
3988 _Jv_JNI_GetShortField,
3989 _Jv_JNI_GetIntField,
3990 _Jv_JNI_GetLongField,
3991 _Jv_JNI_GetFloatField,
3992 _Jv_JNI_GetDoubleField,
3993 _Jv_JNI_SetObjectField,
3994 _Jv_JNI_SetBooleanField,
3995 _Jv_JNI_SetByteField,
3996 _Jv_JNI_SetCharField,
3997 _Jv_JNI_SetShortField,
3998 _Jv_JNI_SetIntField,
3999 _Jv_JNI_SetLongField,
4000 _Jv_JNI_SetFloatField,
4001 _Jv_JNI_SetDoubleField,
4003 _Jv_JNI_GetStaticMethodID,
4005 _Jv_JNI_CallStaticObjectMethod,
4006 _Jv_JNI_CallStaticObjectMethodV,
4007 _Jv_JNI_CallStaticObjectMethodA,
4008 _Jv_JNI_CallStaticBooleanMethod,
4009 _Jv_JNI_CallStaticBooleanMethodV,
4010 _Jv_JNI_CallStaticBooleanMethodA,
4011 _Jv_JNI_CallStaticByteMethod,
4012 _Jv_JNI_CallStaticByteMethodV,
4013 _Jv_JNI_CallStaticByteMethodA,
4014 _Jv_JNI_CallStaticCharMethod,
4015 _Jv_JNI_CallStaticCharMethodV,
4016 _Jv_JNI_CallStaticCharMethodA,
4017 _Jv_JNI_CallStaticShortMethod,
4018 _Jv_JNI_CallStaticShortMethodV,
4019 _Jv_JNI_CallStaticShortMethodA,
4020 _Jv_JNI_CallStaticIntMethod,
4021 _Jv_JNI_CallStaticIntMethodV,
4022 _Jv_JNI_CallStaticIntMethodA,
4023 _Jv_JNI_CallStaticLongMethod,
4024 _Jv_JNI_CallStaticLongMethodV,
4025 _Jv_JNI_CallStaticLongMethodA,
4026 _Jv_JNI_CallStaticFloatMethod,
4027 _Jv_JNI_CallStaticFloatMethodV,
4028 _Jv_JNI_CallStaticFloatMethodA,
4029 _Jv_JNI_CallStaticDoubleMethod,
4030 _Jv_JNI_CallStaticDoubleMethodV,
4031 _Jv_JNI_CallStaticDoubleMethodA,
4032 _Jv_JNI_CallStaticVoidMethod,
4033 _Jv_JNI_CallStaticVoidMethodV,
4034 _Jv_JNI_CallStaticVoidMethodA,
4036 _Jv_JNI_GetStaticFieldID,
4038 _Jv_JNI_GetStaticObjectField,
4039 _Jv_JNI_GetStaticBooleanField,
4040 _Jv_JNI_GetStaticByteField,
4041 _Jv_JNI_GetStaticCharField,
4042 _Jv_JNI_GetStaticShortField,
4043 _Jv_JNI_GetStaticIntField,
4044 _Jv_JNI_GetStaticLongField,
4045 _Jv_JNI_GetStaticFloatField,
4046 _Jv_JNI_GetStaticDoubleField,
4047 _Jv_JNI_SetStaticObjectField,
4048 _Jv_JNI_SetStaticBooleanField,
4049 _Jv_JNI_SetStaticByteField,
4050 _Jv_JNI_SetStaticCharField,
4051 _Jv_JNI_SetStaticShortField,
4052 _Jv_JNI_SetStaticIntField,
4053 _Jv_JNI_SetStaticLongField,
4054 _Jv_JNI_SetStaticFloatField,
4055 _Jv_JNI_SetStaticDoubleField,
4058 jni_GetStringLength,
4060 _Jv_JNI_ReleaseStringChars,
4063 jni_GetStringUTFLength,
4064 _Jv_JNI_GetStringUTFChars,
4065 _Jv_JNI_ReleaseStringUTFChars,
4067 _Jv_JNI_GetArrayLength,
4069 _Jv_JNI_NewObjectArray,
4070 _Jv_JNI_GetObjectArrayElement,
4071 _Jv_JNI_SetObjectArrayElement,
4073 _Jv_JNI_NewBooleanArray,
4074 _Jv_JNI_NewByteArray,
4075 _Jv_JNI_NewCharArray,
4076 _Jv_JNI_NewShortArray,
4077 _Jv_JNI_NewIntArray,
4078 _Jv_JNI_NewLongArray,
4079 _Jv_JNI_NewFloatArray,
4080 _Jv_JNI_NewDoubleArray,
4082 _Jv_JNI_GetBooleanArrayElements,
4083 _Jv_JNI_GetByteArrayElements,
4084 _Jv_JNI_GetCharArrayElements,
4085 _Jv_JNI_GetShortArrayElements,
4086 _Jv_JNI_GetIntArrayElements,
4087 _Jv_JNI_GetLongArrayElements,
4088 _Jv_JNI_GetFloatArrayElements,
4089 _Jv_JNI_GetDoubleArrayElements,
4091 _Jv_JNI_ReleaseBooleanArrayElements,
4092 _Jv_JNI_ReleaseByteArrayElements,
4093 _Jv_JNI_ReleaseCharArrayElements,
4094 _Jv_JNI_ReleaseShortArrayElements,
4095 _Jv_JNI_ReleaseIntArrayElements,
4096 _Jv_JNI_ReleaseLongArrayElements,
4097 _Jv_JNI_ReleaseFloatArrayElements,
4098 _Jv_JNI_ReleaseDoubleArrayElements,
4100 _Jv_JNI_GetBooleanArrayRegion,
4101 _Jv_JNI_GetByteArrayRegion,
4102 _Jv_JNI_GetCharArrayRegion,
4103 _Jv_JNI_GetShortArrayRegion,
4104 _Jv_JNI_GetIntArrayRegion,
4105 _Jv_JNI_GetLongArrayRegion,
4106 _Jv_JNI_GetFloatArrayRegion,
4107 _Jv_JNI_GetDoubleArrayRegion,
4108 _Jv_JNI_SetBooleanArrayRegion,
4109 _Jv_JNI_SetByteArrayRegion,
4110 _Jv_JNI_SetCharArrayRegion,
4111 _Jv_JNI_SetShortArrayRegion,
4112 _Jv_JNI_SetIntArrayRegion,
4113 _Jv_JNI_SetLongArrayRegion,
4114 _Jv_JNI_SetFloatArrayRegion,
4115 _Jv_JNI_SetDoubleArrayRegion,
4117 jni_RegisterNatives,
4118 _Jv_JNI_UnregisterNatives,
4120 _Jv_JNI_MonitorEnter,
4121 _Jv_JNI_MonitorExit,
4125 /* New JNI 1.2 functions. */
4127 jni_GetStringRegion,
4128 jni_GetStringUTFRegion,
4130 jni_GetPrimitiveArrayCritical,
4131 jni_ReleasePrimitiveArrayCritical,
4133 _Jv_JNI_GetStringCritical,
4134 _Jv_JNI_ReleaseStringCritical,
4136 _Jv_JNI_NewWeakGlobalRef,
4137 _Jv_JNI_DeleteWeakGlobalRef,
4139 _Jv_JNI_ExceptionCheck,
4141 /* New JNI 1.4 functions. */
4143 jni_NewDirectByteBuffer,
4144 jni_GetDirectBufferAddress,
4145 jni_GetDirectBufferCapacity,
4147 /* New JNI 1.6 functions. */
4149 jni_GetObjectRefType
4153 /* Invocation API Functions ***************************************************/
4155 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4157 Returns a default configuration for the Java VM.
4159 *******************************************************************************/
4161 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4163 JavaVMInitArgs *_vm_args;
4165 _vm_args = (JavaVMInitArgs *) vm_args;
4167 /* GNU classpath currently supports JNI 1.2 */
4169 switch (_vm_args->version) {
4170 case JNI_VERSION_1_1:
4171 _vm_args->version = JNI_VERSION_1_1;
4174 case JNI_VERSION_1_2:
4175 case JNI_VERSION_1_4:
4176 _vm_args->ignoreUnrecognized = JNI_FALSE;
4177 _vm_args->options = NULL;
4178 _vm_args->nOptions = 0;
4181 case JNI_VERSION_CACAO:
4182 // We reveal ourselves by accepting this version number,
4183 // this actually means we are using the supported JNI version.
4184 _vm_args->version = JNI_VERSION_SUPPORTED;
4195 /* JNI_GetCreatedJavaVMs *******************************************************
4197 Returns all Java VMs that have been created. Pointers to VMs are written in
4198 the buffer vmBuf in the order they are created. At most bufLen number of
4199 entries will be written. The total number of created VMs is returned in
4202 *******************************************************************************/
4204 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4206 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4211 // We currently only support 1 VM running.
4213 vmBuf[0] = VM::get_current()->get_javavm();
4220 /* JNI_CreateJavaVM ************************************************************
4222 Loads and initializes a Java VM. The current thread becomes the main thread.
4223 Sets the env argument to the JNI interface pointer of the main thread.
4225 *******************************************************************************/
4227 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4229 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4231 /* actually create the JVM */
4233 if (!VM_create(p_vm, p_env, vm_args))
4243 * These are local overrides for various environment variables in Emacs.
4244 * Please do not remove this and leave it at the end of the file, where
4245 * Emacs will automagically detect them.
4246 * ---------------------------------------------------------------------
4249 * indent-tabs-mode: t
4253 * vim:noexpandtab:sw=4:ts=4: