1 /* src/native/jni.cpp - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/memory.h"
37 #include "native/jni.h"
38 #include "native/llni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
42 #if defined(ENABLE_JVMTI)
43 # include "native/jvmti/cacaodbg.h"
46 #include "threads/lock-common.h"
47 #include "threads/thread.hpp"
49 #include "toolbox/logging.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.hpp"
54 #include "vm/global.h"
55 #include "vm/initialize.h"
56 #include "vm/primitive.hpp"
57 #include "vm/resolve.h"
58 #include "vm/string.hpp"
61 #include "vm/jit/argument.h"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/jit.h"
64 #include "vm/jit/stacktrace.hpp"
66 #include "vmcore/globals.hpp"
67 #include "vmcore/javaobjects.hpp"
68 #include "vmcore/loader.h"
69 #include "vmcore/options.h"
70 #include "vmcore/statistics.h"
73 /* debug **********************************************************************/
77 # define TRACEJNICALLS(x) \
79 if (opt_TraceJNICalls) { \
84 # define TRACEJNICALLSENTER(x) \
86 if (opt_TraceJNICalls) { \
92 # define TRACEJNICALLSEXIT(x) \
94 if (opt_TraceJNICalls) { \
102 # define TRACEJNICALLS(x)
103 # define TRACEJNICALLSENTER(x)
104 # define TRACEJNICALLSEXIT(x)
109 /* global variables ***********************************************************/
111 /* global reference table *****************************************************/
113 /* hashsize must be power of 2 */
115 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
117 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
120 /* direct buffer stuff ********************************************************/
122 #if defined(ENABLE_JAVASE)
123 static classinfo *class_java_nio_Buffer;
125 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
127 static classinfo *class_java_nio_DirectByteBufferImpl;
128 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
130 # if SIZEOF_VOID_P == 8
131 static classinfo *class_gnu_classpath_Pointer64;
133 static classinfo *class_gnu_classpath_Pointer32;
136 static methodinfo *dbbirw_init;
138 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
140 static classinfo *class_sun_nio_ch_DirectBuffer;
141 static classinfo *class_java_nio_DirectByteBuffer;
143 static methodinfo *dbb_init;
149 /* some forward declarations **************************************************/
152 jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
156 /* jni_init ********************************************************************
158 Initialize the JNI subsystem.
160 *******************************************************************************/
164 TRACESUBSYSTEMINITIALIZATION("jni_init");
166 /* create global ref hashtable */
168 hashtable_global_ref = NEW(hashtable);
170 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
173 #if defined(ENABLE_JAVASE)
174 /* Direct buffer stuff. */
176 if (!(class_java_nio_Buffer =
177 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
178 !link_class(class_java_nio_Buffer))
181 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
183 if (!(class_java_nio_DirectByteBufferImpl =
184 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
185 !link_class(class_java_nio_DirectByteBufferImpl))
188 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
189 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
190 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
194 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
196 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
199 # if SIZEOF_VOID_P == 8
200 if (!(class_gnu_classpath_Pointer64 =
201 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
202 !link_class(class_gnu_classpath_Pointer64))
205 if (!(class_gnu_classpath_Pointer32 =
206 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
207 !link_class(class_gnu_classpath_Pointer32))
211 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
213 if (!(class_sun_nio_ch_DirectBuffer =
214 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
215 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
217 if (!link_class(class_sun_nio_ch_DirectBuffer))
218 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
220 if (!(class_java_nio_DirectByteBuffer =
221 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
222 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
224 if (!link_class(class_java_nio_DirectByteBuffer))
225 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
228 class_resolvemethod(class_java_nio_DirectByteBuffer,
230 utf_new_char("(JI)V"))))
231 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
235 #endif /* defined(ENABLE_JAVASE) */
241 /* jni_version_check ***********************************************************
243 Check if the given JNI version is supported.
246 version....JNI version to check
250 false......not supported
252 *******************************************************************************/
254 bool jni_version_check(int version)
257 case JNI_VERSION_1_1:
258 case JNI_VERSION_1_2:
259 case JNI_VERSION_1_4:
260 case JNI_VERSION_1_6:
268 /* _Jv_jni_CallObjectMethod ****************************************************
270 Internal function to call Java Object methods.
272 *******************************************************************************/
274 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
276 methodinfo *m, va_list ap)
281 STATISTICS(jniinvokation());
284 exceptions_throw_nullpointerexception();
288 /* Class initialization is done by the JIT compiler. This is ok
289 since a static method always belongs to the declaring class. */
291 if (m->flags & ACC_STATIC) {
292 /* For static methods we reset the object. */
297 /* for convenience */
302 /* For instance methods we make a virtual function table lookup. */
304 resm = method_vftbl_lookup(vftbl, m);
307 STATISTICS(jnicallXmethodnvokation());
309 ro = vm_call_method_valist(resm, o, ap);
315 /* _Jv_jni_CallObjectMethodA ***************************************************
317 Internal function to call Java Object methods.
319 *******************************************************************************/
321 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
329 STATISTICS(jniinvokation());
332 exceptions_throw_nullpointerexception();
336 /* Class initialization is done by the JIT compiler. This is ok
337 since a static method always belongs to the declaring class. */
339 if (m->flags & ACC_STATIC) {
340 /* For static methods we reset the object. */
345 /* for convenience */
350 /* For instance methods we make a virtual function table lookup. */
352 resm = method_vftbl_lookup(vftbl, m);
355 STATISTICS(jnicallXmethodnvokation());
357 ro = vm_call_method_jvalue(resm, o, args);
363 /* _Jv_jni_CallIntMethod *******************************************************
365 Internal function to call Java integer class methods (boolean,
366 byte, char, short, int).
368 *******************************************************************************/
370 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
371 methodinfo *m, va_list ap)
376 STATISTICS(jniinvokation());
379 exceptions_throw_nullpointerexception();
383 /* Class initialization is done by the JIT compiler. This is ok
384 since a static method always belongs to the declaring class. */
386 if (m->flags & ACC_STATIC) {
387 /* For static methods we reset the object. */
392 /* for convenience */
397 /* For instance methods we make a virtual function table lookup. */
399 resm = method_vftbl_lookup(vftbl, m);
402 STATISTICS(jnicallXmethodnvokation());
404 i = vm_call_method_int_valist(resm, o, ap);
410 /* _Jv_jni_CallIntMethodA ******************************************************
412 Internal function to call Java integer class methods (boolean,
413 byte, char, short, int).
415 *******************************************************************************/
417 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
418 methodinfo *m, const jvalue *args)
423 STATISTICS(jniinvokation());
426 exceptions_throw_nullpointerexception();
430 /* Class initialization is done by the JIT compiler. This is ok
431 since a static method always belongs to the declaring class. */
433 if (m->flags & ACC_STATIC) {
434 /* For static methods we reset the object. */
439 /* for convenience */
444 /* For instance methods we make a virtual function table lookup. */
446 resm = method_vftbl_lookup(vftbl, m);
449 STATISTICS(jnicallXmethodnvokation());
451 i = vm_call_method_int_jvalue(resm, o, args);
457 /* _Jv_jni_CallLongMethod ******************************************************
459 Internal function to call Java long methods.
461 *******************************************************************************/
463 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
464 methodinfo *m, va_list ap)
469 STATISTICS(jniinvokation());
472 exceptions_throw_nullpointerexception();
476 /* Class initialization is done by the JIT compiler. This is ok
477 since a static method always belongs to the declaring class. */
479 if (m->flags & ACC_STATIC) {
480 /* For static methods we reset the object. */
485 /* for convenience */
490 /* For instance methods we make a virtual function table lookup. */
492 resm = method_vftbl_lookup(vftbl, m);
495 STATISTICS(jnicallXmethodnvokation());
497 l = vm_call_method_long_valist(resm, o, ap);
503 /* _Jv_jni_CallLongMethodA *****************************************************
505 Internal function to call Java long methods.
507 *******************************************************************************/
509 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
510 methodinfo *m, const jvalue *args)
515 STATISTICS(jniinvokation());
518 exceptions_throw_nullpointerexception();
522 /* Class initialization is done by the JIT compiler. This is ok
523 since a static method always belongs to the declaring class. */
525 if (m->flags & ACC_STATIC) {
526 /* For static methods we reset the object. */
531 /* for convenience */
536 /* For instance methods we make a virtual function table lookup. */
538 resm = method_vftbl_lookup(vftbl, m);
541 STATISTICS(jnicallXmethodnvokation());
543 l = vm_call_method_long_jvalue(resm, o, args);
549 /* _Jv_jni_CallFloatMethod *****************************************************
551 Internal function to call Java float methods.
553 *******************************************************************************/
555 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
556 methodinfo *m, va_list ap)
561 /* Class initialization is done by the JIT compiler. This is ok
562 since a static method always belongs to the declaring class. */
564 if (m->flags & ACC_STATIC) {
565 /* For static methods we reset the object. */
570 /* for convenience */
575 /* For instance methods we make a virtual function table lookup. */
577 resm = method_vftbl_lookup(vftbl, m);
580 STATISTICS(jnicallXmethodnvokation());
582 f = vm_call_method_float_valist(resm, o, ap);
588 /* _Jv_jni_CallFloatMethodA ****************************************************
590 Internal function to call Java float methods.
592 *******************************************************************************/
594 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
595 methodinfo *m, const jvalue *args)
600 /* Class initialization is done by the JIT compiler. This is ok
601 since a static method always belongs to the declaring class. */
603 if (m->flags & ACC_STATIC) {
604 /* For static methods we reset the object. */
609 /* for convenience */
614 /* For instance methods we make a virtual function table lookup. */
616 resm = method_vftbl_lookup(vftbl, m);
619 STATISTICS(jnicallXmethodnvokation());
621 f = vm_call_method_float_jvalue(resm, o, args);
627 /* _Jv_jni_CallDoubleMethod ****************************************************
629 Internal function to call Java double methods.
631 *******************************************************************************/
633 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
634 methodinfo *m, va_list ap)
639 /* Class initialization is done by the JIT compiler. This is ok
640 since a static method always belongs to the declaring class. */
642 if (m->flags & ACC_STATIC) {
643 /* For static methods we reset the object. */
648 /* for convenience */
653 /* For instance methods we make a virtual function table lookup. */
655 resm = method_vftbl_lookup(vftbl, m);
658 d = vm_call_method_double_valist(resm, o, ap);
664 /* _Jv_jni_CallDoubleMethodA ***************************************************
666 Internal function to call Java double methods.
668 *******************************************************************************/
670 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
671 methodinfo *m, const jvalue *args)
676 /* Class initialization is done by the JIT compiler. This is ok
677 since a static method always belongs to the declaring class. */
679 if (m->flags & ACC_STATIC) {
680 /* For static methods we reset the object. */
685 /* for convenience */
690 /* For instance methods we make a virtual function table lookup. */
692 resm = method_vftbl_lookup(vftbl, m);
695 d = vm_call_method_double_jvalue(resm, o, args);
701 /* _Jv_jni_CallVoidMethod ******************************************************
703 Internal function to call Java void methods.
705 *******************************************************************************/
707 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
708 methodinfo *m, va_list ap)
713 exceptions_throw_nullpointerexception();
717 /* Class initialization is done by the JIT compiler. This is ok
718 since a static method always belongs to the declaring class. */
720 if (m->flags & ACC_STATIC) {
721 /* For static methods we reset the object. */
726 /* for convenience */
731 /* For instance methods we make a virtual function table lookup. */
733 resm = method_vftbl_lookup(vftbl, m);
736 STATISTICS(jnicallXmethodnvokation());
738 (void) vm_call_method_valist(resm, o, ap);
742 /* _Jv_jni_CallVoidMethodA *****************************************************
744 Internal function to call Java void methods.
746 *******************************************************************************/
748 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
749 methodinfo *m, const jvalue *args)
754 exceptions_throw_nullpointerexception();
758 /* Class initialization is done by the JIT compiler. This is ok
759 since a static method always belongs to the declaring class. */
761 if (m->flags & ACC_STATIC) {
762 /* For static methods we reset the object. */
767 /* for convenience */
772 /* For instance methods we make a virtual function table lookup. */
774 resm = method_vftbl_lookup(vftbl, m);
777 STATISTICS(jnicallXmethodnvokation());
779 (void) vm_call_method_jvalue(resm, o, args);
783 // JNI functions are exported as C functions.
786 /* GetVersion ******************************************************************
788 Returns the major version number in the higher 16 bits and the
789 minor version number in the lower 16 bits.
791 *******************************************************************************/
793 jint _Jv_JNI_GetVersion(JNIEnv *env)
795 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
797 /* We support JNI 1.6. */
799 return JNI_VERSION_1_6;
803 /* Class Operations ***********************************************************/
805 /* DefineClass *****************************************************************
807 Loads a class from a buffer of raw class data. The buffer
808 containing the raw class data is not referenced by the VM after the
809 DefineClass call returns, and it may be discarded if desired.
811 *******************************************************************************/
813 jclass jni_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
815 #if defined(ENABLE_JAVASE)
821 TRACEJNICALLS(("jni_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
823 u = utf_new_char(name);
824 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
826 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
828 h = LLNI_classinfo_wrap(c);
830 return (jclass) jni_NewLocalRef(env, (jobject) h);
832 vm_abort("jni_DefineClass: Not implemented in this configuration");
834 // Keep compiler happy.
841 /* FindClass *******************************************************************
843 This function loads a locally-defined class. It searches the
844 directories and zip files specified by the CLASSPATH environment
845 variable for the class with the specified name.
847 *******************************************************************************/
849 jclass jni_FindClass(JNIEnv *env, const char *name)
851 #if defined(ENABLE_JAVASE)
858 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
860 /* FIXME If name is NULL we have a problem here. */
862 u = utf_new_char_classname((char *) name);
864 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
865 exceptions_throw_noclassdeffounderror(u);
869 /* Check stacktrace for classloader, if one found use it,
870 otherwise use the system classloader. */
872 /* Quote from the JNI documentation:
874 In the Java 2 Platform, FindClass locates the class loader
875 associated with the current native method. If the native code
876 belongs to a system class, no class loader will be
877 involved. Otherwise, the proper class loader will be invoked to
878 load and link the named class. When FindClass is called through
879 the Invocation Interface, there is no current native method or
880 its associated class loader. In that case, the result of
881 ClassLoader.getBaseClassLoader is used." */
883 cc = stacktrace_get_current_class();
886 c = load_class_from_sysloader(u);
888 c = load_class_from_classloader(u, cc->classloader);
891 resolve_handle_pending_exception(true);
898 h = LLNI_classinfo_wrap(c);
900 return (jclass) jni_NewLocalRef(env, (jobject) h);
902 #elif defined(ENABLE_JAVAME_CLDC1_1)
907 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
909 u = utf_new_char_classname((char *) name);
910 c = load_class_bootstrap(u);
913 resolve_handle_pending_exception(true);
920 return (jclass) jni_NewLocalRef(env, (jobject) c);
923 vm_abort("jni_FindClass: not implemented in this configuration");
925 /* keep compiler happy */
932 /* GetSuperclass ***************************************************************
934 If clazz represents any class other than the class Object, then
935 this function returns the object that represents the superclass of
936 the class specified by clazz.
938 *******************************************************************************/
940 jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
945 TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
947 c = LLNI_classinfo_unwrap(sub);
952 super = class_get_superclass(c);
954 java_handle_t* h = LLNI_classinfo_wrap(super);
956 return (jclass) jni_NewLocalRef(env, (jobject) h);
960 /* IsAssignableFrom ************************************************************
962 Determines whether an object of sub can be safely cast to sup.
964 *******************************************************************************/
966 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
971 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
973 to = (classinfo *) sup;
974 from = (classinfo *) sub;
976 return class_is_assignable_from(to, from);
980 /* Throw ***********************************************************************
982 Causes a java.lang.Throwable object to be thrown.
984 *******************************************************************************/
986 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
990 STATISTICS(jniinvokation());
992 o = (java_handle_t *) obj;
994 exceptions_set_exception(o);
1000 /* ThrowNew ********************************************************************
1002 Constructs an exception object from the specified class with the
1003 message specified by message and causes that exception to be
1006 *******************************************************************************/
1008 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1014 STATISTICS(jniinvokation());
1016 c = LLNI_classinfo_unwrap(clazz);
1019 s = javastring_new_from_utf_string(msg);
1021 /* instantiate exception object */
1023 o = native_new_and_init_string(c, s);
1028 exceptions_set_exception(o);
1034 /* ExceptionOccurred ***********************************************************
1036 Determines if an exception is being thrown. The exception stays
1037 being thrown until either the native code calls ExceptionClear(),
1038 or the Java code handles the exception.
1040 *******************************************************************************/
1042 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1046 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1048 o = exceptions_get_exception();
1050 return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1054 /* ExceptionDescribe ***********************************************************
1056 Prints an exception and a backtrace of the stack to a system
1057 error-reporting channel, such as stderr. This is a convenience
1058 routine provided for debugging.
1060 *******************************************************************************/
1062 void jni_ExceptionDescribe(JNIEnv *env)
1064 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1066 exceptions_print_stacktrace();
1070 /* ExceptionClear **************************************************************
1072 Clears any exception that is currently being thrown. If no
1073 exception is currently being thrown, this routine has no effect.
1075 *******************************************************************************/
1077 void jni_ExceptionClear(JNIEnv *env)
1079 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1081 exceptions_clear_exception();
1085 /* FatalError ******************************************************************
1087 Raises a fatal error and does not expect the VM to recover. This
1088 function does not return.
1090 *******************************************************************************/
1092 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1094 STATISTICS(jniinvokation());
1096 /* this seems to be the best way */
1098 vm_abort("JNI Fatal error: %s", msg);
1102 /* PushLocalFrame **************************************************************
1104 Creates a new local reference frame, in which at least a given
1105 number of local references can be created.
1107 *******************************************************************************/
1109 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1111 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1116 /* add new local reference frame to current table */
1118 if (!localref_frame_push(capacity))
1125 /* PopLocalFrame ***************************************************************
1127 Pops off the current local reference frame, frees all the local
1128 references, and returns a local reference in the previous local
1129 reference frame for the given result object.
1131 *******************************************************************************/
1133 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1135 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1137 /* release all current local frames */
1139 localref_frame_pop_all();
1141 /* add local reference and return the value */
1143 return jni_NewLocalRef(env, result);
1147 /* DeleteLocalRef **************************************************************
1149 Deletes the local reference pointed to by localRef.
1151 *******************************************************************************/
1153 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1157 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1159 o = (java_handle_t *) localRef;
1164 /* delete the reference */
1170 /* IsSameObject ****************************************************************
1172 Tests whether two references refer to the same Java object.
1174 *******************************************************************************/
1176 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1182 STATISTICS(jniinvokation());
1184 o1 = (java_handle_t *) ref1;
1185 o2 = (java_handle_t *) ref2;
1187 LLNI_CRITICAL_START;
1189 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1200 /* NewLocalRef *****************************************************************
1202 Creates a new local reference that refers to the same object as ref.
1204 *******************************************************************************/
1206 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1209 java_handle_t *localref;
1211 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1213 o = (java_handle_t *) ref;
1218 /* insert the reference */
1220 localref = localref_add(LLNI_DIRECT(o));
1222 return (jobject) localref;
1226 /* EnsureLocalCapacity *********************************************************
1228 Ensures that at least a given number of local references can be
1229 created in the current thread
1231 *******************************************************************************/
1233 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1235 localref_table *lrt;
1237 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1239 /* get local reference table (thread specific) */
1241 lrt = LOCALREFTABLE;
1243 /* check if capacity elements are available in the local references table */
1245 if ((lrt->used + capacity) > lrt->capacity)
1246 return jni_PushLocalFrame(env, capacity);
1252 /* AllocObject *****************************************************************
1254 Allocates a new Java object without invoking any of the
1255 constructors for the object. Returns a reference to the object.
1257 *******************************************************************************/
1259 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1264 STATISTICS(jniinvokation());
1266 c = LLNI_classinfo_unwrap(clazz);
1268 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1269 exceptions_throw_instantiationexception(c);
1275 return jni_NewLocalRef(env, (jobject) o);
1279 /* NewObject *******************************************************************
1281 Programmers place all arguments that are to be passed to the
1282 constructor immediately following the methodID
1283 argument. NewObject() accepts these arguments and passes them to
1284 the Java method that the programmer wishes to invoke.
1286 *******************************************************************************/
1288 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1295 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1297 c = LLNI_classinfo_unwrap(clazz);
1298 m = (methodinfo *) methodID;
1307 /* call constructor */
1309 va_start(ap, methodID);
1310 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1313 TRACEJNICALLSEXIT(("->%p", o));
1315 return jni_NewLocalRef(env, (jobject) o);
1319 /* NewObjectV ******************************************************************
1321 Programmers place all arguments that are to be passed to the
1322 constructor in an args argument of type va_list that immediately
1323 follows the methodID argument. NewObjectV() accepts these
1324 arguments, and, in turn, passes them to the Java method that the
1325 programmer wishes to invoke.
1327 *******************************************************************************/
1329 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1336 STATISTICS(jniinvokation());
1338 c = LLNI_classinfo_unwrap(clazz);
1339 m = (methodinfo *) methodID;
1348 /* call constructor */
1350 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1352 return jni_NewLocalRef(env, (jobject) o);
1356 /* NewObjectA *****************************************************************
1358 Programmers place all arguments that are to be passed to the
1359 constructor in an args array of jvalues that immediately follows
1360 the methodID argument. NewObjectA() accepts the arguments in this
1361 array, and, in turn, passes them to the Java method that the
1362 programmer wishes to invoke.
1364 *******************************************************************************/
1366 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1373 STATISTICS(jniinvokation());
1375 c = LLNI_classinfo_unwrap(clazz);
1376 m = (methodinfo *) methodID;
1385 /* call constructor */
1387 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1389 return jni_NewLocalRef(env, (jobject) o);
1393 /* GetObjectClass **************************************************************
1395 Returns the class of an object.
1397 *******************************************************************************/
1399 jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
1404 TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
1406 o = (java_handle_t *) obj;
1408 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1411 LLNI_class_get(o, c);
1413 java_handle_t* h = LLNI_classinfo_wrap(c);
1415 return (jclass) jni_NewLocalRef(env, (jobject) h);
1419 /* IsInstanceOf ****************************************************************
1421 Tests whether an object is an instance of a class.
1423 *******************************************************************************/
1425 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1430 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1432 /* XXX Is this correct? */
1433 c = LLNI_classinfo_unwrap(clazz);
1434 h = (java_handle_t *) obj;
1436 return class_is_instance(c, h);
1440 /* Reflection Support *********************************************************/
1442 /* FromReflectedMethod *********************************************************
1444 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1445 object to a method ID.
1447 *******************************************************************************/
1449 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1451 #if defined(ENABLE_JAVASE)
1455 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1457 o = (java_handle_t *) method;
1462 // FIXME We can't access the object here directly.
1463 if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
1464 java_lang_reflect_Constructor rc(method);
1466 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1467 java_lang_reflect_VMConstructor rvmc(rc.get_cons());
1468 m = rvmc.get_method();
1470 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1472 LLNI_field_get_cls(rc, clazz, c);
1473 LLNI_field_get_val(rc, slot , slot);
1476 # error unknown configuration
1480 // FIXME We can't access the object here directly.
1481 assert(o->vftbl->clazz == class_java_lang_reflect_Method);
1483 java_lang_reflect_Method rm(method);
1485 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1487 java_lang_reflect_VMMethod rvmm(rm.get_m());
1488 m = rvmm.get_method();
1489 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1491 LLNI_field_get_cls(rm, clazz, c);
1492 LLNI_field_get_val(rm, slot , slot);
1495 # error unknown configuration
1499 return (jmethodID) m;
1501 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1503 /* Keep compiler happy. */
1510 /* FromReflectedField **********************************************************
1512 Converts a java.lang.reflect.Field to a field ID.
1514 *******************************************************************************/
1516 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1518 #if defined(ENABLE_JAVASE)
1520 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1523 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1528 java_lang_reflect_Field rf(field);
1530 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1532 java_lang_reflect_VMField rvmf(rf.get_f());
1533 fieldinfo* f = rvmf.get_field();
1535 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1537 LLNI_field_get_cls(rf, clazz, c);
1538 LLNI_field_get_val(rf, slot , slot);
1541 # error unknown configuration
1544 return (jfieldID) f;
1546 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1548 /* Keep compiler happy. */
1555 /* ToReflectedMethod ***********************************************************
1557 Converts a method ID derived from cls to an instance of the
1558 java.lang.reflect.Method class or to an instance of the
1559 java.lang.reflect.Constructor class.
1561 *******************************************************************************/
1563 jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1565 #if defined(ENABLE_JAVASE)
1566 TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1568 methodinfo* m = (methodinfo *) methodID;
1570 /* HotSpot does the same assert. */
1572 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1576 if (m->name == utf_init) {
1577 h = java_lang_reflect_Constructor::create(m);
1580 h = java_lang_reflect_Method::create(m);
1585 vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
1587 /* keep compiler happy */
1594 /* ToReflectedField ************************************************************
1596 Converts a field ID derived from cls to an instance of the
1597 java.lang.reflect.Field class.
1599 *******************************************************************************/
1601 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1604 STATISTICS(jniinvokation());
1606 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1612 /* Calling Instance Methods ***************************************************/
1614 /* GetMethodID *****************************************************************
1616 Returns the method ID for an instance (nonstatic) method of a class
1617 or interface. The method may be defined in one of the clazz's
1618 superclasses and inherited by clazz. The method is determined by
1619 its name and signature.
1621 GetMethodID() causes an uninitialized class to be initialized.
1623 *******************************************************************************/
1625 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1633 STATISTICS(jniinvokation());
1635 c = LLNI_classinfo_unwrap(clazz);
1640 if (!(c->state & CLASS_INITIALIZED))
1641 if (!initialize_class(c))
1644 /* try to get the method of the class or one of it's superclasses */
1646 uname = utf_new_char((char *) name);
1647 udesc = utf_new_char((char *) sig);
1649 m = class_resolvemethod(c, uname, udesc);
1651 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1652 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1657 return (jmethodID) m;
1661 /* JNI-functions for calling instance methods *********************************/
1663 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1664 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1665 jmethodID methodID, ...) \
1672 o = (java_handle_t *) obj; \
1673 m = (methodinfo *) methodID; \
1675 va_start(ap, methodID); \
1676 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1682 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1683 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1684 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1685 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1686 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1687 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1688 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1689 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1692 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1693 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1694 jmethodID methodID, va_list args) \
1700 o = (java_handle_t *) obj; \
1701 m = (methodinfo *) methodID; \
1703 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1708 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1709 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1710 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1711 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1712 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1713 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1714 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1715 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1718 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1719 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1720 jmethodID methodID, \
1721 const jvalue *args) \
1727 o = (java_handle_t *) obj; \
1728 m = (methodinfo *) methodID; \
1730 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1735 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1736 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1737 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1738 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1739 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1740 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1741 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1742 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1745 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1753 o = (java_handle_t *) obj;
1754 m = (methodinfo *) methodID;
1756 va_start(ap, methodID);
1757 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1760 return jni_NewLocalRef(env, (jobject) ret);
1764 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1771 o = (java_handle_t *) obj;
1772 m = (methodinfo *) methodID;
1774 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1776 return jni_NewLocalRef(env, (jobject) ret);
1780 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1787 o = (java_handle_t *) obj;
1788 m = (methodinfo *) methodID;
1790 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1792 return jni_NewLocalRef(env, (jobject) ret);
1797 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1803 o = (java_handle_t *) obj;
1804 m = (methodinfo *) methodID;
1806 va_start(ap, methodID);
1807 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1812 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1818 o = (java_handle_t *) obj;
1819 m = (methodinfo *) methodID;
1821 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1825 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1831 o = (java_handle_t *) obj;
1832 m = (methodinfo *) methodID;
1834 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1839 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1840 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1841 jclass clazz, jmethodID methodID, \
1850 o = (java_handle_t *) obj; \
1851 c = LLNI_classinfo_unwrap(clazz); \
1852 m = (methodinfo *) methodID; \
1854 va_start(ap, methodID); \
1855 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1861 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1862 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1863 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1864 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1865 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1866 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1867 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1868 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1871 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1872 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1873 jclass clazz, jmethodID methodID, \
1881 o = (java_handle_t *) obj; \
1882 c = LLNI_classinfo_unwrap(clazz); \
1883 m = (methodinfo *) methodID; \
1885 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1890 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1891 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1892 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1893 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1894 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1895 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1896 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1897 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1900 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1901 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1902 jclass clazz, jmethodID methodID, \
1903 const jvalue *args) \
1905 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1910 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1911 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1912 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1913 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1914 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1915 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1916 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1917 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1919 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1920 jclass clazz, jmethodID methodID,
1929 o = (java_handle_t *) obj;
1930 c = LLNI_classinfo_unwrap(clazz);
1931 m = (methodinfo *) methodID;
1933 va_start(ap, methodID);
1934 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1937 return jni_NewLocalRef(env, (jobject) r);
1941 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1942 jclass clazz, jmethodID methodID,
1950 o = (java_handle_t *) obj;
1951 c = LLNI_classinfo_unwrap(clazz);
1952 m = (methodinfo *) methodID;
1954 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1956 return jni_NewLocalRef(env, (jobject) r);
1960 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1961 jclass clazz, jmethodID methodID,
1964 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1966 return jni_NewLocalRef(env, NULL);
1970 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1971 jmethodID methodID, ...)
1978 o = (java_handle_t *) obj;
1979 c = LLNI_classinfo_unwrap(clazz);
1980 m = (methodinfo *) methodID;
1982 va_start(ap, methodID);
1983 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1988 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1989 jmethodID methodID, va_list args)
1995 o = (java_handle_t *) obj;
1996 c = LLNI_classinfo_unwrap(clazz);
1997 m = (methodinfo *) methodID;
1999 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2003 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2004 jmethodID methodID, const jvalue * args)
2010 o = (java_handle_t *) obj;
2011 c = LLNI_classinfo_unwrap(clazz);
2012 m = (methodinfo *) methodID;
2014 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2018 /* Accessing Fields of Objects ************************************************/
2020 /* GetFieldID ******************************************************************
2022 Returns the field ID for an instance (nonstatic) field of a
2023 class. The field is specified by its name and signature. The
2024 Get<type>Field and Set<type>Field families of accessor functions
2025 use field IDs to retrieve object fields.
2027 *******************************************************************************/
2029 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2037 STATISTICS(jniinvokation());
2039 c = LLNI_classinfo_unwrap(clazz);
2041 /* XXX NPE check? */
2043 uname = utf_new_char((char *) name);
2044 udesc = utf_new_char((char *) sig);
2046 f = class_findfield(c, uname, udesc);
2049 exceptions_throw_nosuchfielderror(c, uname);
2051 return (jfieldID) f;
2055 /* Get<type>Field Routines *****************************************************
2057 This family of accessor routines returns the value of an instance
2058 (nonstatic) field of an object. The field to access is specified by
2059 a field ID obtained by calling GetFieldID().
2061 *******************************************************************************/
2063 #define GET_FIELD(o,type,f) \
2064 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2066 #define JNI_GET_FIELD(name, type, intern) \
2067 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2071 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2073 LLNI_CRITICAL_START; \
2075 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2077 LLNI_CRITICAL_END; \
2079 return (type) ret; \
2082 JNI_GET_FIELD(Boolean, jboolean, s4)
2083 JNI_GET_FIELD(Byte, jbyte, s4)
2084 JNI_GET_FIELD(Char, jchar, s4)
2085 JNI_GET_FIELD(Short, jshort, s4)
2086 JNI_GET_FIELD(Int, jint, s4)
2087 JNI_GET_FIELD(Long, jlong, s8)
2088 JNI_GET_FIELD(Float, jfloat, float)
2089 JNI_GET_FIELD(Double, jdouble, double)
2092 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2096 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2098 LLNI_CRITICAL_START;
2100 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2104 return jni_NewLocalRef(env, (jobject) o);
2108 /* Set<type>Field Routines *****************************************************
2110 This family of accessor routines sets the value of an instance
2111 (nonstatic) field of an object. The field to access is specified by
2112 a field ID obtained by calling GetFieldID().
2114 *******************************************************************************/
2116 #define SET_FIELD(o,type,f,value) \
2117 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2119 #define JNI_SET_FIELD(name, type, intern) \
2120 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2123 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2125 LLNI_CRITICAL_START; \
2127 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2129 LLNI_CRITICAL_START; \
2132 JNI_SET_FIELD(Boolean, jboolean, s4)
2133 JNI_SET_FIELD(Byte, jbyte, s4)
2134 JNI_SET_FIELD(Char, jchar, s4)
2135 JNI_SET_FIELD(Short, jshort, s4)
2136 JNI_SET_FIELD(Int, jint, s4)
2137 JNI_SET_FIELD(Long, jlong, s8)
2138 JNI_SET_FIELD(Float, jfloat, float)
2139 JNI_SET_FIELD(Double, jdouble, double)
2142 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2145 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2147 LLNI_CRITICAL_START;
2149 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2155 /* Calling Static Methods *****************************************************/
2157 /* GetStaticMethodID ***********************************************************
2159 Returns the method ID for a static method of a class. The method is
2160 specified by its name and signature.
2162 GetStaticMethodID() causes an uninitialized class to be
2165 *******************************************************************************/
2167 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2175 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2177 c = LLNI_classinfo_unwrap(clazz);
2182 if (!(c->state & CLASS_INITIALIZED))
2183 if (!initialize_class(c))
2186 /* try to get the static method of the class */
2188 uname = utf_new_char((char *) name);
2189 udesc = utf_new_char((char *) sig);
2191 m = class_resolvemethod(c, uname, udesc);
2193 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2194 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2199 return (jmethodID) m;
2203 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2204 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2205 jmethodID methodID, ...) \
2211 m = (methodinfo *) methodID; \
2213 va_start(ap, methodID); \
2214 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2220 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2221 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2222 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2223 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2224 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2225 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2226 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2227 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2230 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2231 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2232 jmethodID methodID, va_list args) \
2237 m = (methodinfo *) methodID; \
2239 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2244 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2245 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2246 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2247 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2248 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2249 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2250 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2251 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2254 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2255 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2256 jmethodID methodID, const jvalue *args) \
2261 m = (methodinfo *) methodID; \
2263 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2268 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2269 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2270 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2271 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2272 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2273 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2274 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2275 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2278 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2279 jmethodID methodID, ...)
2285 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2287 m = (methodinfo *) methodID;
2289 va_start(ap, methodID);
2290 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2293 return jni_NewLocalRef(env, (jobject) o);
2297 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2298 jmethodID methodID, va_list args)
2303 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2305 m = (methodinfo *) methodID;
2307 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2309 return jni_NewLocalRef(env, (jobject) o);
2313 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2314 jmethodID methodID, const jvalue *args)
2319 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2321 m = (methodinfo *) methodID;
2323 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2325 return jni_NewLocalRef(env, (jobject) o);
2329 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2330 jmethodID methodID, ...)
2335 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2337 m = (methodinfo *) methodID;
2339 va_start(ap, methodID);
2340 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2345 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2346 jmethodID methodID, va_list args)
2350 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2352 m = (methodinfo *) methodID;
2354 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2358 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2359 jmethodID methodID, const jvalue * args)
2363 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2365 m = (methodinfo *) methodID;
2367 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2371 /* Accessing Static Fields ****************************************************/
2373 /* GetStaticFieldID ************************************************************
2375 Returns the field ID for a static field of a class. The field is
2376 specified by its name and signature. The GetStatic<type>Field and
2377 SetStatic<type>Field families of accessor functions use field IDs
2378 to retrieve static fields.
2380 *******************************************************************************/
2382 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2390 STATISTICS(jniinvokation());
2392 c = LLNI_classinfo_unwrap(clazz);
2394 uname = utf_new_char((char *) name);
2395 usig = utf_new_char((char *) sig);
2397 f = class_findfield(c, uname, usig);
2400 exceptions_throw_nosuchfielderror(c, uname);
2402 return (jfieldID) f;
2406 /* GetStatic<type>Field ********************************************************
2408 This family of accessor routines returns the value of a static
2411 *******************************************************************************/
2413 #define JNI_GET_STATIC_FIELD(name, type, field) \
2414 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2420 STATISTICS(jniinvokation()); \
2422 c = LLNI_classinfo_unwrap(clazz); \
2423 f = (fieldinfo *) fieldID; \
2425 if (!(c->state & CLASS_INITIALIZED)) \
2426 if (!initialize_class(c)) \
2429 return f->value->field; \
2432 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2433 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2434 JNI_GET_STATIC_FIELD(Char, jchar, i)
2435 JNI_GET_STATIC_FIELD(Short, jshort, i)
2436 JNI_GET_STATIC_FIELD(Int, jint, i)
2437 JNI_GET_STATIC_FIELD(Long, jlong, l)
2438 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2439 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2442 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2449 STATISTICS(jniinvokation());
2451 c = LLNI_classinfo_unwrap(clazz);
2452 f = (fieldinfo *) fieldID;
2454 if (!(c->state & CLASS_INITIALIZED))
2455 if (!initialize_class(c))
2458 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2460 return jni_NewLocalRef(env, (jobject) h);
2464 /* SetStatic<type>Field *******************************************************
2466 This family of accessor routines sets the value of a static field
2469 *******************************************************************************/
2471 #define JNI_SET_STATIC_FIELD(name, type, field) \
2472 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2479 STATISTICS(jniinvokation()); \
2481 c = LLNI_classinfo_unwrap(clazz); \
2482 f = (fieldinfo *) fieldID; \
2484 if (!(c->state & CLASS_INITIALIZED)) \
2485 if (!initialize_class(c)) \
2488 f->value->field = value; \
2491 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2492 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2493 JNI_SET_STATIC_FIELD(Char, jchar, i)
2494 JNI_SET_STATIC_FIELD(Short, jshort, i)
2495 JNI_SET_STATIC_FIELD(Int, jint, i)
2496 JNI_SET_STATIC_FIELD(Long, jlong, l)
2497 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2498 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2501 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2507 STATISTICS(jniinvokation());
2509 c = LLNI_classinfo_unwrap(clazz);
2510 f = (fieldinfo *) fieldID;
2512 if (!(c->state & CLASS_INITIALIZED))
2513 if (!initialize_class(c))
2516 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2520 /* String Operations **********************************************************/
2522 /* NewString *******************************************************************
2524 Create new java.lang.String object from an array of Unicode
2527 *******************************************************************************/
2529 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
2531 TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
2533 java_handle_chararray_t* a = builtin_newarray_char(len);
2539 for (jsize i = 0; i < len; i++)
2540 LLNI_array_direct(a, i) = buf[i];
2542 java_handle_t* h = builtin_new(class_java_lang_String);
2547 java_lang_String s(h, a, len, 0);
2549 return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
2553 static jchar emptyStringJ[]={0,0};
2555 /* GetStringLength *************************************************************
2557 Returns the length (the count of Unicode characters) of a Java
2560 *******************************************************************************/
2562 jsize jni_GetStringLength(JNIEnv *env, jstring str)
2564 TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
2566 java_lang_String s(str);
2567 jsize count = s.get_count();
2569 TRACEJNICALLSEXIT(("->%d)", count));
2575 /* GetStringChars **************************************************************
2577 Returns a pointer to the array of Unicode characters of the
2578 string. This pointer is valid until ReleaseStringChars() is called.
2580 *******************************************************************************/
2582 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2587 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2590 // FIXME This is really ugly.
2591 return emptyStringJ;
2593 java_lang_String s(str);
2595 java_handle_chararray_t* ca = s.get_value();
2596 int32_t count = s.get_count();
2597 int32_t offset = s.get_offset();
2602 /* allocate memory */
2604 stringbuffer = MNEW(u2, count + 1);
2608 for (i = 0; i < count; i++)
2609 stringbuffer[i] = LLNI_array_direct(ca, offset + i);
2611 /* terminate string */
2613 stringbuffer[i] = '\0';
2618 return (jchar*) stringbuffer;
2622 /* ReleaseStringChars **********************************************************
2624 Informs the VM that the native code no longer needs access to
2625 chars. The chars argument is a pointer obtained from string using
2628 *******************************************************************************/
2630 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2632 TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
2635 if (chars == emptyStringJ)
2638 java_lang_String s(str);
2639 int32_t count = s.get_count();
2641 MFREE(((jchar*) chars), jchar, count + 1);
2645 /* NewStringUTF ****************************************************************
2647 Constructs a new java.lang.String object from an array of UTF-8
2650 *******************************************************************************/
2652 jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
2654 TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2656 java_handle_t *h = javastring_safe_new_from_utf8(bytes);
2658 return (jstring) jni_NewLocalRef(env, (jobject) h);
2662 /****************** returns the utf8 length in bytes of a string *******************/
2664 jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
2666 TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
2668 java_lang_String s(string);
2669 java_handle_chararray_t* ca = s.get_value();
2670 int32_t count = s.get_count();
2672 // FIXME GC critical section!
2673 int32_t length = u2_utflength(ca->data, count);
2679 /* GetStringUTFChars ***********************************************************
2681 Returns a pointer to an array of UTF-8 characters of the
2682 string. This array is valid until it is released by
2683 ReleaseStringUTFChars().
2685 *******************************************************************************/
2687 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2692 STATISTICS(jniinvokation());
2700 u = javastring_toutf((java_handle_t *) string, false);
2709 /* ReleaseStringUTFChars *******************************************************
2711 Informs the VM that the native code no longer needs access to
2712 utf. The utf argument is a pointer derived from string using
2713 GetStringUTFChars().
2715 *******************************************************************************/
2717 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2719 STATISTICS(jniinvokation());
2721 /* XXX we don't release utf chars right now, perhaps that should be done
2722 later. Since there is always one reference the garbage collector will
2727 /* Array Operations ***********************************************************/
2729 /* GetArrayLength **************************************************************
2731 Returns the number of elements in the array.
2733 *******************************************************************************/
2735 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2740 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2742 a = (java_handle_t *) array;
2744 size = LLNI_array_size(a);
2750 /* NewObjectArray **************************************************************
2752 Constructs a new array holding objects in class elementClass. All
2753 elements are initially set to initialElement.
2755 *******************************************************************************/
2757 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2758 jclass elementClass, jobject initialElement)
2762 java_handle_objectarray_t *oa;
2765 STATISTICS(jniinvokation());
2767 c = LLNI_classinfo_unwrap(elementClass);
2768 o = (java_handle_t *) initialElement;
2771 exceptions_throw_negativearraysizeexception();
2775 oa = builtin_anewarray(length, c);
2780 /* set all elements to initialElement */
2782 for (i = 0; i < length; i++)
2783 array_objectarray_element_set(oa, i, o);
2785 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2789 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2792 java_handle_objectarray_t *oa;
2795 STATISTICS(jniinvokation());
2797 oa = (java_handle_objectarray_t *) array;
2799 if (index >= LLNI_array_size(oa)) {
2800 exceptions_throw_arrayindexoutofboundsexception();
2804 o = array_objectarray_element_get(oa, index);
2806 return jni_NewLocalRef(env, (jobject) o);
2810 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2811 jsize index, jobject val)
2813 java_handle_objectarray_t *oa;
2816 STATISTICS(jniinvokation());
2818 oa = (java_handle_objectarray_t *) array;
2819 o = (java_handle_t *) val;
2821 if (index >= LLNI_array_size(oa)) {
2822 exceptions_throw_arrayindexoutofboundsexception();
2826 /* check if the class of value is a subclass of the element class
2829 if (!builtin_canstore(oa, o))
2832 array_objectarray_element_set(oa, index, o);
2836 #define JNI_NEW_ARRAY(name, type, intern) \
2837 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2839 java_handle_##intern##array_t *a; \
2841 STATISTICS(jniinvokation()); \
2844 exceptions_throw_negativearraysizeexception(); \
2848 a = builtin_newarray_##intern(len); \
2850 return (type) jni_NewLocalRef(env, (jobject) a); \
2853 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2854 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2855 JNI_NEW_ARRAY(Char, jcharArray, char)
2856 JNI_NEW_ARRAY(Short, jshortArray, short)
2857 JNI_NEW_ARRAY(Int, jintArray, int)
2858 JNI_NEW_ARRAY(Long, jlongArray, long)
2859 JNI_NEW_ARRAY(Float, jfloatArray, float)
2860 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2863 /* Get<PrimitiveType>ArrayElements *********************************************
2865 A family of functions that returns the body of the primitive array.
2867 *******************************************************************************/
2869 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2870 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2873 java_handle_##intern##array_t *a; \
2875 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2877 a = (java_handle_##intern##array_t *) array; \
2880 *isCopy = JNI_FALSE; \
2882 return (type *) LLNI_array_data(a); \
2885 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2886 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2887 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2888 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2889 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2890 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2891 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2892 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2895 /* Release<PrimitiveType>ArrayElements *****************************************
2897 A family of functions that informs the VM that the native code no
2898 longer needs access to elems. The elems argument is a pointer
2899 derived from array using the corresponding
2900 Get<PrimitiveType>ArrayElements() function. If necessary, this
2901 function copies back all changes made to elems to the original
2904 *******************************************************************************/
2906 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2907 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2908 type *elems, jint mode) \
2910 java_handle_##intern##array_t *a; \
2912 STATISTICS(jniinvokation()); \
2914 a = (java_handle_##intern##array_t *) array; \
2916 if (elems != (type *) LLNI_array_data(a)) { \
2919 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2922 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2923 /* XXX TWISTI how should it be freed? */ \
2926 /* XXX TWISTI how should it be freed? */ \
2932 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2933 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2934 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2935 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2936 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2937 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2938 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2939 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2942 /* Get<PrimitiveType>ArrayRegion **********************************************
2944 A family of functions that copies a region of a primitive array
2947 *******************************************************************************/
2949 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2950 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2951 jsize start, jsize len, type *buf) \
2953 java_handle_##intern##array_t *a; \
2955 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2957 a = (java_handle_##intern##array_t *) array; \
2959 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2960 exceptions_throw_arrayindexoutofboundsexception(); \
2962 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
2965 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2966 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2967 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2968 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2969 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
2970 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
2971 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
2972 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
2975 /* Set<PrimitiveType>ArrayRegion **********************************************
2977 A family of functions that copies back a region of a primitive
2978 array from a buffer.
2980 *******************************************************************************/
2982 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
2983 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
2984 jsize start, jsize len, const type *buf) \
2986 java_handle_##intern##array_t *a; \
2988 STATISTICS(jniinvokation()); \
2990 a = (java_handle_##intern##array_t *) array; \
2992 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2993 exceptions_throw_arrayindexoutofboundsexception(); \
2995 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
2998 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2999 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3000 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3001 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3002 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3003 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3004 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3005 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3008 /* Registering Native Methods *************************************************/
3010 /* RegisterNatives *************************************************************
3012 Registers native methods with the class specified by the clazz
3013 argument. The methods parameter specifies an array of
3014 JNINativeMethod structures that contain the names, signatures, and
3015 function pointers of the native methods. The nMethods parameter
3016 specifies the number of native methods in the array.
3018 *******************************************************************************/
3020 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3021 const JNINativeMethod *methods, jint nMethods)
3025 STATISTICS(jniinvokation());
3027 c = LLNI_classinfo_unwrap(clazz);
3029 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3030 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3033 native_method_register(c->name, methods, nMethods);
3039 /* UnregisterNatives ***********************************************************
3041 Unregisters native methods of a class. The class goes back to the
3042 state before it was linked or registered with its native method
3045 This function should not be used in normal native code. Instead, it
3046 provides special programs a way to reload and relink native
3049 *******************************************************************************/
3051 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3053 STATISTICS(jniinvokation());
3055 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3057 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3063 /* Monitor Operations *********************************************************/
3065 /* MonitorEnter ****************************************************************
3067 Enters the monitor associated with the underlying Java object
3070 *******************************************************************************/
3072 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3074 STATISTICS(jniinvokation());
3077 exceptions_throw_nullpointerexception();
3081 LOCK_MONITOR_ENTER(obj);
3087 /* MonitorExit *****************************************************************
3089 The current thread must be the owner of the monitor associated with
3090 the underlying Java object referred to by obj. The thread
3091 decrements the counter indicating the number of times it has
3092 entered this monitor. If the value of the counter becomes zero, the
3093 current thread releases the monitor.
3095 *******************************************************************************/
3097 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3099 STATISTICS(jniinvokation());
3102 exceptions_throw_nullpointerexception();
3106 LOCK_MONITOR_EXIT(obj);
3112 /* JavaVM Interface ***********************************************************/
3114 /* GetJavaVM *******************************************************************
3116 Returns the Java VM interface (used in the Invocation API)
3117 associated with the current thread. The result is placed at the
3118 location pointed to by the second argument, vm.
3120 *******************************************************************************/
3122 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3124 STATISTICS(jniinvokation());
3126 *javavm = vm->get_javavm();
3132 /* GetStringRegion *************************************************************
3134 Copies len number of Unicode characters beginning at offset start
3135 to the given buffer buf.
3137 Throws StringIndexOutOfBoundsException on index overflow.
3139 *******************************************************************************/
3141 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3143 java_lang_String s(str);
3144 java_handle_chararray_t* ca = s.get_value();
3145 int32_t count = s.get_count();
3147 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3148 exceptions_throw_stringindexoutofboundsexception();
3152 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3156 /* GetStringUTFRegion **********************************************************
3158 Translates len number of Unicode characters beginning at offset
3159 start into UTF-8 format and place the result in the given buffer
3162 Throws StringIndexOutOfBoundsException on index overflow.
3164 *******************************************************************************/
3166 void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3168 TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3170 java_lang_String s(str);
3171 java_handle_chararray_t* ca = s.get_value();
3172 int32_t count = s.get_count();
3173 int32_t offset = s.get_offset();
3175 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3176 exceptions_throw_stringindexoutofboundsexception();
3182 for (i = 0; i < len; i++)
3183 buf[i] = LLNI_array_direct(ca, offset + start + i);
3189 /* GetPrimitiveArrayCritical ***************************************************
3191 Obtain a direct pointer to array elements.
3193 ATTENTION: Critical section keeps open when this function returns!
3194 See ReleasePrimitiveArrayCritical.
3196 *******************************************************************************/
3198 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3202 arraydescriptor* ad;
3205 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3207 if (isCopy != NULL) {
3208 *isCopy = JNI_FALSE;
3211 LLNI_CRITICAL_START;
3213 h = (java_handle_t*) array;
3214 a = (java_array_t*) LLNI_UNWRAP(h);
3215 ad = a->objheader.vftbl->arraydesc;
3221 data = (void*) (((intptr_t) a) + ad->dataoffset);
3227 /* ReleasePrimitiveArrayCritical ***********************************************
3229 No specific documentation.
3231 ATTENTION: This function closes the critical section opened in
3232 GetPrimitiveArrayCritical!
3234 *******************************************************************************/
3236 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3238 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3244 /* GetStringCritical ***********************************************************
3246 The semantics of these two functions are similar to the existing
3247 Get/ReleaseStringChars functions.
3249 *******************************************************************************/
3251 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3254 STATISTICS(jniinvokation());
3256 return jni_GetStringChars(env, string, isCopy);
3260 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3261 const jchar *cstring)
3263 STATISTICS(jniinvokation());
3265 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3269 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3271 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3277 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3279 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3283 /* NewGlobalRef ****************************************************************
3285 Creates a new global reference to the object referred to by the obj
3288 *******************************************************************************/
3290 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3292 hashtable_global_ref_entry *gre;
3293 u4 key; /* hashkey */
3294 u4 slot; /* slot in hashtable */
3297 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3299 o = (java_handle_t *) obj;
3301 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3303 LLNI_CRITICAL_START;
3305 /* normally addresses are aligned to 4, 8 or 16 bytes */
3307 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3308 slot = key & (hashtable_global_ref->size - 1);
3309 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3311 /* search external hash chain for the entry */
3314 if (gre->o == LLNI_DIRECT(o)) {
3315 /* global object found, increment the reference */
3322 gre = gre->hashlink; /* next element in external chain */
3327 /* global ref not found, create a new one */
3330 gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3332 #if defined(ENABLE_GC_CACAO)
3333 /* register global ref with the GC */
3335 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3338 LLNI_CRITICAL_START;
3340 gre->o = LLNI_DIRECT(o);
3345 /* insert entry into hashtable */
3347 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3349 hashtable_global_ref->ptr[slot] = gre;
3351 /* update number of hashtable-entries */
3353 hashtable_global_ref->entries++;
3356 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3358 #if defined(ENABLE_HANDLES)
3366 /* DeleteGlobalRef *************************************************************
3368 Deletes the global reference pointed to by globalRef.
3370 *******************************************************************************/
3372 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3374 hashtable_global_ref_entry *gre;
3375 hashtable_global_ref_entry *prevgre;
3376 u4 key; /* hashkey */
3377 u4 slot; /* slot in hashtable */
3380 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3382 o = (java_handle_t *) globalRef;
3384 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3386 LLNI_CRITICAL_START;
3388 /* normally addresses are aligned to 4, 8 or 16 bytes */
3390 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3391 slot = key & (hashtable_global_ref->size - 1);
3392 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3394 /* initialize prevgre */
3398 /* search external hash chain for the entry */
3401 if (gre->o == LLNI_DIRECT(o)) {
3402 /* global object found, decrement the reference count */
3406 /* if reference count is 0, remove the entry */
3408 if (gre->refs == 0) {
3409 /* special handling if it's the first in the chain */
3411 if (prevgre == NULL)
3412 hashtable_global_ref->ptr[slot] = gre->hashlink;
3414 prevgre->hashlink = gre->hashlink;
3416 #if defined(ENABLE_GC_CACAO)
3417 /* unregister global ref with the GC */
3419 gc_reference_unregister(&(gre->o));
3427 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3432 prevgre = gre; /* save current pointer for removal */
3433 gre = gre->hashlink; /* next element in external chain */
3436 log_println("jni_DeleteGlobalRef: Global reference not found.");
3440 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3444 /* ExceptionCheck **************************************************************
3446 Returns JNI_TRUE when there is a pending exception; otherwise,
3449 *******************************************************************************/
3451 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3455 STATISTICS(jniinvokation());
3457 o = exceptions_get_exception();
3459 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3463 /* New JNI 1.4 functions ******************************************************/
3465 /* NewDirectByteBuffer *********************************************************
3467 Allocates and returns a direct java.nio.ByteBuffer referring to the
3468 block of memory starting at the memory address address and
3469 extending capacity bytes.
3471 *******************************************************************************/
3473 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3475 #if defined(ENABLE_JAVASE)
3476 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3477 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3479 // Allocate a gnu.classpath.Pointer{32,64} object.
3481 # if SIZEOF_VOID_P == 8
3482 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
3484 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
3490 gnu_classpath_Pointer p(h, address);
3492 // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
3494 java_handle_t* nbuf =
3495 (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3496 (jmethodID) dbbirw_init, NULL, p.get_handle(),
3497 (jint) capacity, (jint) capacity, (jint) 0);
3499 // Add a local reference and return the value.
3501 TRACEJNICALLSEXIT(("->%p", nbuf));
3503 return jni_NewLocalRef(env, (jobject) nbuf);
3505 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3511 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3513 /* Be paranoid about address sign-extension. */
3515 addr = (int64_t) ((uintptr_t) address);
3516 cap = (int32_t) capacity;
3518 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3519 (jmethodID) dbb_init, addr, cap);
3521 /* Add local reference and return the value. */
3523 TRACEJNICALLSEXIT(("->%p", o));
3525 return jni_NewLocalRef(env, o);
3528 # error unknown classpath configuration
3532 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3534 /* keep compiler happy */
3541 /* GetDirectBufferAddress ******************************************************
3543 Fetches and returns the starting address of the memory region
3544 referenced by the given direct java.nio.Buffer.
3546 *******************************************************************************/
3548 void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3550 #if defined(ENABLE_JAVASE)
3551 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3553 TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3555 /* Prevent compiler warning. */
3557 java_handle_t* h = (java_handle_t *) buf;
3559 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3562 java_nio_DirectByteBufferImpl dbb(buf);
3563 java_handle_t* address = dbb.get_address();
3565 if (address == NULL) {
3566 TRACEJNICALLSEXIT(("->%p", NULL));
3570 gnu_classpath_Pointer p(address);
3571 void* data = p.get_data();
3573 TRACEJNICALLSEXIT(("->%p", data));
3577 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3583 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3585 /* Prevent compiler warning. */
3587 h = (java_handle_t *) buf;
3589 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3592 o = (java_nio_Buffer *) buf;
3594 LLNI_field_get_val(o, address, address);
3596 p = (void *) (intptr_t) address;
3601 # error unknown classpath configuration
3606 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3608 /* keep compiler happy */
3616 /* GetDirectBufferCapacity *****************************************************
3618 Fetches and returns the capacity in bytes of the memory region
3619 referenced by the given direct java.nio.Buffer.
3621 *******************************************************************************/
3623 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3625 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3626 TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3628 java_handle_t* h = (java_handle_t *) buf;
3630 if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
3633 java_nio_Buffer b(h);
3634 jlong capacity = b.get_cap();
3638 vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
3640 // Keep compiler happy.
3647 /* GetObjectRefType ************************************************************
3649 Returns the type of the object referred to by the obj argument. The
3650 argument obj can either be a local, global or weak global
3653 *******************************************************************************/
3655 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3657 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3659 return (jobjectRefType) NULL;
3663 /* DestroyJavaVM ***************************************************************
3665 Unloads a Java VM and reclaims its resources. Only the main thread
3666 can unload the VM. The system waits until the main thread is only
3667 remaining user thread before it destroys the VM.
3669 *******************************************************************************/
3671 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3675 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3677 if (vm->is_created() == false)
3680 status = vm_destroy(javavm);
3686 /* AttachCurrentThread *********************************************************
3688 Attaches the current thread to a Java VM. Returns a JNI interface
3689 pointer in the JNIEnv argument.
3691 Trying to attach a thread that is already attached is a no-op.
3693 A native thread cannot be attached simultaneously to two Java VMs.
3695 When a thread is attached to the VM, the context class loader is
3696 the bootstrap loader.
3698 *******************************************************************************/
3700 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3702 #if defined(ENABLE_THREADS)
3703 JavaVMAttachArgs *vm_aargs;
3706 /* If the current thread has already been attached, this operation
3709 result = thread_current_is_attached();
3711 if (result == true) {
3712 *p_env = vm->get_jnienv();
3716 vm_aargs = (JavaVMAttachArgs *) thr_args;
3718 if (vm_aargs != NULL) {
3719 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3720 (vm_aargs->version != JNI_VERSION_1_4))
3721 return JNI_EVERSION;
3724 if (!thread_attach_current_external_thread(vm_aargs, false))
3727 if (!localref_table_init())
3731 *p_env = vm->get_jnienv();
3737 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3741 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3743 if (vm->is_created() == false)
3746 result = jni_attach_current_thread(p_env, thr_args, false);
3752 /* DetachCurrentThread *********************************************************
3754 Detaches the current thread from a Java VM. All Java monitors held
3755 by this thread are released. All Java threads waiting for this
3756 thread to die are notified.
3758 In JDK 1.1, the main thread cannot be detached from the VM. It must
3759 call DestroyJavaVM to unload the entire VM.
3761 In the JDK, the main thread can be detached from the VM.
3763 The main thread, which is the thread that created the Java VM,
3764 cannot be detached from the VM. Instead, the main thread must call
3765 JNI_DestroyJavaVM() to unload the entire VM.
3767 *******************************************************************************/
3769 jint jni_DetachCurrentThread(JavaVM *vm)
3771 #if defined(ENABLE_THREADS)
3774 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3776 /* If the current thread has already been detached, this operation
3779 result = thread_current_is_attached();
3781 if (result == false)
3784 /* We need to pop all frames before we can destroy the table. */
3786 localref_frame_pop_all();
3788 if (!localref_table_destroy())
3791 if (!thread_detach_current_external_thread())
3799 /* GetEnv **********************************************************************
3801 If the current thread is not attached to the VM, sets *env to NULL,
3802 and returns JNI_EDETACHED. If the specified version is not
3803 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3804 sets *env to the appropriate interface, and returns JNI_OK.
3806 *******************************************************************************/
3808 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3810 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3812 if (vm->is_created() == false) {
3814 return JNI_EDETACHED;
3817 #if defined(ENABLE_THREADS)
3818 if (thread_get_current() == NULL) {
3821 return JNI_EDETACHED;
3825 /* Check the JNI version. */
3827 if (jni_version_check(version) == true) {
3828 *env = vm->get_jnienv();
3832 #if defined(ENABLE_JVMTI)
3833 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3834 == JVMTI_VERSION_INTERFACE_JVMTI) {
3836 *env = (void *) jvmti_new_environment();
3845 return JNI_EVERSION;
3849 /* AttachCurrentThreadAsDaemon *************************************************
3851 Same semantics as AttachCurrentThread, but the newly-created
3852 java.lang.Thread instance is a daemon.
3854 If the thread has already been attached via either
3855 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3856 simply sets the value pointed to by penv to the JNIEnv of the
3857 current thread. In this case neither AttachCurrentThread nor this
3858 routine have any effect on the daemon status of the thread.
3860 *******************************************************************************/
3862 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3866 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
3868 if (vm->is_created() == false)
3871 result = jni_attach_current_thread(penv, args, true);
3877 /* JNI invocation table *******************************************************/
3879 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3884 _Jv_JNI_DestroyJavaVM,
3885 jni_AttachCurrentThread,
3886 jni_DetachCurrentThread,
3888 jni_AttachCurrentThreadAsDaemon
3892 /* JNI function table *********************************************************/
3894 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3903 jni_FromReflectedMethod,
3904 jni_FromReflectedField,
3905 jni_ToReflectedMethod,
3907 _Jv_JNI_IsAssignableFrom,
3908 _Jv_JNI_ToReflectedField,
3912 _Jv_JNI_ExceptionOccurred,
3913 jni_ExceptionDescribe,
3920 jni_DeleteGlobalRef,
3922 _Jv_JNI_IsSameObject,
3924 jni_EnsureLocalCapacity,
3926 _Jv_JNI_AllocObject,
3932 _Jv_JNI_IsInstanceOf,
3934 _Jv_JNI_GetMethodID,
3936 _Jv_JNI_CallObjectMethod,
3937 _Jv_JNI_CallObjectMethodV,
3938 _Jv_JNI_CallObjectMethodA,
3939 _Jv_JNI_CallBooleanMethod,
3940 _Jv_JNI_CallBooleanMethodV,
3941 _Jv_JNI_CallBooleanMethodA,
3942 _Jv_JNI_CallByteMethod,
3943 _Jv_JNI_CallByteMethodV,
3944 _Jv_JNI_CallByteMethodA,
3945 _Jv_JNI_CallCharMethod,
3946 _Jv_JNI_CallCharMethodV,
3947 _Jv_JNI_CallCharMethodA,
3948 _Jv_JNI_CallShortMethod,
3949 _Jv_JNI_CallShortMethodV,
3950 _Jv_JNI_CallShortMethodA,
3951 _Jv_JNI_CallIntMethod,
3952 _Jv_JNI_CallIntMethodV,
3953 _Jv_JNI_CallIntMethodA,
3954 _Jv_JNI_CallLongMethod,
3955 _Jv_JNI_CallLongMethodV,
3956 _Jv_JNI_CallLongMethodA,
3957 _Jv_JNI_CallFloatMethod,
3958 _Jv_JNI_CallFloatMethodV,
3959 _Jv_JNI_CallFloatMethodA,
3960 _Jv_JNI_CallDoubleMethod,
3961 _Jv_JNI_CallDoubleMethodV,
3962 _Jv_JNI_CallDoubleMethodA,
3963 _Jv_JNI_CallVoidMethod,
3964 _Jv_JNI_CallVoidMethodV,
3965 _Jv_JNI_CallVoidMethodA,
3967 _Jv_JNI_CallNonvirtualObjectMethod,
3968 _Jv_JNI_CallNonvirtualObjectMethodV,
3969 _Jv_JNI_CallNonvirtualObjectMethodA,
3970 _Jv_JNI_CallNonvirtualBooleanMethod,
3971 _Jv_JNI_CallNonvirtualBooleanMethodV,
3972 _Jv_JNI_CallNonvirtualBooleanMethodA,
3973 _Jv_JNI_CallNonvirtualByteMethod,
3974 _Jv_JNI_CallNonvirtualByteMethodV,
3975 _Jv_JNI_CallNonvirtualByteMethodA,
3976 _Jv_JNI_CallNonvirtualCharMethod,
3977 _Jv_JNI_CallNonvirtualCharMethodV,
3978 _Jv_JNI_CallNonvirtualCharMethodA,
3979 _Jv_JNI_CallNonvirtualShortMethod,
3980 _Jv_JNI_CallNonvirtualShortMethodV,
3981 _Jv_JNI_CallNonvirtualShortMethodA,
3982 _Jv_JNI_CallNonvirtualIntMethod,
3983 _Jv_JNI_CallNonvirtualIntMethodV,
3984 _Jv_JNI_CallNonvirtualIntMethodA,
3985 _Jv_JNI_CallNonvirtualLongMethod,
3986 _Jv_JNI_CallNonvirtualLongMethodV,
3987 _Jv_JNI_CallNonvirtualLongMethodA,
3988 _Jv_JNI_CallNonvirtualFloatMethod,
3989 _Jv_JNI_CallNonvirtualFloatMethodV,
3990 _Jv_JNI_CallNonvirtualFloatMethodA,
3991 _Jv_JNI_CallNonvirtualDoubleMethod,
3992 _Jv_JNI_CallNonvirtualDoubleMethodV,
3993 _Jv_JNI_CallNonvirtualDoubleMethodA,
3994 _Jv_JNI_CallNonvirtualVoidMethod,
3995 _Jv_JNI_CallNonvirtualVoidMethodV,
3996 _Jv_JNI_CallNonvirtualVoidMethodA,
4000 _Jv_JNI_GetObjectField,
4001 _Jv_JNI_GetBooleanField,
4002 _Jv_JNI_GetByteField,
4003 _Jv_JNI_GetCharField,
4004 _Jv_JNI_GetShortField,
4005 _Jv_JNI_GetIntField,
4006 _Jv_JNI_GetLongField,
4007 _Jv_JNI_GetFloatField,
4008 _Jv_JNI_GetDoubleField,
4009 _Jv_JNI_SetObjectField,
4010 _Jv_JNI_SetBooleanField,
4011 _Jv_JNI_SetByteField,
4012 _Jv_JNI_SetCharField,
4013 _Jv_JNI_SetShortField,
4014 _Jv_JNI_SetIntField,
4015 _Jv_JNI_SetLongField,
4016 _Jv_JNI_SetFloatField,
4017 _Jv_JNI_SetDoubleField,
4019 _Jv_JNI_GetStaticMethodID,
4021 _Jv_JNI_CallStaticObjectMethod,
4022 _Jv_JNI_CallStaticObjectMethodV,
4023 _Jv_JNI_CallStaticObjectMethodA,
4024 _Jv_JNI_CallStaticBooleanMethod,
4025 _Jv_JNI_CallStaticBooleanMethodV,
4026 _Jv_JNI_CallStaticBooleanMethodA,
4027 _Jv_JNI_CallStaticByteMethod,
4028 _Jv_JNI_CallStaticByteMethodV,
4029 _Jv_JNI_CallStaticByteMethodA,
4030 _Jv_JNI_CallStaticCharMethod,
4031 _Jv_JNI_CallStaticCharMethodV,
4032 _Jv_JNI_CallStaticCharMethodA,
4033 _Jv_JNI_CallStaticShortMethod,
4034 _Jv_JNI_CallStaticShortMethodV,
4035 _Jv_JNI_CallStaticShortMethodA,
4036 _Jv_JNI_CallStaticIntMethod,
4037 _Jv_JNI_CallStaticIntMethodV,
4038 _Jv_JNI_CallStaticIntMethodA,
4039 _Jv_JNI_CallStaticLongMethod,
4040 _Jv_JNI_CallStaticLongMethodV,
4041 _Jv_JNI_CallStaticLongMethodA,
4042 _Jv_JNI_CallStaticFloatMethod,
4043 _Jv_JNI_CallStaticFloatMethodV,
4044 _Jv_JNI_CallStaticFloatMethodA,
4045 _Jv_JNI_CallStaticDoubleMethod,
4046 _Jv_JNI_CallStaticDoubleMethodV,
4047 _Jv_JNI_CallStaticDoubleMethodA,
4048 _Jv_JNI_CallStaticVoidMethod,
4049 _Jv_JNI_CallStaticVoidMethodV,
4050 _Jv_JNI_CallStaticVoidMethodA,
4052 _Jv_JNI_GetStaticFieldID,
4054 _Jv_JNI_GetStaticObjectField,
4055 _Jv_JNI_GetStaticBooleanField,
4056 _Jv_JNI_GetStaticByteField,
4057 _Jv_JNI_GetStaticCharField,
4058 _Jv_JNI_GetStaticShortField,
4059 _Jv_JNI_GetStaticIntField,
4060 _Jv_JNI_GetStaticLongField,
4061 _Jv_JNI_GetStaticFloatField,
4062 _Jv_JNI_GetStaticDoubleField,
4063 _Jv_JNI_SetStaticObjectField,
4064 _Jv_JNI_SetStaticBooleanField,
4065 _Jv_JNI_SetStaticByteField,
4066 _Jv_JNI_SetStaticCharField,
4067 _Jv_JNI_SetStaticShortField,
4068 _Jv_JNI_SetStaticIntField,
4069 _Jv_JNI_SetStaticLongField,
4070 _Jv_JNI_SetStaticFloatField,
4071 _Jv_JNI_SetStaticDoubleField,
4074 jni_GetStringLength,
4076 _Jv_JNI_ReleaseStringChars,
4079 jni_GetStringUTFLength,
4080 _Jv_JNI_GetStringUTFChars,
4081 _Jv_JNI_ReleaseStringUTFChars,
4083 _Jv_JNI_GetArrayLength,
4085 _Jv_JNI_NewObjectArray,
4086 _Jv_JNI_GetObjectArrayElement,
4087 _Jv_JNI_SetObjectArrayElement,
4089 _Jv_JNI_NewBooleanArray,
4090 _Jv_JNI_NewByteArray,
4091 _Jv_JNI_NewCharArray,
4092 _Jv_JNI_NewShortArray,
4093 _Jv_JNI_NewIntArray,
4094 _Jv_JNI_NewLongArray,
4095 _Jv_JNI_NewFloatArray,
4096 _Jv_JNI_NewDoubleArray,
4098 _Jv_JNI_GetBooleanArrayElements,
4099 _Jv_JNI_GetByteArrayElements,
4100 _Jv_JNI_GetCharArrayElements,
4101 _Jv_JNI_GetShortArrayElements,
4102 _Jv_JNI_GetIntArrayElements,
4103 _Jv_JNI_GetLongArrayElements,
4104 _Jv_JNI_GetFloatArrayElements,
4105 _Jv_JNI_GetDoubleArrayElements,
4107 _Jv_JNI_ReleaseBooleanArrayElements,
4108 _Jv_JNI_ReleaseByteArrayElements,
4109 _Jv_JNI_ReleaseCharArrayElements,
4110 _Jv_JNI_ReleaseShortArrayElements,
4111 _Jv_JNI_ReleaseIntArrayElements,
4112 _Jv_JNI_ReleaseLongArrayElements,
4113 _Jv_JNI_ReleaseFloatArrayElements,
4114 _Jv_JNI_ReleaseDoubleArrayElements,
4116 _Jv_JNI_GetBooleanArrayRegion,
4117 _Jv_JNI_GetByteArrayRegion,
4118 _Jv_JNI_GetCharArrayRegion,
4119 _Jv_JNI_GetShortArrayRegion,
4120 _Jv_JNI_GetIntArrayRegion,
4121 _Jv_JNI_GetLongArrayRegion,
4122 _Jv_JNI_GetFloatArrayRegion,
4123 _Jv_JNI_GetDoubleArrayRegion,
4124 _Jv_JNI_SetBooleanArrayRegion,
4125 _Jv_JNI_SetByteArrayRegion,
4126 _Jv_JNI_SetCharArrayRegion,
4127 _Jv_JNI_SetShortArrayRegion,
4128 _Jv_JNI_SetIntArrayRegion,
4129 _Jv_JNI_SetLongArrayRegion,
4130 _Jv_JNI_SetFloatArrayRegion,
4131 _Jv_JNI_SetDoubleArrayRegion,
4133 _Jv_JNI_RegisterNatives,
4134 _Jv_JNI_UnregisterNatives,
4136 _Jv_JNI_MonitorEnter,
4137 _Jv_JNI_MonitorExit,
4141 /* New JNI 1.2 functions. */
4143 jni_GetStringRegion,
4144 jni_GetStringUTFRegion,
4146 jni_GetPrimitiveArrayCritical,
4147 jni_ReleasePrimitiveArrayCritical,
4149 _Jv_JNI_GetStringCritical,
4150 _Jv_JNI_ReleaseStringCritical,
4152 _Jv_JNI_NewWeakGlobalRef,
4153 _Jv_JNI_DeleteWeakGlobalRef,
4155 _Jv_JNI_ExceptionCheck,
4157 /* New JNI 1.4 functions. */
4159 jni_NewDirectByteBuffer,
4160 jni_GetDirectBufferAddress,
4161 jni_GetDirectBufferCapacity,
4163 /* New JNI 1.6 functions. */
4165 jni_GetObjectRefType
4169 /* Invocation API Functions ***************************************************/
4171 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4173 Returns a default configuration for the Java VM.
4175 *******************************************************************************/
4177 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4179 JavaVMInitArgs *_vm_args;
4181 _vm_args = (JavaVMInitArgs *) vm_args;
4183 /* GNU classpath currently supports JNI 1.2 */
4185 switch (_vm_args->version) {
4186 case JNI_VERSION_1_1:
4187 _vm_args->version = JNI_VERSION_1_1;
4190 case JNI_VERSION_1_2:
4191 case JNI_VERSION_1_4:
4192 _vm_args->ignoreUnrecognized = JNI_FALSE;
4193 _vm_args->options = NULL;
4194 _vm_args->nOptions = 0;
4205 /* JNI_GetCreatedJavaVMs *******************************************************
4207 Returns all Java VMs that have been created. Pointers to VMs are written in
4208 the buffer vmBuf in the order they are created. At most bufLen number of
4209 entries will be written. The total number of created VMs is returned in
4212 *******************************************************************************/
4214 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4216 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4221 // We currently only support 1 VM running.
4223 vmBuf[0] = vm->get_javavm();
4230 /* JNI_CreateJavaVM ************************************************************
4232 Loads and initializes a Java VM. The current thread becomes the main thread.
4233 Sets the env argument to the JNI interface pointer of the main thread.
4235 *******************************************************************************/
4237 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4239 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4241 /* actually create the JVM */
4243 if (!VM_create(p_vm, p_env, vm_args))
4253 * These are local overrides for various environment variables in Emacs.
4254 * Please do not remove this and leave it at the end of the file, where
4255 * Emacs will automagically detect them.
4256 * ---------------------------------------------------------------------
4259 * indent-tabs-mode: t
4263 * vim:noexpandtab:sw=4:ts=4: