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_JAVASE)
43 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
44 # include "native/include/gnu_classpath_Pointer.h"
46 # if SIZEOF_VOID_P == 8
47 # include "native/include/gnu_classpath_Pointer64.h"
49 # include "native/include/gnu_classpath_Pointer32.h"
54 #include "native/include/java_lang_Object.h"
55 #include "native/include/java_lang_String.h"
56 #include "native/include/java_lang_Throwable.h"
58 #if defined(ENABLE_JAVASE)
60 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
61 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
64 /* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
65 we pre-define it here to prevent a compiler warning for Sun
68 struct java_lang_ClassLoader;
70 # include "native/include/java_lang_Class.h"
71 # include "native/include/java_lang_ClassLoader.h"
73 # include "native/include/java_lang_reflect_Constructor.h"
74 # include "native/include/java_lang_reflect_Field.h"
75 # include "native/include/java_lang_reflect_Method.h"
77 # include "native/include/java_nio_Buffer.h"
79 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
80 # include "native/include/java_lang_reflect_VMConstructor.h"
81 # include "native/include/java_lang_reflect_VMField.h"
82 # include "native/include/java_lang_reflect_VMMethod.h"
84 # include "native/include/java_nio_DirectByteBufferImpl.h"
86 #elif defined(ENABLE_JAVAME_CLDC1_1)
87 # include "native/include/java_lang_Class.h"
90 #if defined(ENABLE_JVMTI)
91 # include "native/jvmti/cacaodbg.h"
94 #if defined(ENABLE_JAVASE)
95 # include "native/vm/reflect.h"
98 #include "threads/lock-common.h"
99 #include "threads/thread.hpp"
101 #include "toolbox/logging.h"
103 #include "vm/array.h"
104 #include "vm/builtin.h"
105 #include "vm/exceptions.hpp"
106 #include "vm/global.h"
107 #include "vm/initialize.h"
108 #include "vm/primitive.hpp"
109 #include "vm/resolve.h"
110 #include "vm/string.hpp"
113 #include "vm/jit/argument.h"
114 #include "vm/jit/asmpart.h"
115 #include "vm/jit/jit.h"
116 #include "vm/jit/stacktrace.hpp"
118 #include "vmcore/globals.hpp"
119 #include "vmcore/loader.h"
120 #include "vmcore/options.h"
121 #include "vmcore/statistics.h"
124 /* debug **********************************************************************/
128 # define TRACEJNICALLS(x) \
130 if (opt_TraceJNICalls) { \
135 # define TRACEJNICALLSENTER(x) \
137 if (opt_TraceJNICalls) { \
143 # define TRACEJNICALLSEXIT(x) \
145 if (opt_TraceJNICalls) { \
153 # define TRACEJNICALLS(x)
154 # define TRACEJNICALLSENTER(x)
155 # define TRACEJNICALLSEXIT(x)
160 /* global variables ***********************************************************/
162 /* global reference table *****************************************************/
164 /* hashsize must be power of 2 */
166 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
168 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
171 /* direct buffer stuff ********************************************************/
173 #if defined(ENABLE_JAVASE)
174 static classinfo *class_java_nio_Buffer;
176 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
178 static classinfo *class_java_nio_DirectByteBufferImpl;
179 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
181 # if SIZEOF_VOID_P == 8
182 static classinfo *class_gnu_classpath_Pointer64;
184 static classinfo *class_gnu_classpath_Pointer32;
187 static methodinfo *dbbirw_init;
189 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
191 static classinfo *class_sun_nio_ch_DirectBuffer;
192 static classinfo *class_java_nio_DirectByteBuffer;
194 static methodinfo *dbb_init;
200 /* some forward declarations **************************************************/
203 jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
207 /* jni_init ********************************************************************
209 Initialize the JNI subsystem.
211 *******************************************************************************/
215 TRACESUBSYSTEMINITIALIZATION("jni_init");
217 /* create global ref hashtable */
219 hashtable_global_ref = NEW(hashtable);
221 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
224 #if defined(ENABLE_JAVASE)
225 /* Direct buffer stuff. */
227 if (!(class_java_nio_Buffer =
228 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
229 !link_class(class_java_nio_Buffer))
232 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
234 if (!(class_java_nio_DirectByteBufferImpl =
235 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
236 !link_class(class_java_nio_DirectByteBufferImpl))
239 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
240 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
241 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
245 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
247 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
250 # if SIZEOF_VOID_P == 8
251 if (!(class_gnu_classpath_Pointer64 =
252 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
253 !link_class(class_gnu_classpath_Pointer64))
256 if (!(class_gnu_classpath_Pointer32 =
257 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
258 !link_class(class_gnu_classpath_Pointer32))
262 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
264 if (!(class_sun_nio_ch_DirectBuffer =
265 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
266 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
268 if (!link_class(class_sun_nio_ch_DirectBuffer))
269 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
271 if (!(class_java_nio_DirectByteBuffer =
272 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
273 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
275 if (!link_class(class_java_nio_DirectByteBuffer))
276 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
279 class_resolvemethod(class_java_nio_DirectByteBuffer,
281 utf_new_char("(JI)V"))))
282 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
286 #endif /* defined(ENABLE_JAVASE) */
292 /* jni_version_check ***********************************************************
294 Check if the given JNI version is supported.
297 version....JNI version to check
301 false......not supported
303 *******************************************************************************/
305 bool jni_version_check(int version)
308 case JNI_VERSION_1_1:
309 case JNI_VERSION_1_2:
310 case JNI_VERSION_1_4:
311 case JNI_VERSION_1_6:
319 /* _Jv_jni_CallObjectMethod ****************************************************
321 Internal function to call Java Object methods.
323 *******************************************************************************/
325 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
327 methodinfo *m, va_list ap)
332 STATISTICS(jniinvokation());
335 exceptions_throw_nullpointerexception();
339 /* Class initialization is done by the JIT compiler. This is ok
340 since a static method always belongs to the declaring class. */
342 if (m->flags & ACC_STATIC) {
343 /* For static methods we reset the object. */
348 /* for convenience */
353 /* For instance methods we make a virtual function table lookup. */
355 resm = method_vftbl_lookup(vftbl, m);
358 STATISTICS(jnicallXmethodnvokation());
360 ro = vm_call_method_valist(resm, o, ap);
366 /* _Jv_jni_CallObjectMethodA ***************************************************
368 Internal function to call Java Object methods.
370 *******************************************************************************/
372 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
380 STATISTICS(jniinvokation());
383 exceptions_throw_nullpointerexception();
387 /* Class initialization is done by the JIT compiler. This is ok
388 since a static method always belongs to the declaring class. */
390 if (m->flags & ACC_STATIC) {
391 /* For static methods we reset the object. */
396 /* for convenience */
401 /* For instance methods we make a virtual function table lookup. */
403 resm = method_vftbl_lookup(vftbl, m);
406 STATISTICS(jnicallXmethodnvokation());
408 ro = vm_call_method_jvalue(resm, o, args);
414 /* _Jv_jni_CallIntMethod *******************************************************
416 Internal function to call Java integer class methods (boolean,
417 byte, char, short, int).
419 *******************************************************************************/
421 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
422 methodinfo *m, va_list ap)
427 STATISTICS(jniinvokation());
430 exceptions_throw_nullpointerexception();
434 /* Class initialization is done by the JIT compiler. This is ok
435 since a static method always belongs to the declaring class. */
437 if (m->flags & ACC_STATIC) {
438 /* For static methods we reset the object. */
443 /* for convenience */
448 /* For instance methods we make a virtual function table lookup. */
450 resm = method_vftbl_lookup(vftbl, m);
453 STATISTICS(jnicallXmethodnvokation());
455 i = vm_call_method_int_valist(resm, o, ap);
461 /* _Jv_jni_CallIntMethodA ******************************************************
463 Internal function to call Java integer class methods (boolean,
464 byte, char, short, int).
466 *******************************************************************************/
468 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
469 methodinfo *m, const jvalue *args)
474 STATISTICS(jniinvokation());
477 exceptions_throw_nullpointerexception();
481 /* Class initialization is done by the JIT compiler. This is ok
482 since a static method always belongs to the declaring class. */
484 if (m->flags & ACC_STATIC) {
485 /* For static methods we reset the object. */
490 /* for convenience */
495 /* For instance methods we make a virtual function table lookup. */
497 resm = method_vftbl_lookup(vftbl, m);
500 STATISTICS(jnicallXmethodnvokation());
502 i = vm_call_method_int_jvalue(resm, o, args);
508 /* _Jv_jni_CallLongMethod ******************************************************
510 Internal function to call Java long methods.
512 *******************************************************************************/
514 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
515 methodinfo *m, va_list ap)
520 STATISTICS(jniinvokation());
523 exceptions_throw_nullpointerexception();
527 /* Class initialization is done by the JIT compiler. This is ok
528 since a static method always belongs to the declaring class. */
530 if (m->flags & ACC_STATIC) {
531 /* For static methods we reset the object. */
536 /* for convenience */
541 /* For instance methods we make a virtual function table lookup. */
543 resm = method_vftbl_lookup(vftbl, m);
546 STATISTICS(jnicallXmethodnvokation());
548 l = vm_call_method_long_valist(resm, o, ap);
554 /* _Jv_jni_CallLongMethodA *****************************************************
556 Internal function to call Java long methods.
558 *******************************************************************************/
560 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
561 methodinfo *m, const jvalue *args)
566 STATISTICS(jniinvokation());
569 exceptions_throw_nullpointerexception();
573 /* Class initialization is done by the JIT compiler. This is ok
574 since a static method always belongs to the declaring class. */
576 if (m->flags & ACC_STATIC) {
577 /* For static methods we reset the object. */
582 /* for convenience */
587 /* For instance methods we make a virtual function table lookup. */
589 resm = method_vftbl_lookup(vftbl, m);
592 STATISTICS(jnicallXmethodnvokation());
594 l = vm_call_method_long_jvalue(resm, o, args);
600 /* _Jv_jni_CallFloatMethod *****************************************************
602 Internal function to call Java float methods.
604 *******************************************************************************/
606 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
607 methodinfo *m, va_list ap)
612 /* Class initialization is done by the JIT compiler. This is ok
613 since a static method always belongs to the declaring class. */
615 if (m->flags & ACC_STATIC) {
616 /* For static methods we reset the object. */
621 /* for convenience */
626 /* For instance methods we make a virtual function table lookup. */
628 resm = method_vftbl_lookup(vftbl, m);
631 STATISTICS(jnicallXmethodnvokation());
633 f = vm_call_method_float_valist(resm, o, ap);
639 /* _Jv_jni_CallFloatMethodA ****************************************************
641 Internal function to call Java float methods.
643 *******************************************************************************/
645 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
646 methodinfo *m, const jvalue *args)
651 /* Class initialization is done by the JIT compiler. This is ok
652 since a static method always belongs to the declaring class. */
654 if (m->flags & ACC_STATIC) {
655 /* For static methods we reset the object. */
660 /* for convenience */
665 /* For instance methods we make a virtual function table lookup. */
667 resm = method_vftbl_lookup(vftbl, m);
670 STATISTICS(jnicallXmethodnvokation());
672 f = vm_call_method_float_jvalue(resm, o, args);
678 /* _Jv_jni_CallDoubleMethod ****************************************************
680 Internal function to call Java double methods.
682 *******************************************************************************/
684 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
685 methodinfo *m, va_list ap)
690 /* Class initialization is done by the JIT compiler. This is ok
691 since a static method always belongs to the declaring class. */
693 if (m->flags & ACC_STATIC) {
694 /* For static methods we reset the object. */
699 /* for convenience */
704 /* For instance methods we make a virtual function table lookup. */
706 resm = method_vftbl_lookup(vftbl, m);
709 d = vm_call_method_double_valist(resm, o, ap);
715 /* _Jv_jni_CallDoubleMethodA ***************************************************
717 Internal function to call Java double methods.
719 *******************************************************************************/
721 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
722 methodinfo *m, const jvalue *args)
727 /* Class initialization is done by the JIT compiler. This is ok
728 since a static method always belongs to the declaring class. */
730 if (m->flags & ACC_STATIC) {
731 /* For static methods we reset the object. */
736 /* for convenience */
741 /* For instance methods we make a virtual function table lookup. */
743 resm = method_vftbl_lookup(vftbl, m);
746 d = vm_call_method_double_jvalue(resm, o, args);
752 /* _Jv_jni_CallVoidMethod ******************************************************
754 Internal function to call Java void methods.
756 *******************************************************************************/
758 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
759 methodinfo *m, va_list ap)
764 exceptions_throw_nullpointerexception();
768 /* Class initialization is done by the JIT compiler. This is ok
769 since a static method always belongs to the declaring class. */
771 if (m->flags & ACC_STATIC) {
772 /* For static methods we reset the object. */
777 /* for convenience */
782 /* For instance methods we make a virtual function table lookup. */
784 resm = method_vftbl_lookup(vftbl, m);
787 STATISTICS(jnicallXmethodnvokation());
789 (void) vm_call_method_valist(resm, o, ap);
793 /* _Jv_jni_CallVoidMethodA *****************************************************
795 Internal function to call Java void methods.
797 *******************************************************************************/
799 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
800 methodinfo *m, const jvalue *args)
805 exceptions_throw_nullpointerexception();
809 /* Class initialization is done by the JIT compiler. This is ok
810 since a static method always belongs to the declaring class. */
812 if (m->flags & ACC_STATIC) {
813 /* For static methods we reset the object. */
818 /* for convenience */
823 /* For instance methods we make a virtual function table lookup. */
825 resm = method_vftbl_lookup(vftbl, m);
828 STATISTICS(jnicallXmethodnvokation());
830 (void) vm_call_method_jvalue(resm, o, args);
834 // JNI functions are exported as C functions.
837 /* GetVersion ******************************************************************
839 Returns the major version number in the higher 16 bits and the
840 minor version number in the lower 16 bits.
842 *******************************************************************************/
844 jint _Jv_JNI_GetVersion(JNIEnv *env)
846 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
848 /* We support JNI 1.6. */
850 return JNI_VERSION_1_6;
854 /* Class Operations ***********************************************************/
856 /* DefineClass *****************************************************************
858 Loads a class from a buffer of raw class data. The buffer
859 containing the raw class data is not referenced by the VM after the
860 DefineClass call returns, and it may be discarded if desired.
862 *******************************************************************************/
864 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
865 const jbyte *buf, jsize bufLen)
867 #if defined(ENABLE_JAVASE)
873 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
875 u = utf_new_char(name);
876 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
878 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
880 co = LLNI_classinfo_wrap(c);
882 return (jclass) jni_NewLocalRef(env, (jobject) co);
884 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
886 /* keep compiler happy */
893 /* FindClass *******************************************************************
895 This function loads a locally-defined class. It searches the
896 directories and zip files specified by the CLASSPATH environment
897 variable for the class with the specified name.
899 *******************************************************************************/
901 jclass jni_FindClass(JNIEnv *env, const char *name)
903 #if defined(ENABLE_JAVASE)
910 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
912 /* FIXME If name is NULL we have a problem here. */
914 u = utf_new_char_classname((char *) name);
916 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
917 exceptions_throw_noclassdeffounderror(u);
921 /* Check stacktrace for classloader, if one found use it,
922 otherwise use the system classloader. */
924 /* Quote from the JNI documentation:
926 In the Java 2 Platform, FindClass locates the class loader
927 associated with the current native method. If the native code
928 belongs to a system class, no class loader will be
929 involved. Otherwise, the proper class loader will be invoked to
930 load and link the named class. When FindClass is called through
931 the Invocation Interface, there is no current native method or
932 its associated class loader. In that case, the result of
933 ClassLoader.getBaseClassLoader is used." */
935 cc = stacktrace_get_current_class();
938 c = load_class_from_sysloader(u);
940 c = load_class_from_classloader(u, cc->classloader);
943 resolve_handle_pending_exception(true);
950 co = LLNI_classinfo_wrap(c);
952 return (jclass) jni_NewLocalRef(env, (jobject) co);
954 #elif defined(ENABLE_JAVAME_CLDC1_1)
959 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
961 u = utf_new_char_classname((char *) name);
962 c = load_class_bootstrap(u);
965 resolve_handle_pending_exception(true);
972 return (jclass) jni_NewLocalRef(env, (jobject) c);
975 vm_abort("jni_FindClass: not implemented in this configuration");
977 /* keep compiler happy */
984 /* GetSuperclass ***************************************************************
986 If clazz represents any class other than the class Object, then
987 this function returns the object that represents the superclass of
988 the class specified by clazz.
990 *******************************************************************************/
992 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
998 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
1000 c = LLNI_classinfo_unwrap(sub);
1005 super = class_get_superclass(c);
1007 co = LLNI_classinfo_wrap(super);
1009 return (jclass) jni_NewLocalRef(env, (jobject) co);
1013 /* IsAssignableFrom ************************************************************
1015 Determines whether an object of sub can be safely cast to sup.
1017 *******************************************************************************/
1019 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1024 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
1026 to = (classinfo *) sup;
1027 from = (classinfo *) sub;
1029 return class_is_assignable_from(to, from);
1033 /* Throw ***********************************************************************
1035 Causes a java.lang.Throwable object to be thrown.
1037 *******************************************************************************/
1039 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1043 STATISTICS(jniinvokation());
1045 o = (java_handle_t *) obj;
1047 exceptions_set_exception(o);
1053 /* ThrowNew ********************************************************************
1055 Constructs an exception object from the specified class with the
1056 message specified by message and causes that exception to be
1059 *******************************************************************************/
1061 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1067 STATISTICS(jniinvokation());
1069 c = LLNI_classinfo_unwrap(clazz);
1072 s = javastring_new_from_utf_string(msg);
1074 /* instantiate exception object */
1076 o = native_new_and_init_string(c, s);
1081 exceptions_set_exception(o);
1087 /* ExceptionOccurred ***********************************************************
1089 Determines if an exception is being thrown. The exception stays
1090 being thrown until either the native code calls ExceptionClear(),
1091 or the Java code handles the exception.
1093 *******************************************************************************/
1095 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1099 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1101 o = exceptions_get_exception();
1103 return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1107 /* ExceptionDescribe ***********************************************************
1109 Prints an exception and a backtrace of the stack to a system
1110 error-reporting channel, such as stderr. This is a convenience
1111 routine provided for debugging.
1113 *******************************************************************************/
1115 void jni_ExceptionDescribe(JNIEnv *env)
1117 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1119 exceptions_print_stacktrace();
1123 /* ExceptionClear **************************************************************
1125 Clears any exception that is currently being thrown. If no
1126 exception is currently being thrown, this routine has no effect.
1128 *******************************************************************************/
1130 void jni_ExceptionClear(JNIEnv *env)
1132 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1134 exceptions_clear_exception();
1138 /* FatalError ******************************************************************
1140 Raises a fatal error and does not expect the VM to recover. This
1141 function does not return.
1143 *******************************************************************************/
1145 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1147 STATISTICS(jniinvokation());
1149 /* this seems to be the best way */
1151 vm_abort("JNI Fatal error: %s", msg);
1155 /* PushLocalFrame **************************************************************
1157 Creates a new local reference frame, in which at least a given
1158 number of local references can be created.
1160 *******************************************************************************/
1162 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1164 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1169 /* add new local reference frame to current table */
1171 if (!localref_frame_push(capacity))
1178 /* PopLocalFrame ***************************************************************
1180 Pops off the current local reference frame, frees all the local
1181 references, and returns a local reference in the previous local
1182 reference frame for the given result object.
1184 *******************************************************************************/
1186 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1188 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1190 /* release all current local frames */
1192 localref_frame_pop_all();
1194 /* add local reference and return the value */
1196 return jni_NewLocalRef(env, result);
1200 /* DeleteLocalRef **************************************************************
1202 Deletes the local reference pointed to by localRef.
1204 *******************************************************************************/
1206 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1210 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1212 o = (java_handle_t *) localRef;
1217 /* delete the reference */
1223 /* IsSameObject ****************************************************************
1225 Tests whether two references refer to the same Java object.
1227 *******************************************************************************/
1229 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1235 STATISTICS(jniinvokation());
1237 o1 = (java_handle_t *) ref1;
1238 o2 = (java_handle_t *) ref2;
1240 LLNI_CRITICAL_START;
1242 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1253 /* NewLocalRef *****************************************************************
1255 Creates a new local reference that refers to the same object as ref.
1257 *******************************************************************************/
1259 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1262 java_handle_t *localref;
1264 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1266 o = (java_handle_t *) ref;
1271 /* insert the reference */
1273 localref = localref_add(LLNI_DIRECT(o));
1275 return (jobject) localref;
1279 /* EnsureLocalCapacity *********************************************************
1281 Ensures that at least a given number of local references can be
1282 created in the current thread
1284 *******************************************************************************/
1286 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1288 localref_table *lrt;
1290 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1292 /* get local reference table (thread specific) */
1294 lrt = LOCALREFTABLE;
1296 /* check if capacity elements are available in the local references table */
1298 if ((lrt->used + capacity) > lrt->capacity)
1299 return jni_PushLocalFrame(env, capacity);
1305 /* AllocObject *****************************************************************
1307 Allocates a new Java object without invoking any of the
1308 constructors for the object. Returns a reference to the object.
1310 *******************************************************************************/
1312 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1317 STATISTICS(jniinvokation());
1319 c = LLNI_classinfo_unwrap(clazz);
1321 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1322 exceptions_throw_instantiationexception(c);
1328 return jni_NewLocalRef(env, (jobject) o);
1332 /* NewObject *******************************************************************
1334 Programmers place all arguments that are to be passed to the
1335 constructor immediately following the methodID
1336 argument. NewObject() accepts these arguments and passes them to
1337 the Java method that the programmer wishes to invoke.
1339 *******************************************************************************/
1341 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1348 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1350 c = LLNI_classinfo_unwrap(clazz);
1351 m = (methodinfo *) methodID;
1360 /* call constructor */
1362 va_start(ap, methodID);
1363 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1366 TRACEJNICALLSEXIT(("->%p", o));
1368 return jni_NewLocalRef(env, (jobject) o);
1372 /* NewObjectV ******************************************************************
1374 Programmers place all arguments that are to be passed to the
1375 constructor in an args argument of type va_list that immediately
1376 follows the methodID argument. NewObjectV() accepts these
1377 arguments, and, in turn, passes them to the Java method that the
1378 programmer wishes to invoke.
1380 *******************************************************************************/
1382 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1389 STATISTICS(jniinvokation());
1391 c = LLNI_classinfo_unwrap(clazz);
1392 m = (methodinfo *) methodID;
1401 /* call constructor */
1403 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1405 return jni_NewLocalRef(env, (jobject) o);
1409 /* NewObjectA *****************************************************************
1411 Programmers place all arguments that are to be passed to the
1412 constructor in an args array of jvalues that immediately follows
1413 the methodID argument. NewObjectA() accepts the arguments in this
1414 array, and, in turn, passes them to the Java method that the
1415 programmer wishes to invoke.
1417 *******************************************************************************/
1419 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1426 STATISTICS(jniinvokation());
1428 c = LLNI_classinfo_unwrap(clazz);
1429 m = (methodinfo *) methodID;
1438 /* call constructor */
1440 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1442 return jni_NewLocalRef(env, (jobject) o);
1446 /* GetObjectClass **************************************************************
1448 Returns the class of an object.
1450 *******************************************************************************/
1452 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1456 java_lang_Class *co;
1458 STATISTICS(jniinvokation());
1460 o = (java_handle_t *) obj;
1462 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1465 LLNI_class_get(o, c);
1467 co = LLNI_classinfo_wrap(c);
1469 return (jclass) jni_NewLocalRef(env, (jobject) co);
1473 /* IsInstanceOf ****************************************************************
1475 Tests whether an object is an instance of a class.
1477 *******************************************************************************/
1479 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1484 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1486 /* XXX Is this correct? */
1487 c = LLNI_classinfo_unwrap(clazz);
1488 h = (java_handle_t *) obj;
1490 return class_is_instance(c, h);
1494 /* Reflection Support *********************************************************/
1496 /* FromReflectedMethod *********************************************************
1498 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1499 object to a method ID.
1501 *******************************************************************************/
1503 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1505 #if defined(ENABLE_JAVASE)
1507 java_lang_reflect_Method *rm;
1508 java_lang_reflect_Constructor *rc;
1513 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1514 java_lang_reflect_VMMethod *rvmm;
1515 java_lang_reflect_VMConstructor *rvmc;
1518 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1520 o = (java_handle_t *) method;
1525 if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
1526 rc = (java_lang_reflect_Constructor *) method;
1528 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1530 LLNI_field_get_ref(rc, cons , rvmc);
1531 LLNI_field_get_cls(rvmc, clazz, c);
1532 LLNI_field_get_val(rvmc, slot , slot);
1534 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1536 LLNI_field_get_cls(rc, clazz, c);
1537 LLNI_field_get_val(rc, slot , slot);
1540 # error unknown configuration
1544 assert(o->vftbl->clazz == class_java_lang_reflect_Method);
1546 rm = (java_lang_reflect_Method *) method;
1548 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1550 LLNI_field_get_ref(rm, m , rvmm);
1551 LLNI_field_get_cls(rvmm, clazz, c);
1552 LLNI_field_get_val(rvmm, slot , slot);
1554 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1556 LLNI_field_get_cls(rm, clazz, c);
1557 LLNI_field_get_val(rm, slot , slot);
1560 # error unknown configuration
1564 m = &(c->methods[slot]);
1566 return (jmethodID) m;
1568 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1570 /* Keep compiler happy. */
1577 /* FromReflectedField **********************************************************
1579 Converts a java.lang.reflect.Field to a field ID.
1581 *******************************************************************************/
1583 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1585 #if defined(ENABLE_JAVASE)
1586 java_lang_reflect_Field *rf;
1591 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1592 java_lang_reflect_VMField *rvmf;
1595 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1597 rf = (java_lang_reflect_Field *) field;
1602 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1604 LLNI_field_get_ref(rf, f, rvmf);
1605 LLNI_field_get_cls(rvmf, clazz, c);
1606 LLNI_field_get_val(rvmf, slot , slot);
1608 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1610 LLNI_field_get_cls(rf, clazz, c);
1611 LLNI_field_get_val(rf, slot , slot);
1614 # error unknown configuration
1617 f = &(c->fields[slot]);
1619 return (jfieldID) f;
1621 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1623 /* Keep compiler happy. */
1630 /* ToReflectedMethod ***********************************************************
1632 Converts a method ID derived from cls to an instance of the
1633 java.lang.reflect.Method class or to an instance of the
1634 java.lang.reflect.Constructor class.
1636 *******************************************************************************/
1638 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1641 #if defined(ENABLE_JAVASE)
1643 java_lang_reflect_Constructor *rc;
1644 java_lang_reflect_Method *rm;
1646 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1648 m = (methodinfo *) methodID;
1650 /* HotSpot does the same assert. */
1652 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1654 if (m->name == utf_init) {
1655 rc = reflect_constructor_new(m);
1657 return (jobject) rc;
1660 rm = reflect_method_new(m);
1662 return (jobject) rm;
1665 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1667 /* keep compiler happy */
1674 /* ToReflectedField ************************************************************
1676 Converts a field ID derived from cls to an instance of the
1677 java.lang.reflect.Field class.
1679 *******************************************************************************/
1681 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1684 STATISTICS(jniinvokation());
1686 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1692 /* Calling Instance Methods ***************************************************/
1694 /* GetMethodID *****************************************************************
1696 Returns the method ID for an instance (nonstatic) method of a class
1697 or interface. The method may be defined in one of the clazz's
1698 superclasses and inherited by clazz. The method is determined by
1699 its name and signature.
1701 GetMethodID() causes an uninitialized class to be initialized.
1703 *******************************************************************************/
1705 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1713 STATISTICS(jniinvokation());
1715 c = LLNI_classinfo_unwrap(clazz);
1720 if (!(c->state & CLASS_INITIALIZED))
1721 if (!initialize_class(c))
1724 /* try to get the method of the class or one of it's superclasses */
1726 uname = utf_new_char((char *) name);
1727 udesc = utf_new_char((char *) sig);
1729 m = class_resolvemethod(c, uname, udesc);
1731 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1732 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1737 return (jmethodID) m;
1741 /* JNI-functions for calling instance methods *********************************/
1743 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1744 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1745 jmethodID methodID, ...) \
1752 o = (java_handle_t *) obj; \
1753 m = (methodinfo *) methodID; \
1755 va_start(ap, methodID); \
1756 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1762 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1763 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1764 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1765 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1766 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1767 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1768 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1769 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1772 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1773 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1774 jmethodID methodID, va_list args) \
1780 o = (java_handle_t *) obj; \
1781 m = (methodinfo *) methodID; \
1783 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1788 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1789 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1790 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1791 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1792 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1793 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1794 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1795 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1798 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1799 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1800 jmethodID methodID, \
1801 const jvalue *args) \
1807 o = (java_handle_t *) obj; \
1808 m = (methodinfo *) methodID; \
1810 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1815 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1816 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1817 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1818 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1819 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1820 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1821 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1822 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1825 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1833 o = (java_handle_t *) obj;
1834 m = (methodinfo *) methodID;
1836 va_start(ap, methodID);
1837 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1840 return jni_NewLocalRef(env, (jobject) ret);
1844 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1851 o = (java_handle_t *) obj;
1852 m = (methodinfo *) methodID;
1854 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1856 return jni_NewLocalRef(env, (jobject) ret);
1860 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1867 o = (java_handle_t *) obj;
1868 m = (methodinfo *) methodID;
1870 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1872 return jni_NewLocalRef(env, (jobject) ret);
1877 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1883 o = (java_handle_t *) obj;
1884 m = (methodinfo *) methodID;
1886 va_start(ap, methodID);
1887 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1892 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1898 o = (java_handle_t *) obj;
1899 m = (methodinfo *) methodID;
1901 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1905 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1911 o = (java_handle_t *) obj;
1912 m = (methodinfo *) methodID;
1914 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1919 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1920 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1921 jclass clazz, jmethodID methodID, \
1930 o = (java_handle_t *) obj; \
1931 c = LLNI_classinfo_unwrap(clazz); \
1932 m = (methodinfo *) methodID; \
1934 va_start(ap, methodID); \
1935 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1941 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1942 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1943 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1944 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1945 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1946 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1947 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1948 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1951 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1952 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1953 jclass clazz, jmethodID methodID, \
1961 o = (java_handle_t *) obj; \
1962 c = LLNI_classinfo_unwrap(clazz); \
1963 m = (methodinfo *) methodID; \
1965 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1970 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1971 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1972 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1973 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1974 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1975 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1976 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1977 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1980 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1981 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1982 jclass clazz, jmethodID methodID, \
1983 const jvalue *args) \
1985 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1990 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1991 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1992 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1993 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1994 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1995 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1996 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1997 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1999 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2000 jclass clazz, jmethodID methodID,
2009 o = (java_handle_t *) obj;
2010 c = LLNI_classinfo_unwrap(clazz);
2011 m = (methodinfo *) methodID;
2013 va_start(ap, methodID);
2014 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2017 return jni_NewLocalRef(env, (jobject) r);
2021 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2022 jclass clazz, jmethodID methodID,
2030 o = (java_handle_t *) obj;
2031 c = LLNI_classinfo_unwrap(clazz);
2032 m = (methodinfo *) methodID;
2034 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2036 return jni_NewLocalRef(env, (jobject) r);
2040 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2041 jclass clazz, jmethodID methodID,
2044 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2046 return jni_NewLocalRef(env, NULL);
2050 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2051 jmethodID methodID, ...)
2058 o = (java_handle_t *) obj;
2059 c = LLNI_classinfo_unwrap(clazz);
2060 m = (methodinfo *) methodID;
2062 va_start(ap, methodID);
2063 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2068 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2069 jmethodID methodID, va_list args)
2075 o = (java_handle_t *) obj;
2076 c = LLNI_classinfo_unwrap(clazz);
2077 m = (methodinfo *) methodID;
2079 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2083 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2084 jmethodID methodID, const jvalue * args)
2090 o = (java_handle_t *) obj;
2091 c = LLNI_classinfo_unwrap(clazz);
2092 m = (methodinfo *) methodID;
2094 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2098 /* Accessing Fields of Objects ************************************************/
2100 /* GetFieldID ******************************************************************
2102 Returns the field ID for an instance (nonstatic) field of a
2103 class. The field is specified by its name and signature. The
2104 Get<type>Field and Set<type>Field families of accessor functions
2105 use field IDs to retrieve object fields.
2107 *******************************************************************************/
2109 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2117 STATISTICS(jniinvokation());
2119 c = LLNI_classinfo_unwrap(clazz);
2121 /* XXX NPE check? */
2123 uname = utf_new_char((char *) name);
2124 udesc = utf_new_char((char *) sig);
2126 f = class_findfield(c, uname, udesc);
2129 exceptions_throw_nosuchfielderror(c, uname);
2131 return (jfieldID) f;
2135 /* Get<type>Field Routines *****************************************************
2137 This family of accessor routines returns the value of an instance
2138 (nonstatic) field of an object. The field to access is specified by
2139 a field ID obtained by calling GetFieldID().
2141 *******************************************************************************/
2143 #define GET_FIELD(o,type,f) \
2144 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2146 #define JNI_GET_FIELD(name, type, intern) \
2147 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2151 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2153 LLNI_CRITICAL_START; \
2155 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2157 LLNI_CRITICAL_END; \
2159 return (type) ret; \
2162 JNI_GET_FIELD(Boolean, jboolean, s4)
2163 JNI_GET_FIELD(Byte, jbyte, s4)
2164 JNI_GET_FIELD(Char, jchar, s4)
2165 JNI_GET_FIELD(Short, jshort, s4)
2166 JNI_GET_FIELD(Int, jint, s4)
2167 JNI_GET_FIELD(Long, jlong, s8)
2168 JNI_GET_FIELD(Float, jfloat, float)
2169 JNI_GET_FIELD(Double, jdouble, double)
2172 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2176 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2178 LLNI_CRITICAL_START;
2180 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2184 return jni_NewLocalRef(env, (jobject) o);
2188 /* Set<type>Field Routines *****************************************************
2190 This family of accessor routines sets the value of an instance
2191 (nonstatic) field of an object. The field to access is specified by
2192 a field ID obtained by calling GetFieldID().
2194 *******************************************************************************/
2196 #define SET_FIELD(o,type,f,value) \
2197 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2199 #define JNI_SET_FIELD(name, type, intern) \
2200 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2203 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2205 LLNI_CRITICAL_START; \
2207 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2209 LLNI_CRITICAL_START; \
2212 JNI_SET_FIELD(Boolean, jboolean, s4)
2213 JNI_SET_FIELD(Byte, jbyte, s4)
2214 JNI_SET_FIELD(Char, jchar, s4)
2215 JNI_SET_FIELD(Short, jshort, s4)
2216 JNI_SET_FIELD(Int, jint, s4)
2217 JNI_SET_FIELD(Long, jlong, s8)
2218 JNI_SET_FIELD(Float, jfloat, float)
2219 JNI_SET_FIELD(Double, jdouble, double)
2222 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2225 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2227 LLNI_CRITICAL_START;
2229 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2235 /* Calling Static Methods *****************************************************/
2237 /* GetStaticMethodID ***********************************************************
2239 Returns the method ID for a static method of a class. The method is
2240 specified by its name and signature.
2242 GetStaticMethodID() causes an uninitialized class to be
2245 *******************************************************************************/
2247 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2255 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2257 c = LLNI_classinfo_unwrap(clazz);
2262 if (!(c->state & CLASS_INITIALIZED))
2263 if (!initialize_class(c))
2266 /* try to get the static method of the class */
2268 uname = utf_new_char((char *) name);
2269 udesc = utf_new_char((char *) sig);
2271 m = class_resolvemethod(c, uname, udesc);
2273 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2274 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2279 return (jmethodID) m;
2283 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2284 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2285 jmethodID methodID, ...) \
2291 m = (methodinfo *) methodID; \
2293 va_start(ap, methodID); \
2294 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2300 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2301 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2302 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2303 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2304 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2305 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2306 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2307 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2310 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2311 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2312 jmethodID methodID, va_list args) \
2317 m = (methodinfo *) methodID; \
2319 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2324 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2325 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2326 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2327 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2328 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2329 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2330 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2331 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2334 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2335 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2336 jmethodID methodID, const jvalue *args) \
2341 m = (methodinfo *) methodID; \
2343 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2348 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2349 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2350 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2351 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2352 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2353 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2354 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2355 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2358 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2359 jmethodID methodID, ...)
2365 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2367 m = (methodinfo *) methodID;
2369 va_start(ap, methodID);
2370 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2373 return jni_NewLocalRef(env, (jobject) o);
2377 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2378 jmethodID methodID, va_list args)
2383 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2385 m = (methodinfo *) methodID;
2387 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2389 return jni_NewLocalRef(env, (jobject) o);
2393 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2394 jmethodID methodID, const jvalue *args)
2399 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2401 m = (methodinfo *) methodID;
2403 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2405 return jni_NewLocalRef(env, (jobject) o);
2409 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2410 jmethodID methodID, ...)
2415 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2417 m = (methodinfo *) methodID;
2419 va_start(ap, methodID);
2420 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2425 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2426 jmethodID methodID, va_list args)
2430 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2432 m = (methodinfo *) methodID;
2434 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2438 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2439 jmethodID methodID, const jvalue * args)
2443 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2445 m = (methodinfo *) methodID;
2447 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2451 /* Accessing Static Fields ****************************************************/
2453 /* GetStaticFieldID ************************************************************
2455 Returns the field ID for a static field of a class. The field is
2456 specified by its name and signature. The GetStatic<type>Field and
2457 SetStatic<type>Field families of accessor functions use field IDs
2458 to retrieve static fields.
2460 *******************************************************************************/
2462 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2470 STATISTICS(jniinvokation());
2472 c = LLNI_classinfo_unwrap(clazz);
2474 uname = utf_new_char((char *) name);
2475 usig = utf_new_char((char *) sig);
2477 f = class_findfield(c, uname, usig);
2480 exceptions_throw_nosuchfielderror(c, uname);
2482 return (jfieldID) f;
2486 /* GetStatic<type>Field ********************************************************
2488 This family of accessor routines returns the value of a static
2491 *******************************************************************************/
2493 #define JNI_GET_STATIC_FIELD(name, type, field) \
2494 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2500 STATISTICS(jniinvokation()); \
2502 c = LLNI_classinfo_unwrap(clazz); \
2503 f = (fieldinfo *) fieldID; \
2505 if (!(c->state & CLASS_INITIALIZED)) \
2506 if (!initialize_class(c)) \
2509 return f->value->field; \
2512 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2513 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2514 JNI_GET_STATIC_FIELD(Char, jchar, i)
2515 JNI_GET_STATIC_FIELD(Short, jshort, i)
2516 JNI_GET_STATIC_FIELD(Int, jint, i)
2517 JNI_GET_STATIC_FIELD(Long, jlong, l)
2518 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2519 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2522 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2529 STATISTICS(jniinvokation());
2531 c = LLNI_classinfo_unwrap(clazz);
2532 f = (fieldinfo *) fieldID;
2534 if (!(c->state & CLASS_INITIALIZED))
2535 if (!initialize_class(c))
2538 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2540 return jni_NewLocalRef(env, (jobject) h);
2544 /* SetStatic<type>Field *******************************************************
2546 This family of accessor routines sets the value of a static field
2549 *******************************************************************************/
2551 #define JNI_SET_STATIC_FIELD(name, type, field) \
2552 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2559 STATISTICS(jniinvokation()); \
2561 c = LLNI_classinfo_unwrap(clazz); \
2562 f = (fieldinfo *) fieldID; \
2564 if (!(c->state & CLASS_INITIALIZED)) \
2565 if (!initialize_class(c)) \
2568 f->value->field = value; \
2571 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2572 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2573 JNI_SET_STATIC_FIELD(Char, jchar, i)
2574 JNI_SET_STATIC_FIELD(Short, jshort, i)
2575 JNI_SET_STATIC_FIELD(Int, jint, i)
2576 JNI_SET_STATIC_FIELD(Long, jlong, l)
2577 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2578 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2581 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2587 STATISTICS(jniinvokation());
2589 c = LLNI_classinfo_unwrap(clazz);
2590 f = (fieldinfo *) fieldID;
2592 if (!(c->state & CLASS_INITIALIZED))
2593 if (!initialize_class(c))
2596 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2600 /* String Operations **********************************************************/
2602 /* NewString *******************************************************************
2604 Create new java.lang.String object from an array of Unicode
2607 *******************************************************************************/
2609 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2611 java_lang_String *s;
2612 java_handle_chararray_t *a;
2615 STATISTICS(jniinvokation());
2617 s = (java_lang_String *) builtin_new(class_java_lang_String);
2618 a = builtin_newarray_char(len);
2620 /* javastring or characterarray could not be created */
2621 if ((a == NULL) || (s == NULL))
2625 for (i = 0; i < len; i++)
2626 LLNI_array_direct(a, i) = buf[i];
2628 LLNI_field_set_ref(s, value , a);
2629 LLNI_field_set_val(s, offset, 0);
2630 LLNI_field_set_val(s, count , len);
2632 return (jstring) jni_NewLocalRef(env, (jobject) s);
2636 static jchar emptyStringJ[]={0,0};
2638 /* GetStringLength *************************************************************
2640 Returns the length (the count of Unicode characters) of a Java
2643 *******************************************************************************/
2645 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2647 java_lang_String *s;
2650 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2652 s = (java_lang_String *) str;
2654 LLNI_field_get_val(s, count, len);
2660 /* GetStringChars **************************************************************
2662 Returns a pointer to the array of Unicode characters of the
2663 string. This pointer is valid until ReleaseStringChars() is called.
2665 *******************************************************************************/
2667 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2669 java_lang_String *s;
2670 java_handle_chararray_t *a;
2676 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2679 // FIXME This is really ugly.
2680 return emptyStringJ;
2682 s = (java_lang_String *) str;
2684 LLNI_field_get_ref(s, value, a);
2689 LLNI_field_get_val(s, count, count);
2690 LLNI_field_get_val(s, offset, offset);
2692 /* allocate memory */
2694 stringbuffer = MNEW(u2, count + 1);
2698 for (i = 0; i < count; i++)
2699 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2701 /* terminate string */
2703 stringbuffer[i] = '\0';
2708 return (jchar*) stringbuffer;
2712 /* ReleaseStringChars **********************************************************
2714 Informs the VM that the native code no longer needs access to
2715 chars. The chars argument is a pointer obtained from string using
2718 *******************************************************************************/
2720 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2722 java_lang_String *s;
2724 STATISTICS(jniinvokation());
2726 if (chars == emptyStringJ)
2729 s = (java_lang_String *) str;
2731 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2735 /* NewStringUTF ****************************************************************
2737 Constructs a new java.lang.String object from an array of UTF-8
2740 *******************************************************************************/
2742 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2744 java_lang_String *s;
2746 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2748 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2750 return (jstring) jni_NewLocalRef(env, (jobject) s);
2754 /****************** returns the utf8 length in bytes of a string *******************/
2756 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2758 java_lang_String *s;
2761 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2763 s = (java_lang_String *) string;
2765 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2771 /* GetStringUTFChars ***********************************************************
2773 Returns a pointer to an array of UTF-8 characters of the
2774 string. This array is valid until it is released by
2775 ReleaseStringUTFChars().
2777 *******************************************************************************/
2779 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2784 STATISTICS(jniinvokation());
2792 u = javastring_toutf((java_handle_t *) string, false);
2801 /* ReleaseStringUTFChars *******************************************************
2803 Informs the VM that the native code no longer needs access to
2804 utf. The utf argument is a pointer derived from string using
2805 GetStringUTFChars().
2807 *******************************************************************************/
2809 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2811 STATISTICS(jniinvokation());
2813 /* XXX we don't release utf chars right now, perhaps that should be done
2814 later. Since there is always one reference the garbage collector will
2819 /* Array Operations ***********************************************************/
2821 /* GetArrayLength **************************************************************
2823 Returns the number of elements in the array.
2825 *******************************************************************************/
2827 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2832 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2834 a = (java_handle_t *) array;
2836 size = LLNI_array_size(a);
2842 /* NewObjectArray **************************************************************
2844 Constructs a new array holding objects in class elementClass. All
2845 elements are initially set to initialElement.
2847 *******************************************************************************/
2849 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2850 jclass elementClass, jobject initialElement)
2854 java_handle_objectarray_t *oa;
2857 STATISTICS(jniinvokation());
2859 c = LLNI_classinfo_unwrap(elementClass);
2860 o = (java_handle_t *) initialElement;
2863 exceptions_throw_negativearraysizeexception();
2867 oa = builtin_anewarray(length, c);
2872 /* set all elements to initialElement */
2874 for (i = 0; i < length; i++)
2875 array_objectarray_element_set(oa, i, o);
2877 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2881 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2884 java_handle_objectarray_t *oa;
2887 STATISTICS(jniinvokation());
2889 oa = (java_handle_objectarray_t *) array;
2891 if (index >= LLNI_array_size(oa)) {
2892 exceptions_throw_arrayindexoutofboundsexception();
2896 o = array_objectarray_element_get(oa, index);
2898 return jni_NewLocalRef(env, (jobject) o);
2902 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2903 jsize index, jobject val)
2905 java_handle_objectarray_t *oa;
2908 STATISTICS(jniinvokation());
2910 oa = (java_handle_objectarray_t *) array;
2911 o = (java_handle_t *) val;
2913 if (index >= LLNI_array_size(oa)) {
2914 exceptions_throw_arrayindexoutofboundsexception();
2918 /* check if the class of value is a subclass of the element class
2921 if (!builtin_canstore(oa, o))
2924 array_objectarray_element_set(oa, index, o);
2928 #define JNI_NEW_ARRAY(name, type, intern) \
2929 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2931 java_handle_##intern##array_t *a; \
2933 STATISTICS(jniinvokation()); \
2936 exceptions_throw_negativearraysizeexception(); \
2940 a = builtin_newarray_##intern(len); \
2942 return (type) jni_NewLocalRef(env, (jobject) a); \
2945 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2946 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2947 JNI_NEW_ARRAY(Char, jcharArray, char)
2948 JNI_NEW_ARRAY(Short, jshortArray, short)
2949 JNI_NEW_ARRAY(Int, jintArray, int)
2950 JNI_NEW_ARRAY(Long, jlongArray, long)
2951 JNI_NEW_ARRAY(Float, jfloatArray, float)
2952 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2955 /* Get<PrimitiveType>ArrayElements *********************************************
2957 A family of functions that returns the body of the primitive array.
2959 *******************************************************************************/
2961 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2962 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2965 java_handle_##intern##array_t *a; \
2967 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2969 a = (java_handle_##intern##array_t *) array; \
2972 *isCopy = JNI_FALSE; \
2974 return (type *) LLNI_array_data(a); \
2977 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2978 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2979 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2980 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2981 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2982 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2983 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2984 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2987 /* Release<PrimitiveType>ArrayElements *****************************************
2989 A family of functions that informs the VM that the native code no
2990 longer needs access to elems. The elems argument is a pointer
2991 derived from array using the corresponding
2992 Get<PrimitiveType>ArrayElements() function. If necessary, this
2993 function copies back all changes made to elems to the original
2996 *******************************************************************************/
2998 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2999 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3000 type *elems, jint mode) \
3002 java_handle_##intern##array_t *a; \
3004 STATISTICS(jniinvokation()); \
3006 a = (java_handle_##intern##array_t *) array; \
3008 if (elems != (type *) LLNI_array_data(a)) { \
3011 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3014 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3015 /* XXX TWISTI how should it be freed? */ \
3018 /* XXX TWISTI how should it be freed? */ \
3024 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3025 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3026 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3027 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3028 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3029 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3030 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3031 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3034 /* Get<PrimitiveType>ArrayRegion **********************************************
3036 A family of functions that copies a region of a primitive array
3039 *******************************************************************************/
3041 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3042 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3043 jsize start, jsize len, type *buf) \
3045 java_handle_##intern##array_t *a; \
3047 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3049 a = (java_handle_##intern##array_t *) array; \
3051 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3052 exceptions_throw_arrayindexoutofboundsexception(); \
3054 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3057 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3058 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3059 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3060 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3061 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3062 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3063 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3064 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3067 /* Set<PrimitiveType>ArrayRegion **********************************************
3069 A family of functions that copies back a region of a primitive
3070 array from a buffer.
3072 *******************************************************************************/
3074 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3075 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3076 jsize start, jsize len, const type *buf) \
3078 java_handle_##intern##array_t *a; \
3080 STATISTICS(jniinvokation()); \
3082 a = (java_handle_##intern##array_t *) array; \
3084 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3085 exceptions_throw_arrayindexoutofboundsexception(); \
3087 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3090 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3091 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3092 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3093 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3094 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3095 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3096 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3097 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3100 /* Registering Native Methods *************************************************/
3102 /* RegisterNatives *************************************************************
3104 Registers native methods with the class specified by the clazz
3105 argument. The methods parameter specifies an array of
3106 JNINativeMethod structures that contain the names, signatures, and
3107 function pointers of the native methods. The nMethods parameter
3108 specifies the number of native methods in the array.
3110 *******************************************************************************/
3112 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3113 const JNINativeMethod *methods, jint nMethods)
3117 STATISTICS(jniinvokation());
3119 c = LLNI_classinfo_unwrap(clazz);
3121 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3122 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3125 native_method_register(c->name, methods, nMethods);
3131 /* UnregisterNatives ***********************************************************
3133 Unregisters native methods of a class. The class goes back to the
3134 state before it was linked or registered with its native method
3137 This function should not be used in normal native code. Instead, it
3138 provides special programs a way to reload and relink native
3141 *******************************************************************************/
3143 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3145 STATISTICS(jniinvokation());
3147 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3149 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3155 /* Monitor Operations *********************************************************/
3157 /* MonitorEnter ****************************************************************
3159 Enters the monitor associated with the underlying Java object
3162 *******************************************************************************/
3164 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3166 STATISTICS(jniinvokation());
3169 exceptions_throw_nullpointerexception();
3173 LOCK_MONITOR_ENTER(obj);
3179 /* MonitorExit *****************************************************************
3181 The current thread must be the owner of the monitor associated with
3182 the underlying Java object referred to by obj. The thread
3183 decrements the counter indicating the number of times it has
3184 entered this monitor. If the value of the counter becomes zero, the
3185 current thread releases the monitor.
3187 *******************************************************************************/
3189 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3191 STATISTICS(jniinvokation());
3194 exceptions_throw_nullpointerexception();
3198 LOCK_MONITOR_EXIT(obj);
3204 /* JavaVM Interface ***********************************************************/
3206 /* GetJavaVM *******************************************************************
3208 Returns the Java VM interface (used in the Invocation API)
3209 associated with the current thread. The result is placed at the
3210 location pointed to by the second argument, vm.
3212 *******************************************************************************/
3214 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3216 STATISTICS(jniinvokation());
3218 *javavm = vm->get_javavm();
3224 /* GetStringRegion *************************************************************
3226 Copies len number of Unicode characters beginning at offset start
3227 to the given buffer buf.
3229 Throws StringIndexOutOfBoundsException on index overflow.
3231 *******************************************************************************/
3233 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3236 java_lang_String *s;
3237 java_handle_chararray_t *ca;
3239 STATISTICS(jniinvokation());
3241 s = (java_lang_String *) str;
3242 LLNI_field_get_ref(s, value, ca);
3244 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3245 (start + len > LLNI_field_direct(s, count))) {
3246 exceptions_throw_stringindexoutofboundsexception();
3250 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3254 /* GetStringUTFRegion **********************************************************
3256 Translates len number of Unicode characters beginning at offset
3257 start into UTF-8 format and place the result in the given buffer
3260 Throws StringIndexOutOfBoundsException on index overflow.
3262 *******************************************************************************/
3264 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3265 jsize len, char *buf)
3267 java_lang_String *s;
3268 java_handle_chararray_t *ca;
3273 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3275 s = (java_lang_String *) str;
3276 LLNI_field_get_ref(s, value, ca);
3277 LLNI_field_get_val(s, count, count);
3278 LLNI_field_get_val(s, offset, offset);
3280 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3281 exceptions_throw_stringindexoutofboundsexception();
3285 for (i = 0; i < len; i++)
3286 buf[i] = LLNI_array_direct(ca, offset + start + i);
3292 /* GetPrimitiveArrayCritical ***************************************************
3294 Obtain a direct pointer to array elements.
3296 ATTENTION: Critical section keeps open when this function returns!
3297 See ReleasePrimitiveArrayCritical.
3299 *******************************************************************************/
3301 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3305 arraydescriptor* ad;
3308 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3310 if (isCopy != NULL) {
3311 *isCopy = JNI_FALSE;
3314 LLNI_CRITICAL_START;
3316 h = (java_handle_t*) array;
3317 a = (java_array_t*) LLNI_UNWRAP(h);
3318 ad = a->objheader.vftbl->arraydesc;
3324 data = (void*) (((intptr_t) a) + ad->dataoffset);
3330 /* ReleasePrimitiveArrayCritical ***********************************************
3332 No specific documentation.
3334 ATTENTION: This function closes the critical section opened in
3335 GetPrimitiveArrayCritical!
3337 *******************************************************************************/
3339 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3341 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3347 /* GetStringCritical ***********************************************************
3349 The semantics of these two functions are similar to the existing
3350 Get/ReleaseStringChars functions.
3352 *******************************************************************************/
3354 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3357 STATISTICS(jniinvokation());
3359 return jni_GetStringChars(env, string, isCopy);
3363 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3364 const jchar *cstring)
3366 STATISTICS(jniinvokation());
3368 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3372 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3374 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3380 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3382 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3386 /* NewGlobalRef ****************************************************************
3388 Creates a new global reference to the object referred to by the obj
3391 *******************************************************************************/
3393 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3395 hashtable_global_ref_entry *gre;
3396 u4 key; /* hashkey */
3397 u4 slot; /* slot in hashtable */
3400 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3402 o = (java_handle_t *) obj;
3404 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3406 LLNI_CRITICAL_START;
3408 /* normally addresses are aligned to 4, 8 or 16 bytes */
3410 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3411 slot = key & (hashtable_global_ref->size - 1);
3412 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3414 /* search external hash chain for the entry */
3417 if (gre->o == LLNI_DIRECT(o)) {
3418 /* global object found, increment the reference */
3425 gre = gre->hashlink; /* next element in external chain */
3430 /* global ref not found, create a new one */
3433 gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3435 #if defined(ENABLE_GC_CACAO)
3436 /* register global ref with the GC */
3438 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3441 LLNI_CRITICAL_START;
3443 gre->o = LLNI_DIRECT(o);
3448 /* insert entry into hashtable */
3450 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3452 hashtable_global_ref->ptr[slot] = gre;
3454 /* update number of hashtable-entries */
3456 hashtable_global_ref->entries++;
3459 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3461 #if defined(ENABLE_HANDLES)
3469 /* DeleteGlobalRef *************************************************************
3471 Deletes the global reference pointed to by globalRef.
3473 *******************************************************************************/
3475 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3477 hashtable_global_ref_entry *gre;
3478 hashtable_global_ref_entry *prevgre;
3479 u4 key; /* hashkey */
3480 u4 slot; /* slot in hashtable */
3483 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3485 o = (java_handle_t *) globalRef;
3487 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3489 LLNI_CRITICAL_START;
3491 /* normally addresses are aligned to 4, 8 or 16 bytes */
3493 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3494 slot = key & (hashtable_global_ref->size - 1);
3495 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3497 /* initialize prevgre */
3501 /* search external hash chain for the entry */
3504 if (gre->o == LLNI_DIRECT(o)) {
3505 /* global object found, decrement the reference count */
3509 /* if reference count is 0, remove the entry */
3511 if (gre->refs == 0) {
3512 /* special handling if it's the first in the chain */
3514 if (prevgre == NULL)
3515 hashtable_global_ref->ptr[slot] = gre->hashlink;
3517 prevgre->hashlink = gre->hashlink;
3519 #if defined(ENABLE_GC_CACAO)
3520 /* unregister global ref with the GC */
3522 gc_reference_unregister(&(gre->o));
3530 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3535 prevgre = gre; /* save current pointer for removal */
3536 gre = gre->hashlink; /* next element in external chain */
3539 log_println("jni_DeleteGlobalRef: Global reference not found.");
3543 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3547 /* ExceptionCheck **************************************************************
3549 Returns JNI_TRUE when there is a pending exception; otherwise,
3552 *******************************************************************************/
3554 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3558 STATISTICS(jniinvokation());
3560 o = exceptions_get_exception();
3562 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3566 /* New JNI 1.4 functions ******************************************************/
3568 /* NewDirectByteBuffer *********************************************************
3570 Allocates and returns a direct java.nio.ByteBuffer referring to the
3571 block of memory starting at the memory address address and
3572 extending capacity bytes.
3574 *******************************************************************************/
3576 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3578 #if defined(ENABLE_JAVASE)
3579 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3580 java_handle_t *nbuf;
3582 # if SIZEOF_VOID_P == 8
3583 gnu_classpath_Pointer64 *paddress;
3585 gnu_classpath_Pointer32 *paddress;
3588 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3590 /* alocate a gnu.classpath.Pointer{32,64} object */
3592 # if SIZEOF_VOID_P == 8
3593 if (!(paddress = (gnu_classpath_Pointer64 *)
3594 builtin_new(class_gnu_classpath_Pointer64)))
3596 if (!(paddress = (gnu_classpath_Pointer32 *)
3597 builtin_new(class_gnu_classpath_Pointer32)))
3601 /* fill gnu.classpath.Pointer{32,64} with address */
3603 LLNI_field_set_val(paddress, data, (ptrint) address);
3605 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3607 nbuf = (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3608 (jmethodID) dbbirw_init, NULL, paddress,
3609 (jint) capacity, (jint) capacity, (jint) 0);
3611 /* add local reference and return the value */
3613 TRACEJNICALLSEXIT(("->%p", nbuf));
3615 return jni_NewLocalRef(env, (jobject) nbuf);
3617 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3623 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3625 /* Be paranoid about address sign-extension. */
3627 addr = (int64_t) ((uintptr_t) address);
3628 cap = (int32_t) capacity;
3630 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3631 (jmethodID) dbb_init, addr, cap);
3633 /* Add local reference and return the value. */
3635 TRACEJNICALLSEXIT(("->%p", o));
3637 return jni_NewLocalRef(env, o);
3640 # error unknown classpath configuration
3644 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3646 /* keep compiler happy */
3653 /* GetDirectBufferAddress ******************************************************
3655 Fetches and returns the starting address of the memory region
3656 referenced by the given direct java.nio.Buffer.
3658 *******************************************************************************/
3660 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3662 #if defined(ENABLE_JAVASE)
3665 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3667 java_nio_DirectByteBufferImpl *nbuf;
3668 gnu_classpath_Pointer *po;
3669 # if SIZEOF_VOID_P == 8
3670 gnu_classpath_Pointer64 *paddress;
3673 gnu_classpath_Pointer32 *paddress;
3678 TRACEJNICALLSENTER(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3680 /* Prevent compiler warning. */
3682 h = (java_handle_t *) buf;
3684 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3687 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3689 LLNI_field_get_ref(nbuf, address, po);
3691 # if SIZEOF_VOID_P == 8
3692 paddress = (gnu_classpath_Pointer64 *) po;
3694 paddress = (gnu_classpath_Pointer32 *) po;
3697 if (paddress == NULL) {
3698 TRACEJNICALLSEXIT(("->%p", NULL));
3702 LLNI_field_get_val(paddress, data, address);
3704 p = (void *) (intptr_t) address;
3706 TRACEJNICALLSEXIT(("->%p", p));
3710 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3716 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3718 /* Prevent compiler warning. */
3720 h = (java_handle_t *) buf;
3722 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3725 o = (java_nio_Buffer *) buf;
3727 LLNI_field_get_val(o, address, address);
3729 p = (void *) (intptr_t) address;
3734 # error unknown classpath configuration
3739 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3741 /* keep compiler happy */
3749 /* GetDirectBufferCapacity *****************************************************
3751 Fetches and returns the capacity in bytes of the memory region
3752 referenced by the given direct java.nio.Buffer.
3754 *******************************************************************************/
3756 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3758 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3760 java_nio_Buffer *nbuf;
3763 STATISTICS(jniinvokation());
3765 o = (java_handle_t *) buf;
3767 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3770 nbuf = (java_nio_Buffer *) o;
3772 LLNI_field_get_val(nbuf, cap, capacity);
3776 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3778 /* keep compiler happy */
3785 /* GetObjectRefType ************************************************************
3787 Returns the type of the object referred to by the obj argument. The
3788 argument obj can either be a local, global or weak global
3791 *******************************************************************************/
3793 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3795 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3797 return (jobjectRefType) NULL;
3801 /* DestroyJavaVM ***************************************************************
3803 Unloads a Java VM and reclaims its resources. Only the main thread
3804 can unload the VM. The system waits until the main thread is only
3805 remaining user thread before it destroys the VM.
3807 *******************************************************************************/
3809 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3813 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3815 if (vm->is_created() == false)
3818 status = vm_destroy(javavm);
3824 /* AttachCurrentThread *********************************************************
3826 Attaches the current thread to a Java VM. Returns a JNI interface
3827 pointer in the JNIEnv argument.
3829 Trying to attach a thread that is already attached is a no-op.
3831 A native thread cannot be attached simultaneously to two Java VMs.
3833 When a thread is attached to the VM, the context class loader is
3834 the bootstrap loader.
3836 *******************************************************************************/
3838 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3840 #if defined(ENABLE_THREADS)
3841 JavaVMAttachArgs *vm_aargs;
3844 /* If the current thread has already been attached, this operation
3847 result = thread_current_is_attached();
3849 if (result == true) {
3850 *p_env = vm->get_jnienv();
3854 vm_aargs = (JavaVMAttachArgs *) thr_args;
3856 if (vm_aargs != NULL) {
3857 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3858 (vm_aargs->version != JNI_VERSION_1_4))
3859 return JNI_EVERSION;
3862 if (!thread_attach_current_external_thread(vm_aargs, false))
3865 if (!localref_table_init())
3869 *p_env = vm->get_jnienv();
3875 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3879 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3881 if (vm->is_created() == false)
3884 result = jni_attach_current_thread(p_env, thr_args, false);
3890 /* DetachCurrentThread *********************************************************
3892 Detaches the current thread from a Java VM. All Java monitors held
3893 by this thread are released. All Java threads waiting for this
3894 thread to die are notified.
3896 In JDK 1.1, the main thread cannot be detached from the VM. It must
3897 call DestroyJavaVM to unload the entire VM.
3899 In the JDK, the main thread can be detached from the VM.
3901 The main thread, which is the thread that created the Java VM,
3902 cannot be detached from the VM. Instead, the main thread must call
3903 JNI_DestroyJavaVM() to unload the entire VM.
3905 *******************************************************************************/
3907 jint jni_DetachCurrentThread(JavaVM *vm)
3909 #if defined(ENABLE_THREADS)
3912 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3914 /* If the current thread has already been detached, this operation
3917 result = thread_current_is_attached();
3919 if (result == false)
3922 /* We need to pop all frames before we can destroy the table. */
3924 localref_frame_pop_all();
3926 if (!localref_table_destroy())
3929 if (!thread_detach_current_external_thread())
3937 /* GetEnv **********************************************************************
3939 If the current thread is not attached to the VM, sets *env to NULL,
3940 and returns JNI_EDETACHED. If the specified version is not
3941 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3942 sets *env to the appropriate interface, and returns JNI_OK.
3944 *******************************************************************************/
3946 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3948 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3950 if (vm->is_created() == false) {
3952 return JNI_EDETACHED;
3955 #if defined(ENABLE_THREADS)
3956 if (thread_get_current() == NULL) {
3959 return JNI_EDETACHED;
3963 /* Check the JNI version. */
3965 if (jni_version_check(version) == true) {
3966 *env = vm->get_jnienv();
3970 #if defined(ENABLE_JVMTI)
3971 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3972 == JVMTI_VERSION_INTERFACE_JVMTI) {
3974 *env = (void *) jvmti_new_environment();
3983 return JNI_EVERSION;
3987 /* AttachCurrentThreadAsDaemon *************************************************
3989 Same semantics as AttachCurrentThread, but the newly-created
3990 java.lang.Thread instance is a daemon.
3992 If the thread has already been attached via either
3993 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3994 simply sets the value pointed to by penv to the JNIEnv of the
3995 current thread. In this case neither AttachCurrentThread nor this
3996 routine have any effect on the daemon status of the thread.
3998 *******************************************************************************/
4000 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
4004 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
4006 if (vm->is_created() == false)
4009 result = jni_attach_current_thread(penv, args, true);
4015 /* JNI invocation table *******************************************************/
4017 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4022 _Jv_JNI_DestroyJavaVM,
4023 jni_AttachCurrentThread,
4024 jni_DetachCurrentThread,
4026 jni_AttachCurrentThreadAsDaemon
4030 /* JNI function table *********************************************************/
4032 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4039 _Jv_JNI_DefineClass,
4041 jni_FromReflectedMethod,
4042 jni_FromReflectedField,
4043 _Jv_JNI_ToReflectedMethod,
4044 _Jv_JNI_GetSuperclass,
4045 _Jv_JNI_IsAssignableFrom,
4046 _Jv_JNI_ToReflectedField,
4050 _Jv_JNI_ExceptionOccurred,
4051 jni_ExceptionDescribe,
4058 jni_DeleteGlobalRef,
4060 _Jv_JNI_IsSameObject,
4062 jni_EnsureLocalCapacity,
4064 _Jv_JNI_AllocObject,
4069 _Jv_JNI_GetObjectClass,
4070 _Jv_JNI_IsInstanceOf,
4072 _Jv_JNI_GetMethodID,
4074 _Jv_JNI_CallObjectMethod,
4075 _Jv_JNI_CallObjectMethodV,
4076 _Jv_JNI_CallObjectMethodA,
4077 _Jv_JNI_CallBooleanMethod,
4078 _Jv_JNI_CallBooleanMethodV,
4079 _Jv_JNI_CallBooleanMethodA,
4080 _Jv_JNI_CallByteMethod,
4081 _Jv_JNI_CallByteMethodV,
4082 _Jv_JNI_CallByteMethodA,
4083 _Jv_JNI_CallCharMethod,
4084 _Jv_JNI_CallCharMethodV,
4085 _Jv_JNI_CallCharMethodA,
4086 _Jv_JNI_CallShortMethod,
4087 _Jv_JNI_CallShortMethodV,
4088 _Jv_JNI_CallShortMethodA,
4089 _Jv_JNI_CallIntMethod,
4090 _Jv_JNI_CallIntMethodV,
4091 _Jv_JNI_CallIntMethodA,
4092 _Jv_JNI_CallLongMethod,
4093 _Jv_JNI_CallLongMethodV,
4094 _Jv_JNI_CallLongMethodA,
4095 _Jv_JNI_CallFloatMethod,
4096 _Jv_JNI_CallFloatMethodV,
4097 _Jv_JNI_CallFloatMethodA,
4098 _Jv_JNI_CallDoubleMethod,
4099 _Jv_JNI_CallDoubleMethodV,
4100 _Jv_JNI_CallDoubleMethodA,
4101 _Jv_JNI_CallVoidMethod,
4102 _Jv_JNI_CallVoidMethodV,
4103 _Jv_JNI_CallVoidMethodA,
4105 _Jv_JNI_CallNonvirtualObjectMethod,
4106 _Jv_JNI_CallNonvirtualObjectMethodV,
4107 _Jv_JNI_CallNonvirtualObjectMethodA,
4108 _Jv_JNI_CallNonvirtualBooleanMethod,
4109 _Jv_JNI_CallNonvirtualBooleanMethodV,
4110 _Jv_JNI_CallNonvirtualBooleanMethodA,
4111 _Jv_JNI_CallNonvirtualByteMethod,
4112 _Jv_JNI_CallNonvirtualByteMethodV,
4113 _Jv_JNI_CallNonvirtualByteMethodA,
4114 _Jv_JNI_CallNonvirtualCharMethod,
4115 _Jv_JNI_CallNonvirtualCharMethodV,
4116 _Jv_JNI_CallNonvirtualCharMethodA,
4117 _Jv_JNI_CallNonvirtualShortMethod,
4118 _Jv_JNI_CallNonvirtualShortMethodV,
4119 _Jv_JNI_CallNonvirtualShortMethodA,
4120 _Jv_JNI_CallNonvirtualIntMethod,
4121 _Jv_JNI_CallNonvirtualIntMethodV,
4122 _Jv_JNI_CallNonvirtualIntMethodA,
4123 _Jv_JNI_CallNonvirtualLongMethod,
4124 _Jv_JNI_CallNonvirtualLongMethodV,
4125 _Jv_JNI_CallNonvirtualLongMethodA,
4126 _Jv_JNI_CallNonvirtualFloatMethod,
4127 _Jv_JNI_CallNonvirtualFloatMethodV,
4128 _Jv_JNI_CallNonvirtualFloatMethodA,
4129 _Jv_JNI_CallNonvirtualDoubleMethod,
4130 _Jv_JNI_CallNonvirtualDoubleMethodV,
4131 _Jv_JNI_CallNonvirtualDoubleMethodA,
4132 _Jv_JNI_CallNonvirtualVoidMethod,
4133 _Jv_JNI_CallNonvirtualVoidMethodV,
4134 _Jv_JNI_CallNonvirtualVoidMethodA,
4138 _Jv_JNI_GetObjectField,
4139 _Jv_JNI_GetBooleanField,
4140 _Jv_JNI_GetByteField,
4141 _Jv_JNI_GetCharField,
4142 _Jv_JNI_GetShortField,
4143 _Jv_JNI_GetIntField,
4144 _Jv_JNI_GetLongField,
4145 _Jv_JNI_GetFloatField,
4146 _Jv_JNI_GetDoubleField,
4147 _Jv_JNI_SetObjectField,
4148 _Jv_JNI_SetBooleanField,
4149 _Jv_JNI_SetByteField,
4150 _Jv_JNI_SetCharField,
4151 _Jv_JNI_SetShortField,
4152 _Jv_JNI_SetIntField,
4153 _Jv_JNI_SetLongField,
4154 _Jv_JNI_SetFloatField,
4155 _Jv_JNI_SetDoubleField,
4157 _Jv_JNI_GetStaticMethodID,
4159 _Jv_JNI_CallStaticObjectMethod,
4160 _Jv_JNI_CallStaticObjectMethodV,
4161 _Jv_JNI_CallStaticObjectMethodA,
4162 _Jv_JNI_CallStaticBooleanMethod,
4163 _Jv_JNI_CallStaticBooleanMethodV,
4164 _Jv_JNI_CallStaticBooleanMethodA,
4165 _Jv_JNI_CallStaticByteMethod,
4166 _Jv_JNI_CallStaticByteMethodV,
4167 _Jv_JNI_CallStaticByteMethodA,
4168 _Jv_JNI_CallStaticCharMethod,
4169 _Jv_JNI_CallStaticCharMethodV,
4170 _Jv_JNI_CallStaticCharMethodA,
4171 _Jv_JNI_CallStaticShortMethod,
4172 _Jv_JNI_CallStaticShortMethodV,
4173 _Jv_JNI_CallStaticShortMethodA,
4174 _Jv_JNI_CallStaticIntMethod,
4175 _Jv_JNI_CallStaticIntMethodV,
4176 _Jv_JNI_CallStaticIntMethodA,
4177 _Jv_JNI_CallStaticLongMethod,
4178 _Jv_JNI_CallStaticLongMethodV,
4179 _Jv_JNI_CallStaticLongMethodA,
4180 _Jv_JNI_CallStaticFloatMethod,
4181 _Jv_JNI_CallStaticFloatMethodV,
4182 _Jv_JNI_CallStaticFloatMethodA,
4183 _Jv_JNI_CallStaticDoubleMethod,
4184 _Jv_JNI_CallStaticDoubleMethodV,
4185 _Jv_JNI_CallStaticDoubleMethodA,
4186 _Jv_JNI_CallStaticVoidMethod,
4187 _Jv_JNI_CallStaticVoidMethodV,
4188 _Jv_JNI_CallStaticVoidMethodA,
4190 _Jv_JNI_GetStaticFieldID,
4192 _Jv_JNI_GetStaticObjectField,
4193 _Jv_JNI_GetStaticBooleanField,
4194 _Jv_JNI_GetStaticByteField,
4195 _Jv_JNI_GetStaticCharField,
4196 _Jv_JNI_GetStaticShortField,
4197 _Jv_JNI_GetStaticIntField,
4198 _Jv_JNI_GetStaticLongField,
4199 _Jv_JNI_GetStaticFloatField,
4200 _Jv_JNI_GetStaticDoubleField,
4201 _Jv_JNI_SetStaticObjectField,
4202 _Jv_JNI_SetStaticBooleanField,
4203 _Jv_JNI_SetStaticByteField,
4204 _Jv_JNI_SetStaticCharField,
4205 _Jv_JNI_SetStaticShortField,
4206 _Jv_JNI_SetStaticIntField,
4207 _Jv_JNI_SetStaticLongField,
4208 _Jv_JNI_SetStaticFloatField,
4209 _Jv_JNI_SetStaticDoubleField,
4212 _Jv_JNI_GetStringLength,
4214 _Jv_JNI_ReleaseStringChars,
4216 _Jv_JNI_NewStringUTF,
4217 _Jv_JNI_GetStringUTFLength,
4218 _Jv_JNI_GetStringUTFChars,
4219 _Jv_JNI_ReleaseStringUTFChars,
4221 _Jv_JNI_GetArrayLength,
4223 _Jv_JNI_NewObjectArray,
4224 _Jv_JNI_GetObjectArrayElement,
4225 _Jv_JNI_SetObjectArrayElement,
4227 _Jv_JNI_NewBooleanArray,
4228 _Jv_JNI_NewByteArray,
4229 _Jv_JNI_NewCharArray,
4230 _Jv_JNI_NewShortArray,
4231 _Jv_JNI_NewIntArray,
4232 _Jv_JNI_NewLongArray,
4233 _Jv_JNI_NewFloatArray,
4234 _Jv_JNI_NewDoubleArray,
4236 _Jv_JNI_GetBooleanArrayElements,
4237 _Jv_JNI_GetByteArrayElements,
4238 _Jv_JNI_GetCharArrayElements,
4239 _Jv_JNI_GetShortArrayElements,
4240 _Jv_JNI_GetIntArrayElements,
4241 _Jv_JNI_GetLongArrayElements,
4242 _Jv_JNI_GetFloatArrayElements,
4243 _Jv_JNI_GetDoubleArrayElements,
4245 _Jv_JNI_ReleaseBooleanArrayElements,
4246 _Jv_JNI_ReleaseByteArrayElements,
4247 _Jv_JNI_ReleaseCharArrayElements,
4248 _Jv_JNI_ReleaseShortArrayElements,
4249 _Jv_JNI_ReleaseIntArrayElements,
4250 _Jv_JNI_ReleaseLongArrayElements,
4251 _Jv_JNI_ReleaseFloatArrayElements,
4252 _Jv_JNI_ReleaseDoubleArrayElements,
4254 _Jv_JNI_GetBooleanArrayRegion,
4255 _Jv_JNI_GetByteArrayRegion,
4256 _Jv_JNI_GetCharArrayRegion,
4257 _Jv_JNI_GetShortArrayRegion,
4258 _Jv_JNI_GetIntArrayRegion,
4259 _Jv_JNI_GetLongArrayRegion,
4260 _Jv_JNI_GetFloatArrayRegion,
4261 _Jv_JNI_GetDoubleArrayRegion,
4262 _Jv_JNI_SetBooleanArrayRegion,
4263 _Jv_JNI_SetByteArrayRegion,
4264 _Jv_JNI_SetCharArrayRegion,
4265 _Jv_JNI_SetShortArrayRegion,
4266 _Jv_JNI_SetIntArrayRegion,
4267 _Jv_JNI_SetLongArrayRegion,
4268 _Jv_JNI_SetFloatArrayRegion,
4269 _Jv_JNI_SetDoubleArrayRegion,
4271 _Jv_JNI_RegisterNatives,
4272 _Jv_JNI_UnregisterNatives,
4274 _Jv_JNI_MonitorEnter,
4275 _Jv_JNI_MonitorExit,
4279 /* New JNI 1.2 functions. */
4281 _Jv_JNI_GetStringRegion,
4282 _Jv_JNI_GetStringUTFRegion,
4284 jni_GetPrimitiveArrayCritical,
4285 jni_ReleasePrimitiveArrayCritical,
4287 _Jv_JNI_GetStringCritical,
4288 _Jv_JNI_ReleaseStringCritical,
4290 _Jv_JNI_NewWeakGlobalRef,
4291 _Jv_JNI_DeleteWeakGlobalRef,
4293 _Jv_JNI_ExceptionCheck,
4295 /* New JNI 1.4 functions. */
4297 jni_NewDirectByteBuffer,
4298 _Jv_JNI_GetDirectBufferAddress,
4299 _Jv_JNI_GetDirectBufferCapacity,
4301 /* New JNI 1.6 functions. */
4303 jni_GetObjectRefType
4307 /* Invocation API Functions ***************************************************/
4309 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4311 Returns a default configuration for the Java VM.
4313 *******************************************************************************/
4315 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4317 JavaVMInitArgs *_vm_args;
4319 _vm_args = (JavaVMInitArgs *) vm_args;
4321 /* GNU classpath currently supports JNI 1.2 */
4323 switch (_vm_args->version) {
4324 case JNI_VERSION_1_1:
4325 _vm_args->version = JNI_VERSION_1_1;
4328 case JNI_VERSION_1_2:
4329 case JNI_VERSION_1_4:
4330 _vm_args->ignoreUnrecognized = JNI_FALSE;
4331 _vm_args->options = NULL;
4332 _vm_args->nOptions = 0;
4343 /* JNI_GetCreatedJavaVMs *******************************************************
4345 Returns all Java VMs that have been created. Pointers to VMs are written in
4346 the buffer vmBuf in the order they are created. At most bufLen number of
4347 entries will be written. The total number of created VMs is returned in
4350 *******************************************************************************/
4352 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4354 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4359 // We currently only support 1 VM running.
4361 vmBuf[0] = vm->get_javavm();
4368 /* JNI_CreateJavaVM ************************************************************
4370 Loads and initializes a Java VM. The current thread becomes the main thread.
4371 Sets the env argument to the JNI interface pointer of the main thread.
4373 *******************************************************************************/
4375 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4377 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4379 /* actually create the JVM */
4381 if (!VM_create(p_vm, p_env, vm_args))
4391 * These are local overrides for various environment variables in Emacs.
4392 * Please do not remove this and leave it at the end of the file, where
4393 * Emacs will automagically detect them.
4394 * ---------------------------------------------------------------------
4397 * indent-tabs-mode: t
4401 * vim:noexpandtab:sw=4:ts=4: