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);
1465 m = rc.get_method();
1468 // FIXME We can't access the object here directly.
1469 assert(o->vftbl->clazz == class_java_lang_reflect_Method);
1471 java_lang_reflect_Method rm(method);
1472 m = rm.get_method();
1475 return (jmethodID) m;
1477 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1479 // Keep compiler happy.
1485 /* FromReflectedField **********************************************************
1487 Converts a java.lang.reflect.Field to a field ID.
1489 *******************************************************************************/
1491 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1493 #if defined(ENABLE_JAVASE)
1495 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1497 java_lang_reflect_Field rf(field);
1502 fieldinfo* f = rf.get_field();
1504 return (jfieldID) f;
1506 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1508 // Keep compiler happy.
1514 /* ToReflectedMethod ***********************************************************
1516 Converts a method ID derived from cls to an instance of the
1517 java.lang.reflect.Method class or to an instance of the
1518 java.lang.reflect.Constructor class.
1520 *******************************************************************************/
1522 jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1524 #if defined(ENABLE_JAVASE)
1525 TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1527 methodinfo* m = (methodinfo *) methodID;
1529 /* HotSpot does the same assert. */
1531 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1535 if (m->name == utf_init) {
1536 h = java_lang_reflect_Constructor(m).get_handle();
1539 h = java_lang_reflect_Method(m).get_handle();
1544 vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
1546 /* keep compiler happy */
1553 /* ToReflectedField ************************************************************
1555 Converts a field ID derived from cls to an instance of the
1556 java.lang.reflect.Field class.
1558 *******************************************************************************/
1560 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1563 STATISTICS(jniinvokation());
1565 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1571 /* Calling Instance Methods ***************************************************/
1573 /* GetMethodID *****************************************************************
1575 Returns the method ID for an instance (nonstatic) method of a class
1576 or interface. The method may be defined in one of the clazz's
1577 superclasses and inherited by clazz. The method is determined by
1578 its name and signature.
1580 GetMethodID() causes an uninitialized class to be initialized.
1582 *******************************************************************************/
1584 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1592 STATISTICS(jniinvokation());
1594 c = LLNI_classinfo_unwrap(clazz);
1599 if (!(c->state & CLASS_INITIALIZED))
1600 if (!initialize_class(c))
1603 /* try to get the method of the class or one of it's superclasses */
1605 uname = utf_new_char((char *) name);
1606 udesc = utf_new_char((char *) sig);
1608 m = class_resolvemethod(c, uname, udesc);
1610 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1611 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1616 return (jmethodID) m;
1620 /* JNI-functions for calling instance methods *********************************/
1622 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1623 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1624 jmethodID methodID, ...) \
1631 o = (java_handle_t *) obj; \
1632 m = (methodinfo *) methodID; \
1634 va_start(ap, methodID); \
1635 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1641 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1642 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1643 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1644 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1645 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1646 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1647 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1648 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1651 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1652 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1653 jmethodID methodID, va_list args) \
1659 o = (java_handle_t *) obj; \
1660 m = (methodinfo *) methodID; \
1662 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1667 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1668 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1669 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1670 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1671 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1672 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1673 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1674 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1677 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1678 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1679 jmethodID methodID, \
1680 const jvalue *args) \
1686 o = (java_handle_t *) obj; \
1687 m = (methodinfo *) methodID; \
1689 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1694 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1695 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1696 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1697 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1698 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1699 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1700 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1701 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1704 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1712 o = (java_handle_t *) obj;
1713 m = (methodinfo *) methodID;
1715 va_start(ap, methodID);
1716 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1719 return jni_NewLocalRef(env, (jobject) ret);
1723 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1730 o = (java_handle_t *) obj;
1731 m = (methodinfo *) methodID;
1733 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1735 return jni_NewLocalRef(env, (jobject) ret);
1739 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1746 o = (java_handle_t *) obj;
1747 m = (methodinfo *) methodID;
1749 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1751 return jni_NewLocalRef(env, (jobject) ret);
1756 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1762 o = (java_handle_t *) obj;
1763 m = (methodinfo *) methodID;
1765 va_start(ap, methodID);
1766 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1771 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1777 o = (java_handle_t *) obj;
1778 m = (methodinfo *) methodID;
1780 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1784 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1790 o = (java_handle_t *) obj;
1791 m = (methodinfo *) methodID;
1793 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1798 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1799 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1800 jclass clazz, jmethodID methodID, \
1809 o = (java_handle_t *) obj; \
1810 c = LLNI_classinfo_unwrap(clazz); \
1811 m = (methodinfo *) methodID; \
1813 va_start(ap, methodID); \
1814 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1820 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1821 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1822 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1823 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1824 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1825 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1826 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1827 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1830 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1831 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1832 jclass clazz, jmethodID methodID, \
1840 o = (java_handle_t *) obj; \
1841 c = LLNI_classinfo_unwrap(clazz); \
1842 m = (methodinfo *) methodID; \
1844 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1849 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1850 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1851 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1852 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1853 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1854 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1855 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1856 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1859 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1860 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1861 jclass clazz, jmethodID methodID, \
1862 const jvalue *args) \
1864 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1869 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1870 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1871 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1872 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1873 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1874 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1875 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1876 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1878 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1879 jclass clazz, jmethodID methodID,
1888 o = (java_handle_t *) obj;
1889 c = LLNI_classinfo_unwrap(clazz);
1890 m = (methodinfo *) methodID;
1892 va_start(ap, methodID);
1893 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1896 return jni_NewLocalRef(env, (jobject) r);
1900 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1901 jclass clazz, jmethodID methodID,
1909 o = (java_handle_t *) obj;
1910 c = LLNI_classinfo_unwrap(clazz);
1911 m = (methodinfo *) methodID;
1913 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1915 return jni_NewLocalRef(env, (jobject) r);
1919 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1920 jclass clazz, jmethodID methodID,
1923 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1925 return jni_NewLocalRef(env, NULL);
1929 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1930 jmethodID methodID, ...)
1937 o = (java_handle_t *) obj;
1938 c = LLNI_classinfo_unwrap(clazz);
1939 m = (methodinfo *) methodID;
1941 va_start(ap, methodID);
1942 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1947 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1948 jmethodID methodID, va_list args)
1954 o = (java_handle_t *) obj;
1955 c = LLNI_classinfo_unwrap(clazz);
1956 m = (methodinfo *) methodID;
1958 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
1962 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
1963 jmethodID methodID, const jvalue * args)
1969 o = (java_handle_t *) obj;
1970 c = LLNI_classinfo_unwrap(clazz);
1971 m = (methodinfo *) methodID;
1973 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
1977 /* Accessing Fields of Objects ************************************************/
1979 /* GetFieldID ******************************************************************
1981 Returns the field ID for an instance (nonstatic) field of a
1982 class. The field is specified by its name and signature. The
1983 Get<type>Field and Set<type>Field families of accessor functions
1984 use field IDs to retrieve object fields.
1986 *******************************************************************************/
1988 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
1996 STATISTICS(jniinvokation());
1998 c = LLNI_classinfo_unwrap(clazz);
2000 /* XXX NPE check? */
2002 uname = utf_new_char((char *) name);
2003 udesc = utf_new_char((char *) sig);
2005 f = class_findfield(c, uname, udesc);
2008 exceptions_throw_nosuchfielderror(c, uname);
2010 return (jfieldID) f;
2014 /* Get<type>Field Routines *****************************************************
2016 This family of accessor routines returns the value of an instance
2017 (nonstatic) field of an object. The field to access is specified by
2018 a field ID obtained by calling GetFieldID().
2020 *******************************************************************************/
2022 #define GET_FIELD(o,type,f) \
2023 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2025 #define JNI_GET_FIELD(name, type, intern) \
2026 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2030 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2032 LLNI_CRITICAL_START; \
2034 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2036 LLNI_CRITICAL_END; \
2038 return (type) ret; \
2041 JNI_GET_FIELD(Boolean, jboolean, s4)
2042 JNI_GET_FIELD(Byte, jbyte, s4)
2043 JNI_GET_FIELD(Char, jchar, s4)
2044 JNI_GET_FIELD(Short, jshort, s4)
2045 JNI_GET_FIELD(Int, jint, s4)
2046 JNI_GET_FIELD(Long, jlong, s8)
2047 JNI_GET_FIELD(Float, jfloat, float)
2048 JNI_GET_FIELD(Double, jdouble, double)
2051 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2055 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2057 LLNI_CRITICAL_START;
2059 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2063 return jni_NewLocalRef(env, (jobject) o);
2067 /* Set<type>Field Routines *****************************************************
2069 This family of accessor routines sets the value of an instance
2070 (nonstatic) field of an object. The field to access is specified by
2071 a field ID obtained by calling GetFieldID().
2073 *******************************************************************************/
2075 #define SET_FIELD(o,type,f,value) \
2076 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2078 #define JNI_SET_FIELD(name, type, intern) \
2079 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2082 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2084 LLNI_CRITICAL_START; \
2086 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2088 LLNI_CRITICAL_START; \
2091 JNI_SET_FIELD(Boolean, jboolean, s4)
2092 JNI_SET_FIELD(Byte, jbyte, s4)
2093 JNI_SET_FIELD(Char, jchar, s4)
2094 JNI_SET_FIELD(Short, jshort, s4)
2095 JNI_SET_FIELD(Int, jint, s4)
2096 JNI_SET_FIELD(Long, jlong, s8)
2097 JNI_SET_FIELD(Float, jfloat, float)
2098 JNI_SET_FIELD(Double, jdouble, double)
2101 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2104 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2106 LLNI_CRITICAL_START;
2108 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2114 /* Calling Static Methods *****************************************************/
2116 /* GetStaticMethodID ***********************************************************
2118 Returns the method ID for a static method of a class. The method is
2119 specified by its name and signature.
2121 GetStaticMethodID() causes an uninitialized class to be
2124 *******************************************************************************/
2126 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2134 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2136 c = LLNI_classinfo_unwrap(clazz);
2141 if (!(c->state & CLASS_INITIALIZED))
2142 if (!initialize_class(c))
2145 /* try to get the static method of the class */
2147 uname = utf_new_char((char *) name);
2148 udesc = utf_new_char((char *) sig);
2150 m = class_resolvemethod(c, uname, udesc);
2152 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2153 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2158 return (jmethodID) m;
2162 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2163 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2164 jmethodID methodID, ...) \
2170 m = (methodinfo *) methodID; \
2172 va_start(ap, methodID); \
2173 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2179 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2180 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2181 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2182 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2183 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2184 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2185 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2186 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2189 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2190 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2191 jmethodID methodID, va_list args) \
2196 m = (methodinfo *) methodID; \
2198 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2203 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2204 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2205 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2206 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2207 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2208 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2209 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2210 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2213 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2214 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2215 jmethodID methodID, const jvalue *args) \
2220 m = (methodinfo *) methodID; \
2222 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2227 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2228 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2229 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2230 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2231 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2232 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2233 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2234 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2237 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2238 jmethodID methodID, ...)
2244 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2246 m = (methodinfo *) methodID;
2248 va_start(ap, methodID);
2249 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2252 return jni_NewLocalRef(env, (jobject) o);
2256 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2257 jmethodID methodID, va_list args)
2262 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2264 m = (methodinfo *) methodID;
2266 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2268 return jni_NewLocalRef(env, (jobject) o);
2272 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2273 jmethodID methodID, const jvalue *args)
2278 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2280 m = (methodinfo *) methodID;
2282 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2284 return jni_NewLocalRef(env, (jobject) o);
2288 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2289 jmethodID methodID, ...)
2294 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2296 m = (methodinfo *) methodID;
2298 va_start(ap, methodID);
2299 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2304 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2305 jmethodID methodID, va_list args)
2309 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2311 m = (methodinfo *) methodID;
2313 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2317 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2318 jmethodID methodID, const jvalue * args)
2322 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2324 m = (methodinfo *) methodID;
2326 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2330 /* Accessing Static Fields ****************************************************/
2332 /* GetStaticFieldID ************************************************************
2334 Returns the field ID for a static field of a class. The field is
2335 specified by its name and signature. The GetStatic<type>Field and
2336 SetStatic<type>Field families of accessor functions use field IDs
2337 to retrieve static fields.
2339 *******************************************************************************/
2341 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2349 STATISTICS(jniinvokation());
2351 c = LLNI_classinfo_unwrap(clazz);
2353 uname = utf_new_char((char *) name);
2354 usig = utf_new_char((char *) sig);
2356 f = class_findfield(c, uname, usig);
2359 exceptions_throw_nosuchfielderror(c, uname);
2361 return (jfieldID) f;
2365 /* GetStatic<type>Field ********************************************************
2367 This family of accessor routines returns the value of a static
2370 *******************************************************************************/
2372 #define JNI_GET_STATIC_FIELD(name, type, field) \
2373 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2379 STATISTICS(jniinvokation()); \
2381 c = LLNI_classinfo_unwrap(clazz); \
2382 f = (fieldinfo *) fieldID; \
2384 if (!(c->state & CLASS_INITIALIZED)) \
2385 if (!initialize_class(c)) \
2388 return f->value->field; \
2391 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2392 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2393 JNI_GET_STATIC_FIELD(Char, jchar, i)
2394 JNI_GET_STATIC_FIELD(Short, jshort, i)
2395 JNI_GET_STATIC_FIELD(Int, jint, i)
2396 JNI_GET_STATIC_FIELD(Long, jlong, l)
2397 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2398 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2401 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2408 STATISTICS(jniinvokation());
2410 c = LLNI_classinfo_unwrap(clazz);
2411 f = (fieldinfo *) fieldID;
2413 if (!(c->state & CLASS_INITIALIZED))
2414 if (!initialize_class(c))
2417 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2419 return jni_NewLocalRef(env, (jobject) h);
2423 /* SetStatic<type>Field *******************************************************
2425 This family of accessor routines sets the value of a static field
2428 *******************************************************************************/
2430 #define JNI_SET_STATIC_FIELD(name, type, field) \
2431 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2438 STATISTICS(jniinvokation()); \
2440 c = LLNI_classinfo_unwrap(clazz); \
2441 f = (fieldinfo *) fieldID; \
2443 if (!(c->state & CLASS_INITIALIZED)) \
2444 if (!initialize_class(c)) \
2447 f->value->field = value; \
2450 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2451 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2452 JNI_SET_STATIC_FIELD(Char, jchar, i)
2453 JNI_SET_STATIC_FIELD(Short, jshort, i)
2454 JNI_SET_STATIC_FIELD(Int, jint, i)
2455 JNI_SET_STATIC_FIELD(Long, jlong, l)
2456 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2457 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2460 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2466 STATISTICS(jniinvokation());
2468 c = LLNI_classinfo_unwrap(clazz);
2469 f = (fieldinfo *) fieldID;
2471 if (!(c->state & CLASS_INITIALIZED))
2472 if (!initialize_class(c))
2475 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2479 /* String Operations **********************************************************/
2481 /* NewString *******************************************************************
2483 Create new java.lang.String object from an array of Unicode
2486 *******************************************************************************/
2488 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
2490 TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
2492 java_handle_chararray_t* a = builtin_newarray_char(len);
2498 for (jsize i = 0; i < len; i++)
2499 LLNI_array_direct(a, i) = buf[i];
2501 java_handle_t* h = builtin_new(class_java_lang_String);
2506 java_lang_String s(h, a, len, 0);
2508 return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
2512 static jchar emptyStringJ[]={0,0};
2514 /* GetStringLength *************************************************************
2516 Returns the length (the count of Unicode characters) of a Java
2519 *******************************************************************************/
2521 jsize jni_GetStringLength(JNIEnv *env, jstring str)
2523 TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
2525 java_lang_String s(str);
2526 jsize count = s.get_count();
2528 TRACEJNICALLSEXIT(("->%d)", count));
2534 /* GetStringChars **************************************************************
2536 Returns a pointer to the array of Unicode characters of the
2537 string. This pointer is valid until ReleaseStringChars() is called.
2539 *******************************************************************************/
2541 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2546 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2549 // FIXME This is really ugly.
2550 return emptyStringJ;
2552 java_lang_String s(str);
2554 java_handle_chararray_t* ca = s.get_value();
2555 int32_t count = s.get_count();
2556 int32_t offset = s.get_offset();
2561 /* allocate memory */
2563 stringbuffer = MNEW(u2, count + 1);
2567 for (i = 0; i < count; i++)
2568 stringbuffer[i] = LLNI_array_direct(ca, offset + i);
2570 /* terminate string */
2572 stringbuffer[i] = '\0';
2577 return (jchar*) stringbuffer;
2581 /* ReleaseStringChars **********************************************************
2583 Informs the VM that the native code no longer needs access to
2584 chars. The chars argument is a pointer obtained from string using
2587 *******************************************************************************/
2589 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2591 TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
2594 if (chars == emptyStringJ)
2597 java_lang_String s(str);
2598 int32_t count = s.get_count();
2600 MFREE(((jchar*) chars), jchar, count + 1);
2604 /* NewStringUTF ****************************************************************
2606 Constructs a new java.lang.String object from an array of UTF-8
2609 *******************************************************************************/
2611 jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
2613 TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2615 java_handle_t *h = javastring_safe_new_from_utf8(bytes);
2617 return (jstring) jni_NewLocalRef(env, (jobject) h);
2621 /****************** returns the utf8 length in bytes of a string *******************/
2623 jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
2625 TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
2627 java_lang_String s(string);
2628 java_handle_chararray_t* ca = s.get_value();
2629 int32_t count = s.get_count();
2631 // FIXME GC critical section!
2632 int32_t length = u2_utflength(ca->data, count);
2638 /* GetStringUTFChars ***********************************************************
2640 Returns a pointer to an array of UTF-8 characters of the
2641 string. This array is valid until it is released by
2642 ReleaseStringUTFChars().
2644 *******************************************************************************/
2646 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2651 STATISTICS(jniinvokation());
2659 u = javastring_toutf((java_handle_t *) string, false);
2668 /* ReleaseStringUTFChars *******************************************************
2670 Informs the VM that the native code no longer needs access to
2671 utf. The utf argument is a pointer derived from string using
2672 GetStringUTFChars().
2674 *******************************************************************************/
2676 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2678 STATISTICS(jniinvokation());
2680 /* XXX we don't release utf chars right now, perhaps that should be done
2681 later. Since there is always one reference the garbage collector will
2686 /* Array Operations ***********************************************************/
2688 /* GetArrayLength **************************************************************
2690 Returns the number of elements in the array.
2692 *******************************************************************************/
2694 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2699 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2701 a = (java_handle_t *) array;
2703 size = LLNI_array_size(a);
2709 /* NewObjectArray **************************************************************
2711 Constructs a new array holding objects in class elementClass. All
2712 elements are initially set to initialElement.
2714 *******************************************************************************/
2716 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2717 jclass elementClass, jobject initialElement)
2721 java_handle_objectarray_t *oa;
2724 STATISTICS(jniinvokation());
2726 c = LLNI_classinfo_unwrap(elementClass);
2727 o = (java_handle_t *) initialElement;
2730 exceptions_throw_negativearraysizeexception();
2734 oa = builtin_anewarray(length, c);
2739 /* set all elements to initialElement */
2741 for (i = 0; i < length; i++)
2742 array_objectarray_element_set(oa, i, o);
2744 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2748 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2751 java_handle_objectarray_t *oa;
2754 STATISTICS(jniinvokation());
2756 oa = (java_handle_objectarray_t *) array;
2758 if (index >= LLNI_array_size(oa)) {
2759 exceptions_throw_arrayindexoutofboundsexception();
2763 o = array_objectarray_element_get(oa, index);
2765 return jni_NewLocalRef(env, (jobject) o);
2769 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2770 jsize index, jobject val)
2772 java_handle_objectarray_t *oa;
2775 STATISTICS(jniinvokation());
2777 oa = (java_handle_objectarray_t *) array;
2778 o = (java_handle_t *) val;
2780 if (index >= LLNI_array_size(oa)) {
2781 exceptions_throw_arrayindexoutofboundsexception();
2785 /* check if the class of value is a subclass of the element class
2788 if (!builtin_canstore(oa, o))
2791 array_objectarray_element_set(oa, index, o);
2795 #define JNI_NEW_ARRAY(name, type, intern) \
2796 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2798 java_handle_##intern##array_t *a; \
2800 STATISTICS(jniinvokation()); \
2803 exceptions_throw_negativearraysizeexception(); \
2807 a = builtin_newarray_##intern(len); \
2809 return (type) jni_NewLocalRef(env, (jobject) a); \
2812 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2813 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2814 JNI_NEW_ARRAY(Char, jcharArray, char)
2815 JNI_NEW_ARRAY(Short, jshortArray, short)
2816 JNI_NEW_ARRAY(Int, jintArray, int)
2817 JNI_NEW_ARRAY(Long, jlongArray, long)
2818 JNI_NEW_ARRAY(Float, jfloatArray, float)
2819 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2822 /* Get<PrimitiveType>ArrayElements *********************************************
2824 A family of functions that returns the body of the primitive array.
2826 *******************************************************************************/
2828 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2829 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2832 java_handle_##intern##array_t *a; \
2834 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2836 a = (java_handle_##intern##array_t *) array; \
2839 *isCopy = JNI_FALSE; \
2841 return (type *) LLNI_array_data(a); \
2844 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2845 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2846 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2847 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2848 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2849 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2850 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2851 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2854 /* Release<PrimitiveType>ArrayElements *****************************************
2856 A family of functions that informs the VM that the native code no
2857 longer needs access to elems. The elems argument is a pointer
2858 derived from array using the corresponding
2859 Get<PrimitiveType>ArrayElements() function. If necessary, this
2860 function copies back all changes made to elems to the original
2863 *******************************************************************************/
2865 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2866 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2867 type *elems, jint mode) \
2869 java_handle_##intern##array_t *a; \
2871 STATISTICS(jniinvokation()); \
2873 a = (java_handle_##intern##array_t *) array; \
2875 if (elems != (type *) LLNI_array_data(a)) { \
2878 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2881 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2882 /* XXX TWISTI how should it be freed? */ \
2885 /* XXX TWISTI how should it be freed? */ \
2891 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2892 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2893 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2894 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2895 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2896 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2897 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2898 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2901 /* Get<PrimitiveType>ArrayRegion **********************************************
2903 A family of functions that copies a region of a primitive array
2906 *******************************************************************************/
2908 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2909 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2910 jsize start, jsize len, type *buf) \
2912 java_handle_##intern##array_t *a; \
2914 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2916 a = (java_handle_##intern##array_t *) array; \
2918 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2919 exceptions_throw_arrayindexoutofboundsexception(); \
2921 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
2924 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2925 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2926 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2927 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2928 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
2929 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
2930 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
2931 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
2934 /* Set<PrimitiveType>ArrayRegion **********************************************
2936 A family of functions that copies back a region of a primitive
2937 array from a buffer.
2939 *******************************************************************************/
2941 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
2942 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
2943 jsize start, jsize len, const type *buf) \
2945 java_handle_##intern##array_t *a; \
2947 STATISTICS(jniinvokation()); \
2949 a = (java_handle_##intern##array_t *) array; \
2951 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2952 exceptions_throw_arrayindexoutofboundsexception(); \
2954 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
2957 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2958 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
2959 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
2960 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
2961 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
2962 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
2963 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
2964 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
2967 /* Registering Native Methods *************************************************/
2969 /* RegisterNatives *************************************************************
2971 Registers native methods with the class specified by the clazz
2972 argument. The methods parameter specifies an array of
2973 JNINativeMethod structures that contain the names, signatures, and
2974 function pointers of the native methods. The nMethods parameter
2975 specifies the number of native methods in the array.
2977 *******************************************************************************/
2979 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
2980 const JNINativeMethod *methods, jint nMethods)
2984 STATISTICS(jniinvokation());
2986 c = LLNI_classinfo_unwrap(clazz);
2988 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
2989 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
2992 native_method_register(c->name, methods, nMethods);
2998 /* UnregisterNatives ***********************************************************
3000 Unregisters native methods of a class. The class goes back to the
3001 state before it was linked or registered with its native method
3004 This function should not be used in normal native code. Instead, it
3005 provides special programs a way to reload and relink native
3008 *******************************************************************************/
3010 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3012 STATISTICS(jniinvokation());
3014 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3016 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3022 /* Monitor Operations *********************************************************/
3024 /* MonitorEnter ****************************************************************
3026 Enters the monitor associated with the underlying Java object
3029 *******************************************************************************/
3031 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3033 STATISTICS(jniinvokation());
3036 exceptions_throw_nullpointerexception();
3040 LOCK_MONITOR_ENTER(obj);
3046 /* MonitorExit *****************************************************************
3048 The current thread must be the owner of the monitor associated with
3049 the underlying Java object referred to by obj. The thread
3050 decrements the counter indicating the number of times it has
3051 entered this monitor. If the value of the counter becomes zero, the
3052 current thread releases the monitor.
3054 *******************************************************************************/
3056 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3058 STATISTICS(jniinvokation());
3061 exceptions_throw_nullpointerexception();
3065 LOCK_MONITOR_EXIT(obj);
3071 /* JavaVM Interface ***********************************************************/
3073 /* GetJavaVM *******************************************************************
3075 Returns the Java VM interface (used in the Invocation API)
3076 associated with the current thread. The result is placed at the
3077 location pointed to by the second argument, vm.
3079 *******************************************************************************/
3081 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3083 STATISTICS(jniinvokation());
3085 *javavm = vm->get_javavm();
3091 /* GetStringRegion *************************************************************
3093 Copies len number of Unicode characters beginning at offset start
3094 to the given buffer buf.
3096 Throws StringIndexOutOfBoundsException on index overflow.
3098 *******************************************************************************/
3100 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3102 java_lang_String s(str);
3103 java_handle_chararray_t* ca = s.get_value();
3104 int32_t count = s.get_count();
3106 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3107 exceptions_throw_stringindexoutofboundsexception();
3111 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3115 /* GetStringUTFRegion **********************************************************
3117 Translates len number of Unicode characters beginning at offset
3118 start into UTF-8 format and place the result in the given buffer
3121 Throws StringIndexOutOfBoundsException on index overflow.
3123 *******************************************************************************/
3125 void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3127 TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3129 java_lang_String s(str);
3130 java_handle_chararray_t* ca = s.get_value();
3131 int32_t count = s.get_count();
3132 int32_t offset = s.get_offset();
3134 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3135 exceptions_throw_stringindexoutofboundsexception();
3141 for (i = 0; i < len; i++)
3142 buf[i] = LLNI_array_direct(ca, offset + start + i);
3148 /* GetPrimitiveArrayCritical ***************************************************
3150 Obtain a direct pointer to array elements.
3152 ATTENTION: Critical section keeps open when this function returns!
3153 See ReleasePrimitiveArrayCritical.
3155 *******************************************************************************/
3157 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3161 arraydescriptor* ad;
3164 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3166 if (isCopy != NULL) {
3167 *isCopy = JNI_FALSE;
3170 LLNI_CRITICAL_START;
3172 h = (java_handle_t*) array;
3173 a = (java_array_t*) LLNI_UNWRAP(h);
3174 ad = a->objheader.vftbl->arraydesc;
3180 data = (void*) (((intptr_t) a) + ad->dataoffset);
3186 /* ReleasePrimitiveArrayCritical ***********************************************
3188 No specific documentation.
3190 ATTENTION: This function closes the critical section opened in
3191 GetPrimitiveArrayCritical!
3193 *******************************************************************************/
3195 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3197 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3203 /* GetStringCritical ***********************************************************
3205 The semantics of these two functions are similar to the existing
3206 Get/ReleaseStringChars functions.
3208 *******************************************************************************/
3210 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3213 STATISTICS(jniinvokation());
3215 return jni_GetStringChars(env, string, isCopy);
3219 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3220 const jchar *cstring)
3222 STATISTICS(jniinvokation());
3224 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3228 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3230 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3236 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3238 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3242 /* NewGlobalRef ****************************************************************
3244 Creates a new global reference to the object referred to by the obj
3247 *******************************************************************************/
3249 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3251 hashtable_global_ref_entry *gre;
3252 u4 key; /* hashkey */
3253 u4 slot; /* slot in hashtable */
3256 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3258 o = (java_handle_t *) obj;
3260 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3262 LLNI_CRITICAL_START;
3264 /* normally addresses are aligned to 4, 8 or 16 bytes */
3266 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3267 slot = key & (hashtable_global_ref->size - 1);
3268 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3270 /* search external hash chain for the entry */
3273 if (gre->o == LLNI_DIRECT(o)) {
3274 /* global object found, increment the reference */
3281 gre = gre->hashlink; /* next element in external chain */
3286 /* global ref not found, create a new one */
3289 gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3291 #if defined(ENABLE_GC_CACAO)
3292 /* register global ref with the GC */
3294 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3297 LLNI_CRITICAL_START;
3299 gre->o = LLNI_DIRECT(o);
3304 /* insert entry into hashtable */
3306 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3308 hashtable_global_ref->ptr[slot] = gre;
3310 /* update number of hashtable-entries */
3312 hashtable_global_ref->entries++;
3315 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3317 #if defined(ENABLE_HANDLES)
3325 /* DeleteGlobalRef *************************************************************
3327 Deletes the global reference pointed to by globalRef.
3329 *******************************************************************************/
3331 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3333 hashtable_global_ref_entry *gre;
3334 hashtable_global_ref_entry *prevgre;
3335 u4 key; /* hashkey */
3336 u4 slot; /* slot in hashtable */
3339 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3341 o = (java_handle_t *) globalRef;
3343 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3345 LLNI_CRITICAL_START;
3347 /* normally addresses are aligned to 4, 8 or 16 bytes */
3349 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3350 slot = key & (hashtable_global_ref->size - 1);
3351 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3353 /* initialize prevgre */
3357 /* search external hash chain for the entry */
3360 if (gre->o == LLNI_DIRECT(o)) {
3361 /* global object found, decrement the reference count */
3365 /* if reference count is 0, remove the entry */
3367 if (gre->refs == 0) {
3368 /* special handling if it's the first in the chain */
3370 if (prevgre == NULL)
3371 hashtable_global_ref->ptr[slot] = gre->hashlink;
3373 prevgre->hashlink = gre->hashlink;
3375 #if defined(ENABLE_GC_CACAO)
3376 /* unregister global ref with the GC */
3378 gc_reference_unregister(&(gre->o));
3386 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3391 prevgre = gre; /* save current pointer for removal */
3392 gre = gre->hashlink; /* next element in external chain */
3395 log_println("jni_DeleteGlobalRef: Global reference not found.");
3399 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3403 /* ExceptionCheck **************************************************************
3405 Returns JNI_TRUE when there is a pending exception; otherwise,
3408 *******************************************************************************/
3410 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3414 STATISTICS(jniinvokation());
3416 o = exceptions_get_exception();
3418 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3422 /* New JNI 1.4 functions ******************************************************/
3424 /* NewDirectByteBuffer *********************************************************
3426 Allocates and returns a direct java.nio.ByteBuffer referring to the
3427 block of memory starting at the memory address address and
3428 extending capacity bytes.
3430 *******************************************************************************/
3432 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3434 #if defined(ENABLE_JAVASE)
3435 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3436 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3438 // Allocate a gnu.classpath.Pointer{32,64} object.
3440 # if SIZEOF_VOID_P == 8
3441 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
3443 java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
3449 gnu_classpath_Pointer p(h, address);
3451 // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
3453 java_handle_t* nbuf =
3454 (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3455 (jmethodID) dbbirw_init, NULL, p.get_handle(),
3456 (jint) capacity, (jint) capacity, (jint) 0);
3458 // Add a local reference and return the value.
3460 TRACEJNICALLSEXIT(("->%p", nbuf));
3462 return jni_NewLocalRef(env, (jobject) nbuf);
3464 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3470 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3472 /* Be paranoid about address sign-extension. */
3474 addr = (int64_t) ((uintptr_t) address);
3475 cap = (int32_t) capacity;
3477 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3478 (jmethodID) dbb_init, addr, cap);
3480 /* Add local reference and return the value. */
3482 TRACEJNICALLSEXIT(("->%p", o));
3484 return jni_NewLocalRef(env, o);
3487 # error unknown classpath configuration
3491 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3493 /* keep compiler happy */
3500 /* GetDirectBufferAddress ******************************************************
3502 Fetches and returns the starting address of the memory region
3503 referenced by the given direct java.nio.Buffer.
3505 *******************************************************************************/
3507 void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3509 #if defined(ENABLE_JAVASE)
3510 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3512 TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3514 /* Prevent compiler warning. */
3516 java_handle_t* h = (java_handle_t *) buf;
3518 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3521 java_nio_DirectByteBufferImpl dbb(buf);
3522 java_handle_t* address = dbb.get_address();
3524 if (address == NULL) {
3525 TRACEJNICALLSEXIT(("->%p", NULL));
3529 gnu_classpath_Pointer p(address);
3530 void* data = p.get_data();
3532 TRACEJNICALLSEXIT(("->%p", data));
3536 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3538 TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3540 java_nio_Buffer jnb(buf);
3542 if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3545 void* address = jnb.get_address();
3550 # error unknown classpath configuration
3555 vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
3557 // Keep compiler happy.
3564 /* GetDirectBufferCapacity *****************************************************
3566 Fetches and returns the capacity in bytes of the memory region
3567 referenced by the given direct java.nio.Buffer.
3569 *******************************************************************************/
3571 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3573 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3574 TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3576 java_handle_t* h = (java_handle_t *) buf;
3578 if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
3581 java_nio_Buffer b(h);
3582 jlong capacity = b.get_cap();
3586 vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
3588 // Keep compiler happy.
3595 /* GetObjectRefType ************************************************************
3597 Returns the type of the object referred to by the obj argument. The
3598 argument obj can either be a local, global or weak global
3601 *******************************************************************************/
3603 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3605 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3607 return (jobjectRefType) NULL;
3611 /* DestroyJavaVM ***************************************************************
3613 Unloads a Java VM and reclaims its resources. Only the main thread
3614 can unload the VM. The system waits until the main thread is only
3615 remaining user thread before it destroys the VM.
3617 *******************************************************************************/
3619 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3623 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3625 if (vm->is_created() == false)
3628 status = vm_destroy(javavm);
3634 /* AttachCurrentThread *********************************************************
3636 Attaches the current thread to a Java VM. Returns a JNI interface
3637 pointer in the JNIEnv argument.
3639 Trying to attach a thread that is already attached is a no-op.
3641 A native thread cannot be attached simultaneously to two Java VMs.
3643 When a thread is attached to the VM, the context class loader is
3644 the bootstrap loader.
3646 *******************************************************************************/
3648 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3650 #if defined(ENABLE_THREADS)
3651 JavaVMAttachArgs *vm_aargs;
3654 /* If the current thread has already been attached, this operation
3657 result = thread_current_is_attached();
3659 if (result == true) {
3660 *p_env = vm->get_jnienv();
3664 vm_aargs = (JavaVMAttachArgs *) thr_args;
3666 if (vm_aargs != NULL) {
3667 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3668 (vm_aargs->version != JNI_VERSION_1_4))
3669 return JNI_EVERSION;
3672 if (!thread_attach_current_external_thread(vm_aargs, false))
3675 if (!localref_table_init())
3679 *p_env = vm->get_jnienv();
3685 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3689 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3691 if (vm->is_created() == false)
3694 result = jni_attach_current_thread(p_env, thr_args, false);
3700 /* DetachCurrentThread *********************************************************
3702 Detaches the current thread from a Java VM. All Java monitors held
3703 by this thread are released. All Java threads waiting for this
3704 thread to die are notified.
3706 In JDK 1.1, the main thread cannot be detached from the VM. It must
3707 call DestroyJavaVM to unload the entire VM.
3709 In the JDK, the main thread can be detached from the VM.
3711 The main thread, which is the thread that created the Java VM,
3712 cannot be detached from the VM. Instead, the main thread must call
3713 JNI_DestroyJavaVM() to unload the entire VM.
3715 *******************************************************************************/
3717 jint jni_DetachCurrentThread(JavaVM *vm)
3719 #if defined(ENABLE_THREADS)
3722 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3724 /* If the current thread has already been detached, this operation
3727 result = thread_current_is_attached();
3729 if (result == false)
3732 /* We need to pop all frames before we can destroy the table. */
3734 localref_frame_pop_all();
3736 if (!localref_table_destroy())
3739 if (!thread_detach_current_external_thread())
3747 /* GetEnv **********************************************************************
3749 If the current thread is not attached to the VM, sets *env to NULL,
3750 and returns JNI_EDETACHED. If the specified version is not
3751 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3752 sets *env to the appropriate interface, and returns JNI_OK.
3754 *******************************************************************************/
3756 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3758 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3760 if (vm->is_created() == false) {
3762 return JNI_EDETACHED;
3765 #if defined(ENABLE_THREADS)
3766 if (thread_get_current() == NULL) {
3769 return JNI_EDETACHED;
3773 /* Check the JNI version. */
3775 if (jni_version_check(version) == true) {
3776 *env = vm->get_jnienv();
3780 #if defined(ENABLE_JVMTI)
3781 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3782 == JVMTI_VERSION_INTERFACE_JVMTI) {
3784 *env = (void *) jvmti_new_environment();
3793 return JNI_EVERSION;
3797 /* AttachCurrentThreadAsDaemon *************************************************
3799 Same semantics as AttachCurrentThread, but the newly-created
3800 java.lang.Thread instance is a daemon.
3802 If the thread has already been attached via either
3803 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3804 simply sets the value pointed to by penv to the JNIEnv of the
3805 current thread. In this case neither AttachCurrentThread nor this
3806 routine have any effect on the daemon status of the thread.
3808 *******************************************************************************/
3810 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3814 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
3816 if (vm->is_created() == false)
3819 result = jni_attach_current_thread(penv, args, true);
3825 /* JNI invocation table *******************************************************/
3827 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3832 _Jv_JNI_DestroyJavaVM,
3833 jni_AttachCurrentThread,
3834 jni_DetachCurrentThread,
3836 jni_AttachCurrentThreadAsDaemon
3840 /* JNI function table *********************************************************/
3842 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3851 jni_FromReflectedMethod,
3852 jni_FromReflectedField,
3853 jni_ToReflectedMethod,
3855 _Jv_JNI_IsAssignableFrom,
3856 _Jv_JNI_ToReflectedField,
3860 _Jv_JNI_ExceptionOccurred,
3861 jni_ExceptionDescribe,
3868 jni_DeleteGlobalRef,
3870 _Jv_JNI_IsSameObject,
3872 jni_EnsureLocalCapacity,
3874 _Jv_JNI_AllocObject,
3880 _Jv_JNI_IsInstanceOf,
3882 _Jv_JNI_GetMethodID,
3884 _Jv_JNI_CallObjectMethod,
3885 _Jv_JNI_CallObjectMethodV,
3886 _Jv_JNI_CallObjectMethodA,
3887 _Jv_JNI_CallBooleanMethod,
3888 _Jv_JNI_CallBooleanMethodV,
3889 _Jv_JNI_CallBooleanMethodA,
3890 _Jv_JNI_CallByteMethod,
3891 _Jv_JNI_CallByteMethodV,
3892 _Jv_JNI_CallByteMethodA,
3893 _Jv_JNI_CallCharMethod,
3894 _Jv_JNI_CallCharMethodV,
3895 _Jv_JNI_CallCharMethodA,
3896 _Jv_JNI_CallShortMethod,
3897 _Jv_JNI_CallShortMethodV,
3898 _Jv_JNI_CallShortMethodA,
3899 _Jv_JNI_CallIntMethod,
3900 _Jv_JNI_CallIntMethodV,
3901 _Jv_JNI_CallIntMethodA,
3902 _Jv_JNI_CallLongMethod,
3903 _Jv_JNI_CallLongMethodV,
3904 _Jv_JNI_CallLongMethodA,
3905 _Jv_JNI_CallFloatMethod,
3906 _Jv_JNI_CallFloatMethodV,
3907 _Jv_JNI_CallFloatMethodA,
3908 _Jv_JNI_CallDoubleMethod,
3909 _Jv_JNI_CallDoubleMethodV,
3910 _Jv_JNI_CallDoubleMethodA,
3911 _Jv_JNI_CallVoidMethod,
3912 _Jv_JNI_CallVoidMethodV,
3913 _Jv_JNI_CallVoidMethodA,
3915 _Jv_JNI_CallNonvirtualObjectMethod,
3916 _Jv_JNI_CallNonvirtualObjectMethodV,
3917 _Jv_JNI_CallNonvirtualObjectMethodA,
3918 _Jv_JNI_CallNonvirtualBooleanMethod,
3919 _Jv_JNI_CallNonvirtualBooleanMethodV,
3920 _Jv_JNI_CallNonvirtualBooleanMethodA,
3921 _Jv_JNI_CallNonvirtualByteMethod,
3922 _Jv_JNI_CallNonvirtualByteMethodV,
3923 _Jv_JNI_CallNonvirtualByteMethodA,
3924 _Jv_JNI_CallNonvirtualCharMethod,
3925 _Jv_JNI_CallNonvirtualCharMethodV,
3926 _Jv_JNI_CallNonvirtualCharMethodA,
3927 _Jv_JNI_CallNonvirtualShortMethod,
3928 _Jv_JNI_CallNonvirtualShortMethodV,
3929 _Jv_JNI_CallNonvirtualShortMethodA,
3930 _Jv_JNI_CallNonvirtualIntMethod,
3931 _Jv_JNI_CallNonvirtualIntMethodV,
3932 _Jv_JNI_CallNonvirtualIntMethodA,
3933 _Jv_JNI_CallNonvirtualLongMethod,
3934 _Jv_JNI_CallNonvirtualLongMethodV,
3935 _Jv_JNI_CallNonvirtualLongMethodA,
3936 _Jv_JNI_CallNonvirtualFloatMethod,
3937 _Jv_JNI_CallNonvirtualFloatMethodV,
3938 _Jv_JNI_CallNonvirtualFloatMethodA,
3939 _Jv_JNI_CallNonvirtualDoubleMethod,
3940 _Jv_JNI_CallNonvirtualDoubleMethodV,
3941 _Jv_JNI_CallNonvirtualDoubleMethodA,
3942 _Jv_JNI_CallNonvirtualVoidMethod,
3943 _Jv_JNI_CallNonvirtualVoidMethodV,
3944 _Jv_JNI_CallNonvirtualVoidMethodA,
3948 _Jv_JNI_GetObjectField,
3949 _Jv_JNI_GetBooleanField,
3950 _Jv_JNI_GetByteField,
3951 _Jv_JNI_GetCharField,
3952 _Jv_JNI_GetShortField,
3953 _Jv_JNI_GetIntField,
3954 _Jv_JNI_GetLongField,
3955 _Jv_JNI_GetFloatField,
3956 _Jv_JNI_GetDoubleField,
3957 _Jv_JNI_SetObjectField,
3958 _Jv_JNI_SetBooleanField,
3959 _Jv_JNI_SetByteField,
3960 _Jv_JNI_SetCharField,
3961 _Jv_JNI_SetShortField,
3962 _Jv_JNI_SetIntField,
3963 _Jv_JNI_SetLongField,
3964 _Jv_JNI_SetFloatField,
3965 _Jv_JNI_SetDoubleField,
3967 _Jv_JNI_GetStaticMethodID,
3969 _Jv_JNI_CallStaticObjectMethod,
3970 _Jv_JNI_CallStaticObjectMethodV,
3971 _Jv_JNI_CallStaticObjectMethodA,
3972 _Jv_JNI_CallStaticBooleanMethod,
3973 _Jv_JNI_CallStaticBooleanMethodV,
3974 _Jv_JNI_CallStaticBooleanMethodA,
3975 _Jv_JNI_CallStaticByteMethod,
3976 _Jv_JNI_CallStaticByteMethodV,
3977 _Jv_JNI_CallStaticByteMethodA,
3978 _Jv_JNI_CallStaticCharMethod,
3979 _Jv_JNI_CallStaticCharMethodV,
3980 _Jv_JNI_CallStaticCharMethodA,
3981 _Jv_JNI_CallStaticShortMethod,
3982 _Jv_JNI_CallStaticShortMethodV,
3983 _Jv_JNI_CallStaticShortMethodA,
3984 _Jv_JNI_CallStaticIntMethod,
3985 _Jv_JNI_CallStaticIntMethodV,
3986 _Jv_JNI_CallStaticIntMethodA,
3987 _Jv_JNI_CallStaticLongMethod,
3988 _Jv_JNI_CallStaticLongMethodV,
3989 _Jv_JNI_CallStaticLongMethodA,
3990 _Jv_JNI_CallStaticFloatMethod,
3991 _Jv_JNI_CallStaticFloatMethodV,
3992 _Jv_JNI_CallStaticFloatMethodA,
3993 _Jv_JNI_CallStaticDoubleMethod,
3994 _Jv_JNI_CallStaticDoubleMethodV,
3995 _Jv_JNI_CallStaticDoubleMethodA,
3996 _Jv_JNI_CallStaticVoidMethod,
3997 _Jv_JNI_CallStaticVoidMethodV,
3998 _Jv_JNI_CallStaticVoidMethodA,
4000 _Jv_JNI_GetStaticFieldID,
4002 _Jv_JNI_GetStaticObjectField,
4003 _Jv_JNI_GetStaticBooleanField,
4004 _Jv_JNI_GetStaticByteField,
4005 _Jv_JNI_GetStaticCharField,
4006 _Jv_JNI_GetStaticShortField,
4007 _Jv_JNI_GetStaticIntField,
4008 _Jv_JNI_GetStaticLongField,
4009 _Jv_JNI_GetStaticFloatField,
4010 _Jv_JNI_GetStaticDoubleField,
4011 _Jv_JNI_SetStaticObjectField,
4012 _Jv_JNI_SetStaticBooleanField,
4013 _Jv_JNI_SetStaticByteField,
4014 _Jv_JNI_SetStaticCharField,
4015 _Jv_JNI_SetStaticShortField,
4016 _Jv_JNI_SetStaticIntField,
4017 _Jv_JNI_SetStaticLongField,
4018 _Jv_JNI_SetStaticFloatField,
4019 _Jv_JNI_SetStaticDoubleField,
4022 jni_GetStringLength,
4024 _Jv_JNI_ReleaseStringChars,
4027 jni_GetStringUTFLength,
4028 _Jv_JNI_GetStringUTFChars,
4029 _Jv_JNI_ReleaseStringUTFChars,
4031 _Jv_JNI_GetArrayLength,
4033 _Jv_JNI_NewObjectArray,
4034 _Jv_JNI_GetObjectArrayElement,
4035 _Jv_JNI_SetObjectArrayElement,
4037 _Jv_JNI_NewBooleanArray,
4038 _Jv_JNI_NewByteArray,
4039 _Jv_JNI_NewCharArray,
4040 _Jv_JNI_NewShortArray,
4041 _Jv_JNI_NewIntArray,
4042 _Jv_JNI_NewLongArray,
4043 _Jv_JNI_NewFloatArray,
4044 _Jv_JNI_NewDoubleArray,
4046 _Jv_JNI_GetBooleanArrayElements,
4047 _Jv_JNI_GetByteArrayElements,
4048 _Jv_JNI_GetCharArrayElements,
4049 _Jv_JNI_GetShortArrayElements,
4050 _Jv_JNI_GetIntArrayElements,
4051 _Jv_JNI_GetLongArrayElements,
4052 _Jv_JNI_GetFloatArrayElements,
4053 _Jv_JNI_GetDoubleArrayElements,
4055 _Jv_JNI_ReleaseBooleanArrayElements,
4056 _Jv_JNI_ReleaseByteArrayElements,
4057 _Jv_JNI_ReleaseCharArrayElements,
4058 _Jv_JNI_ReleaseShortArrayElements,
4059 _Jv_JNI_ReleaseIntArrayElements,
4060 _Jv_JNI_ReleaseLongArrayElements,
4061 _Jv_JNI_ReleaseFloatArrayElements,
4062 _Jv_JNI_ReleaseDoubleArrayElements,
4064 _Jv_JNI_GetBooleanArrayRegion,
4065 _Jv_JNI_GetByteArrayRegion,
4066 _Jv_JNI_GetCharArrayRegion,
4067 _Jv_JNI_GetShortArrayRegion,
4068 _Jv_JNI_GetIntArrayRegion,
4069 _Jv_JNI_GetLongArrayRegion,
4070 _Jv_JNI_GetFloatArrayRegion,
4071 _Jv_JNI_GetDoubleArrayRegion,
4072 _Jv_JNI_SetBooleanArrayRegion,
4073 _Jv_JNI_SetByteArrayRegion,
4074 _Jv_JNI_SetCharArrayRegion,
4075 _Jv_JNI_SetShortArrayRegion,
4076 _Jv_JNI_SetIntArrayRegion,
4077 _Jv_JNI_SetLongArrayRegion,
4078 _Jv_JNI_SetFloatArrayRegion,
4079 _Jv_JNI_SetDoubleArrayRegion,
4081 _Jv_JNI_RegisterNatives,
4082 _Jv_JNI_UnregisterNatives,
4084 _Jv_JNI_MonitorEnter,
4085 _Jv_JNI_MonitorExit,
4089 /* New JNI 1.2 functions. */
4091 jni_GetStringRegion,
4092 jni_GetStringUTFRegion,
4094 jni_GetPrimitiveArrayCritical,
4095 jni_ReleasePrimitiveArrayCritical,
4097 _Jv_JNI_GetStringCritical,
4098 _Jv_JNI_ReleaseStringCritical,
4100 _Jv_JNI_NewWeakGlobalRef,
4101 _Jv_JNI_DeleteWeakGlobalRef,
4103 _Jv_JNI_ExceptionCheck,
4105 /* New JNI 1.4 functions. */
4107 jni_NewDirectByteBuffer,
4108 jni_GetDirectBufferAddress,
4109 jni_GetDirectBufferCapacity,
4111 /* New JNI 1.6 functions. */
4113 jni_GetObjectRefType
4117 /* Invocation API Functions ***************************************************/
4119 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4121 Returns a default configuration for the Java VM.
4123 *******************************************************************************/
4125 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4127 JavaVMInitArgs *_vm_args;
4129 _vm_args = (JavaVMInitArgs *) vm_args;
4131 /* GNU classpath currently supports JNI 1.2 */
4133 switch (_vm_args->version) {
4134 case JNI_VERSION_1_1:
4135 _vm_args->version = JNI_VERSION_1_1;
4138 case JNI_VERSION_1_2:
4139 case JNI_VERSION_1_4:
4140 _vm_args->ignoreUnrecognized = JNI_FALSE;
4141 _vm_args->options = NULL;
4142 _vm_args->nOptions = 0;
4153 /* JNI_GetCreatedJavaVMs *******************************************************
4155 Returns all Java VMs that have been created. Pointers to VMs are written in
4156 the buffer vmBuf in the order they are created. At most bufLen number of
4157 entries will be written. The total number of created VMs is returned in
4160 *******************************************************************************/
4162 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4164 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4169 // We currently only support 1 VM running.
4171 vmBuf[0] = vm->get_javavm();
4178 /* JNI_CreateJavaVM ************************************************************
4180 Loads and initializes a Java VM. The current thread becomes the main thread.
4181 Sets the env argument to the JNI interface pointer of the main thread.
4183 *******************************************************************************/
4185 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4187 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4189 /* actually create the JVM */
4191 if (!VM_create(p_vm, p_env, vm_args))
4201 * These are local overrides for various environment variables in Emacs.
4202 * Please do not remove this and leave it at the end of the file, where
4203 * Emacs will automagically detect them.
4204 * ---------------------------------------------------------------------
4207 * indent-tabs-mode: t
4211 * vim:noexpandtab:sw=4:ts=4: