1 /* src/native/jni.c - 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.h"
101 #include "toolbox/logging.h"
103 #include "vm/array.h"
104 #include "vm/builtin.h"
105 #include "vm/exceptions.h"
106 #include "vm/global.h"
107 #include "vm/initialize.h"
108 #include "vm/primitive.hpp"
109 #include "vm/resolve.h"
110 #include "vm/stringlocal.h"
113 #include "vm/jit/argument.h"
114 #include "vm/jit/asmpart.h"
115 #include "vm/jit/jit.h"
116 #include "vm/jit/stacktrace.h"
118 #include "vmcore/loader.h"
119 #include "vmcore/options.h"
120 #include "vmcore/statistics.h"
123 /* debug **********************************************************************/
127 # define TRACEJNICALLS(x) \
129 if (opt_TraceJNICalls) { \
134 # define TRACEJNICALLSENTER(x) \
136 if (opt_TraceJNICalls) { \
142 # define TRACEJNICALLSEXIT(x) \
144 if (opt_TraceJNICalls) { \
152 # define TRACEJNICALLS(x)
153 # define TRACEJNICALLSENTER(x)
154 # define TRACEJNICALLSEXIT(x)
159 /* global variables ***********************************************************/
161 /* global reference table *****************************************************/
163 /* hashsize must be power of 2 */
165 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
167 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
170 /* direct buffer stuff ********************************************************/
172 #if defined(ENABLE_JAVASE)
173 static classinfo *class_java_nio_Buffer;
175 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
177 static classinfo *class_java_nio_DirectByteBufferImpl;
178 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
180 # if SIZEOF_VOID_P == 8
181 static classinfo *class_gnu_classpath_Pointer64;
183 static classinfo *class_gnu_classpath_Pointer32;
186 static methodinfo *dbbirw_init;
188 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
190 static classinfo *class_sun_nio_ch_DirectBuffer;
191 static classinfo *class_java_nio_DirectByteBuffer;
193 static methodinfo *dbb_init;
199 /* some forward declarations **************************************************/
201 jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
204 /* jni_init ********************************************************************
206 Initialize the JNI subsystem.
208 *******************************************************************************/
212 TRACESUBSYSTEMINITIALIZATION("jni_init");
214 /* create global ref hashtable */
216 hashtable_global_ref = NEW(hashtable);
218 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
221 #if defined(ENABLE_JAVASE)
222 /* Direct buffer stuff. */
224 if (!(class_java_nio_Buffer =
225 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
226 !link_class(class_java_nio_Buffer))
229 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
231 if (!(class_java_nio_DirectByteBufferImpl =
232 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
233 !link_class(class_java_nio_DirectByteBufferImpl))
236 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
237 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
238 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
242 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
244 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
247 # if SIZEOF_VOID_P == 8
248 if (!(class_gnu_classpath_Pointer64 =
249 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
250 !link_class(class_gnu_classpath_Pointer64))
253 if (!(class_gnu_classpath_Pointer32 =
254 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
255 !link_class(class_gnu_classpath_Pointer32))
259 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
261 if (!(class_sun_nio_ch_DirectBuffer =
262 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
263 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
265 if (!link_class(class_sun_nio_ch_DirectBuffer))
266 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
268 if (!(class_java_nio_DirectByteBuffer =
269 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
270 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
272 if (!link_class(class_java_nio_DirectByteBuffer))
273 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
276 class_resolvemethod(class_java_nio_DirectByteBuffer,
278 utf_new_char("(JI)V"))))
279 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
283 #endif /* defined(ENABLE_JAVASE) */
289 /* jni_version_check ***********************************************************
291 Check if the given JNI version is supported.
294 version....JNI version to check
298 false......not supported
300 *******************************************************************************/
302 bool jni_version_check(int version)
305 case JNI_VERSION_1_1:
306 case JNI_VERSION_1_2:
307 case JNI_VERSION_1_4:
308 case JNI_VERSION_1_6:
316 /* _Jv_jni_CallObjectMethod ****************************************************
318 Internal function to call Java Object methods.
320 *******************************************************************************/
322 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
324 methodinfo *m, va_list ap)
329 STATISTICS(jniinvokation());
332 exceptions_throw_nullpointerexception();
336 /* Class initialization is done by the JIT compiler. This is ok
337 since a static method always belongs to the declaring class. */
339 if (m->flags & ACC_STATIC) {
340 /* For static methods we reset the object. */
345 /* for convenience */
350 /* For instance methods we make a virtual function table lookup. */
352 resm = method_vftbl_lookup(vftbl, m);
355 STATISTICS(jnicallXmethodnvokation());
357 ro = vm_call_method_valist(resm, o, ap);
363 /* _Jv_jni_CallObjectMethodA ***************************************************
365 Internal function to call Java Object methods.
367 *******************************************************************************/
369 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
377 STATISTICS(jniinvokation());
380 exceptions_throw_nullpointerexception();
384 /* Class initialization is done by the JIT compiler. This is ok
385 since a static method always belongs to the declaring class. */
387 if (m->flags & ACC_STATIC) {
388 /* For static methods we reset the object. */
393 /* for convenience */
398 /* For instance methods we make a virtual function table lookup. */
400 resm = method_vftbl_lookup(vftbl, m);
403 STATISTICS(jnicallXmethodnvokation());
405 ro = vm_call_method_jvalue(resm, o, args);
411 /* _Jv_jni_CallIntMethod *******************************************************
413 Internal function to call Java integer class methods (boolean,
414 byte, char, short, int).
416 *******************************************************************************/
418 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
419 methodinfo *m, va_list ap)
424 STATISTICS(jniinvokation());
427 exceptions_throw_nullpointerexception();
431 /* Class initialization is done by the JIT compiler. This is ok
432 since a static method always belongs to the declaring class. */
434 if (m->flags & ACC_STATIC) {
435 /* For static methods we reset the object. */
440 /* for convenience */
445 /* For instance methods we make a virtual function table lookup. */
447 resm = method_vftbl_lookup(vftbl, m);
450 STATISTICS(jnicallXmethodnvokation());
452 i = vm_call_method_int_valist(resm, o, ap);
458 /* _Jv_jni_CallIntMethodA ******************************************************
460 Internal function to call Java integer class methods (boolean,
461 byte, char, short, int).
463 *******************************************************************************/
465 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
466 methodinfo *m, const jvalue *args)
471 STATISTICS(jniinvokation());
474 exceptions_throw_nullpointerexception();
478 /* Class initialization is done by the JIT compiler. This is ok
479 since a static method always belongs to the declaring class. */
481 if (m->flags & ACC_STATIC) {
482 /* For static methods we reset the object. */
487 /* for convenience */
492 /* For instance methods we make a virtual function table lookup. */
494 resm = method_vftbl_lookup(vftbl, m);
497 STATISTICS(jnicallXmethodnvokation());
499 i = vm_call_method_int_jvalue(resm, o, args);
505 /* _Jv_jni_CallLongMethod ******************************************************
507 Internal function to call Java long methods.
509 *******************************************************************************/
511 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
512 methodinfo *m, va_list ap)
517 STATISTICS(jniinvokation());
520 exceptions_throw_nullpointerexception();
524 /* Class initialization is done by the JIT compiler. This is ok
525 since a static method always belongs to the declaring class. */
527 if (m->flags & ACC_STATIC) {
528 /* For static methods we reset the object. */
533 /* for convenience */
538 /* For instance methods we make a virtual function table lookup. */
540 resm = method_vftbl_lookup(vftbl, m);
543 STATISTICS(jnicallXmethodnvokation());
545 l = vm_call_method_long_valist(resm, o, ap);
551 /* _Jv_jni_CallLongMethodA *****************************************************
553 Internal function to call Java long methods.
555 *******************************************************************************/
557 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
558 methodinfo *m, const jvalue *args)
563 STATISTICS(jniinvokation());
566 exceptions_throw_nullpointerexception();
570 /* Class initialization is done by the JIT compiler. This is ok
571 since a static method always belongs to the declaring class. */
573 if (m->flags & ACC_STATIC) {
574 /* For static methods we reset the object. */
579 /* for convenience */
584 /* For instance methods we make a virtual function table lookup. */
586 resm = method_vftbl_lookup(vftbl, m);
589 STATISTICS(jnicallXmethodnvokation());
591 l = vm_call_method_long_jvalue(resm, o, args);
597 /* _Jv_jni_CallFloatMethod *****************************************************
599 Internal function to call Java float methods.
601 *******************************************************************************/
603 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
604 methodinfo *m, va_list ap)
609 /* Class initialization is done by the JIT compiler. This is ok
610 since a static method always belongs to the declaring class. */
612 if (m->flags & ACC_STATIC) {
613 /* For static methods we reset the object. */
618 /* for convenience */
623 /* For instance methods we make a virtual function table lookup. */
625 resm = method_vftbl_lookup(vftbl, m);
628 STATISTICS(jnicallXmethodnvokation());
630 f = vm_call_method_float_valist(resm, o, ap);
636 /* _Jv_jni_CallFloatMethodA ****************************************************
638 Internal function to call Java float methods.
640 *******************************************************************************/
642 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
643 methodinfo *m, const jvalue *args)
648 /* Class initialization is done by the JIT compiler. This is ok
649 since a static method always belongs to the declaring class. */
651 if (m->flags & ACC_STATIC) {
652 /* For static methods we reset the object. */
657 /* for convenience */
662 /* For instance methods we make a virtual function table lookup. */
664 resm = method_vftbl_lookup(vftbl, m);
667 STATISTICS(jnicallXmethodnvokation());
669 f = vm_call_method_float_jvalue(resm, o, args);
675 /* _Jv_jni_CallDoubleMethod ****************************************************
677 Internal function to call Java double methods.
679 *******************************************************************************/
681 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
682 methodinfo *m, va_list ap)
687 /* Class initialization is done by the JIT compiler. This is ok
688 since a static method always belongs to the declaring class. */
690 if (m->flags & ACC_STATIC) {
691 /* For static methods we reset the object. */
696 /* for convenience */
701 /* For instance methods we make a virtual function table lookup. */
703 resm = method_vftbl_lookup(vftbl, m);
706 d = vm_call_method_double_valist(resm, o, ap);
712 /* _Jv_jni_CallDoubleMethodA ***************************************************
714 Internal function to call Java double methods.
716 *******************************************************************************/
718 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
719 methodinfo *m, const jvalue *args)
724 /* Class initialization is done by the JIT compiler. This is ok
725 since a static method always belongs to the declaring class. */
727 if (m->flags & ACC_STATIC) {
728 /* For static methods we reset the object. */
733 /* for convenience */
738 /* For instance methods we make a virtual function table lookup. */
740 resm = method_vftbl_lookup(vftbl, m);
743 d = vm_call_method_double_jvalue(resm, o, args);
749 /* _Jv_jni_CallVoidMethod ******************************************************
751 Internal function to call Java void methods.
753 *******************************************************************************/
755 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
756 methodinfo *m, va_list ap)
761 exceptions_throw_nullpointerexception();
765 /* Class initialization is done by the JIT compiler. This is ok
766 since a static method always belongs to the declaring class. */
768 if (m->flags & ACC_STATIC) {
769 /* For static methods we reset the object. */
774 /* for convenience */
779 /* For instance methods we make a virtual function table lookup. */
781 resm = method_vftbl_lookup(vftbl, m);
784 STATISTICS(jnicallXmethodnvokation());
786 (void) vm_call_method_valist(resm, o, ap);
790 /* _Jv_jni_CallVoidMethodA *****************************************************
792 Internal function to call Java void methods.
794 *******************************************************************************/
796 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
797 methodinfo *m, const jvalue *args)
802 exceptions_throw_nullpointerexception();
806 /* Class initialization is done by the JIT compiler. This is ok
807 since a static method always belongs to the declaring class. */
809 if (m->flags & ACC_STATIC) {
810 /* For static methods we reset the object. */
815 /* for convenience */
820 /* For instance methods we make a virtual function table lookup. */
822 resm = method_vftbl_lookup(vftbl, m);
825 STATISTICS(jnicallXmethodnvokation());
827 (void) vm_call_method_jvalue(resm, o, args);
831 /* GetVersion ******************************************************************
833 Returns the major version number in the higher 16 bits and the
834 minor version number in the lower 16 bits.
836 *******************************************************************************/
838 jint _Jv_JNI_GetVersion(JNIEnv *env)
840 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
842 /* We support JNI 1.6. */
844 return JNI_VERSION_1_6;
848 /* Class Operations ***********************************************************/
850 /* DefineClass *****************************************************************
852 Loads a class from a buffer of raw class data. The buffer
853 containing the raw class data is not referenced by the VM after the
854 DefineClass call returns, and it may be discarded if desired.
856 *******************************************************************************/
858 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
859 const jbyte *buf, jsize bufLen)
861 #if defined(ENABLE_JAVASE)
867 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
869 u = utf_new_char(name);
870 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
872 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
874 co = LLNI_classinfo_wrap(c);
876 return (jclass) jni_NewLocalRef(env, (jobject) co);
878 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
880 /* keep compiler happy */
887 /* FindClass *******************************************************************
889 This function loads a locally-defined class. It searches the
890 directories and zip files specified by the CLASSPATH environment
891 variable for the class with the specified name.
893 *******************************************************************************/
895 jclass jni_FindClass(JNIEnv *env, const char *name)
897 #if defined(ENABLE_JAVASE)
904 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
906 /* FIXME If name is NULL we have a problem here. */
908 u = utf_new_char_classname((char *) name);
910 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
911 exceptions_throw_noclassdeffounderror(u);
915 /* Check stacktrace for classloader, if one found use it,
916 otherwise use the system classloader. */
918 /* Quote from the JNI documentation:
920 In the Java 2 Platform, FindClass locates the class loader
921 associated with the current native method. If the native code
922 belongs to a system class, no class loader will be
923 involved. Otherwise, the proper class loader will be invoked to
924 load and link the named class. When FindClass is called through
925 the Invocation Interface, there is no current native method or
926 its associated class loader. In that case, the result of
927 ClassLoader.getBaseClassLoader is used." */
929 cc = stacktrace_get_current_class();
932 c = load_class_from_sysloader(u);
934 c = load_class_from_classloader(u, cc->classloader);
937 resolve_handle_pending_exception(true);
944 co = LLNI_classinfo_wrap(c);
946 return (jclass) jni_NewLocalRef(env, (jobject) co);
948 #elif defined(ENABLE_JAVAME_CLDC1_1)
953 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
955 u = utf_new_char_classname((char *) name);
956 c = load_class_bootstrap(u);
959 resolve_handle_pending_exception(true);
966 return (jclass) jni_NewLocalRef(env, (jobject) c);
969 vm_abort("jni_FindClass: not implemented in this configuration");
971 /* keep compiler happy */
978 /* GetSuperclass ***************************************************************
980 If clazz represents any class other than the class Object, then
981 this function returns the object that represents the superclass of
982 the class specified by clazz.
984 *******************************************************************************/
986 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
992 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
994 c = LLNI_classinfo_unwrap(sub);
999 super = class_get_superclass(c);
1001 co = LLNI_classinfo_wrap(super);
1003 return (jclass) jni_NewLocalRef(env, (jobject) co);
1007 /* IsAssignableFrom ************************************************************
1009 Determines whether an object of sub can be safely cast to sup.
1011 *******************************************************************************/
1013 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1018 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
1020 to = (classinfo *) sup;
1021 from = (classinfo *) sub;
1023 return class_is_assignable_from(to, from);
1027 /* Throw ***********************************************************************
1029 Causes a java.lang.Throwable object to be thrown.
1031 *******************************************************************************/
1033 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1037 STATISTICS(jniinvokation());
1039 o = (java_handle_t *) obj;
1041 exceptions_set_exception(o);
1047 /* ThrowNew ********************************************************************
1049 Constructs an exception object from the specified class with the
1050 message specified by message and causes that exception to be
1053 *******************************************************************************/
1055 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1061 STATISTICS(jniinvokation());
1063 c = LLNI_classinfo_unwrap(clazz);
1066 s = javastring_new_from_utf_string(msg);
1068 /* instantiate exception object */
1070 o = native_new_and_init_string(c, s);
1075 exceptions_set_exception(o);
1081 /* ExceptionOccurred ***********************************************************
1083 Determines if an exception is being thrown. The exception stays
1084 being thrown until either the native code calls ExceptionClear(),
1085 or the Java code handles the exception.
1087 *******************************************************************************/
1089 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1093 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1095 o = exceptions_get_exception();
1097 return jni_NewLocalRef(env, (jthrowable) o);
1101 /* ExceptionDescribe ***********************************************************
1103 Prints an exception and a backtrace of the stack to a system
1104 error-reporting channel, such as stderr. This is a convenience
1105 routine provided for debugging.
1107 *******************************************************************************/
1109 void jni_ExceptionDescribe(JNIEnv *env)
1111 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1113 exceptions_print_stacktrace();
1117 /* ExceptionClear **************************************************************
1119 Clears any exception that is currently being thrown. If no
1120 exception is currently being thrown, this routine has no effect.
1122 *******************************************************************************/
1124 void jni_ExceptionClear(JNIEnv *env)
1126 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1128 exceptions_clear_exception();
1132 /* FatalError ******************************************************************
1134 Raises a fatal error and does not expect the VM to recover. This
1135 function does not return.
1137 *******************************************************************************/
1139 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1141 STATISTICS(jniinvokation());
1143 /* this seems to be the best way */
1145 vm_abort("JNI Fatal error: %s", msg);
1149 /* PushLocalFrame **************************************************************
1151 Creates a new local reference frame, in which at least a given
1152 number of local references can be created.
1154 *******************************************************************************/
1156 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1158 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1163 /* add new local reference frame to current table */
1165 if (!localref_frame_push(capacity))
1172 /* PopLocalFrame ***************************************************************
1174 Pops off the current local reference frame, frees all the local
1175 references, and returns a local reference in the previous local
1176 reference frame for the given result object.
1178 *******************************************************************************/
1180 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1182 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1184 /* release all current local frames */
1186 localref_frame_pop_all();
1188 /* add local reference and return the value */
1190 return jni_NewLocalRef(env, result);
1194 /* DeleteLocalRef **************************************************************
1196 Deletes the local reference pointed to by localRef.
1198 *******************************************************************************/
1200 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1204 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1206 o = (java_handle_t *) localRef;
1211 /* delete the reference */
1217 /* IsSameObject ****************************************************************
1219 Tests whether two references refer to the same Java object.
1221 *******************************************************************************/
1223 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1229 STATISTICS(jniinvokation());
1231 o1 = (java_handle_t *) ref1;
1232 o2 = (java_handle_t *) ref2;
1234 LLNI_CRITICAL_START;
1236 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1247 /* NewLocalRef *****************************************************************
1249 Creates a new local reference that refers to the same object as ref.
1251 *******************************************************************************/
1253 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1256 java_handle_t *localref;
1258 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1260 o = (java_handle_t *) ref;
1265 /* insert the reference */
1267 localref = localref_add(LLNI_DIRECT(o));
1269 return (jobject) localref;
1273 /* EnsureLocalCapacity *********************************************************
1275 Ensures that at least a given number of local references can be
1276 created in the current thread
1278 *******************************************************************************/
1280 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1282 localref_table *lrt;
1284 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1286 /* get local reference table (thread specific) */
1288 lrt = LOCALREFTABLE;
1290 /* check if capacity elements are available in the local references table */
1292 if ((lrt->used + capacity) > lrt->capacity)
1293 return jni_PushLocalFrame(env, capacity);
1299 /* AllocObject *****************************************************************
1301 Allocates a new Java object without invoking any of the
1302 constructors for the object. Returns a reference to the object.
1304 *******************************************************************************/
1306 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1311 STATISTICS(jniinvokation());
1313 c = LLNI_classinfo_unwrap(clazz);
1315 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1316 exceptions_throw_instantiationexception(c);
1322 return jni_NewLocalRef(env, (jobject) o);
1326 /* NewObject *******************************************************************
1328 Programmers place all arguments that are to be passed to the
1329 constructor immediately following the methodID
1330 argument. NewObject() accepts these arguments and passes them to
1331 the Java method that the programmer wishes to invoke.
1333 *******************************************************************************/
1335 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1342 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1344 c = LLNI_classinfo_unwrap(clazz);
1345 m = (methodinfo *) methodID;
1354 /* call constructor */
1356 va_start(ap, methodID);
1357 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1360 TRACEJNICALLSEXIT(("->%p", o));
1362 return jni_NewLocalRef(env, (jobject) o);
1366 /* NewObjectV ******************************************************************
1368 Programmers place all arguments that are to be passed to the
1369 constructor in an args argument of type va_list that immediately
1370 follows the methodID argument. NewObjectV() accepts these
1371 arguments, and, in turn, passes them to the Java method that the
1372 programmer wishes to invoke.
1374 *******************************************************************************/
1376 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1383 STATISTICS(jniinvokation());
1385 c = LLNI_classinfo_unwrap(clazz);
1386 m = (methodinfo *) methodID;
1395 /* call constructor */
1397 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1399 return jni_NewLocalRef(env, (jobject) o);
1403 /* NewObjectA *****************************************************************
1405 Programmers place all arguments that are to be passed to the
1406 constructor in an args array of jvalues that immediately follows
1407 the methodID argument. NewObjectA() accepts the arguments in this
1408 array, and, in turn, passes them to the Java method that the
1409 programmer wishes to invoke.
1411 *******************************************************************************/
1413 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1420 STATISTICS(jniinvokation());
1422 c = LLNI_classinfo_unwrap(clazz);
1423 m = (methodinfo *) methodID;
1432 /* call constructor */
1434 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1436 return jni_NewLocalRef(env, (jobject) o);
1440 /* GetObjectClass **************************************************************
1442 Returns the class of an object.
1444 *******************************************************************************/
1446 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1450 java_lang_Class *co;
1452 STATISTICS(jniinvokation());
1454 o = (java_handle_t *) obj;
1456 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1459 LLNI_class_get(o, c);
1461 co = LLNI_classinfo_wrap(c);
1463 return (jclass) jni_NewLocalRef(env, (jobject) co);
1467 /* IsInstanceOf ****************************************************************
1469 Tests whether an object is an instance of a class.
1471 *******************************************************************************/
1473 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1478 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1480 /* XXX Is this correct? */
1481 c = LLNI_classinfo_unwrap(clazz);
1482 h = (java_handle_t *) obj;
1484 return class_is_instance(c, h);
1488 /* Reflection Support *********************************************************/
1490 /* FromReflectedMethod *********************************************************
1492 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1493 object to a method ID.
1495 *******************************************************************************/
1497 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1499 #if defined(ENABLE_JAVASE)
1501 java_lang_reflect_Method *rm;
1502 java_lang_reflect_Constructor *rc;
1507 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1508 java_lang_reflect_VMMethod *rvmm;
1509 java_lang_reflect_VMConstructor *rvmc;
1512 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1514 o = (java_handle_t *) method;
1519 if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
1520 rc = (java_lang_reflect_Constructor *) method;
1522 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1524 LLNI_field_get_ref(rc, cons , rvmc);
1525 LLNI_field_get_cls(rvmc, clazz, c);
1526 LLNI_field_get_val(rvmc, slot , slot);
1528 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1530 LLNI_field_get_cls(rc, clazz, c);
1531 LLNI_field_get_val(rc, slot , slot);
1534 # error unknown configuration
1538 assert(o->vftbl->clazz == class_java_lang_reflect_Method);
1540 rm = (java_lang_reflect_Method *) method;
1542 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1544 LLNI_field_get_ref(rm, m , rvmm);
1545 LLNI_field_get_cls(rvmm, clazz, c);
1546 LLNI_field_get_val(rvmm, slot , slot);
1548 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1550 LLNI_field_get_cls(rm, clazz, c);
1551 LLNI_field_get_val(rm, slot , slot);
1554 # error unknown configuration
1558 m = &(c->methods[slot]);
1560 return (jmethodID) m;
1562 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1564 /* Keep compiler happy. */
1571 /* FromReflectedField **********************************************************
1573 Converts a java.lang.reflect.Field to a field ID.
1575 *******************************************************************************/
1577 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1579 #if defined(ENABLE_JAVASE)
1580 java_lang_reflect_Field *rf;
1585 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1586 java_lang_reflect_VMField *rvmf;
1589 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1591 rf = (java_lang_reflect_Field *) field;
1596 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1598 LLNI_field_get_ref(rf, f, rvmf);
1599 LLNI_field_get_cls(rvmf, clazz, c);
1600 LLNI_field_get_val(rvmf, slot , slot);
1602 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1604 LLNI_field_get_cls(rf, clazz, c);
1605 LLNI_field_get_val(rf, slot , slot);
1608 # error unknown configuration
1611 f = &(c->fields[slot]);
1613 return (jfieldID) f;
1615 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1617 /* Keep compiler happy. */
1624 /* ToReflectedMethod ***********************************************************
1626 Converts a method ID derived from cls to an instance of the
1627 java.lang.reflect.Method class or to an instance of the
1628 java.lang.reflect.Constructor class.
1630 *******************************************************************************/
1632 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1635 #if defined(ENABLE_JAVASE)
1637 java_lang_reflect_Constructor *rc;
1638 java_lang_reflect_Method *rm;
1640 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1642 m = (methodinfo *) methodID;
1644 /* HotSpot does the same assert. */
1646 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1648 if (m->name == utf_init) {
1649 rc = reflect_constructor_new(m);
1651 return (jobject) rc;
1654 rm = reflect_method_new(m);
1656 return (jobject) rm;
1659 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1661 /* keep compiler happy */
1668 /* ToReflectedField ************************************************************
1670 Converts a field ID derived from cls to an instance of the
1671 java.lang.reflect.Field class.
1673 *******************************************************************************/
1675 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1678 STATISTICS(jniinvokation());
1680 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1686 /* Calling Instance Methods ***************************************************/
1688 /* GetMethodID *****************************************************************
1690 Returns the method ID for an instance (nonstatic) method of a class
1691 or interface. The method may be defined in one of the clazz's
1692 superclasses and inherited by clazz. The method is determined by
1693 its name and signature.
1695 GetMethodID() causes an uninitialized class to be initialized.
1697 *******************************************************************************/
1699 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1707 STATISTICS(jniinvokation());
1709 c = LLNI_classinfo_unwrap(clazz);
1714 if (!(c->state & CLASS_INITIALIZED))
1715 if (!initialize_class(c))
1718 /* try to get the method of the class or one of it's superclasses */
1720 uname = utf_new_char((char *) name);
1721 udesc = utf_new_char((char *) sig);
1723 m = class_resolvemethod(c, uname, udesc);
1725 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1726 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1731 return (jmethodID) m;
1735 /* JNI-functions for calling instance methods *********************************/
1737 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1738 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1739 jmethodID methodID, ...) \
1746 o = (java_handle_t *) obj; \
1747 m = (methodinfo *) methodID; \
1749 va_start(ap, methodID); \
1750 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1756 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1757 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1758 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1759 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1760 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1761 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1762 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1763 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1766 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1767 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1768 jmethodID methodID, va_list args) \
1774 o = (java_handle_t *) obj; \
1775 m = (methodinfo *) methodID; \
1777 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1782 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1783 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1784 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1785 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1786 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1787 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1788 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1789 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1792 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1793 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1794 jmethodID methodID, \
1795 const jvalue *args) \
1801 o = (java_handle_t *) obj; \
1802 m = (methodinfo *) methodID; \
1804 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1809 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1810 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1811 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1812 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1813 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1814 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1815 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1816 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1819 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1827 o = (java_handle_t *) obj;
1828 m = (methodinfo *) methodID;
1830 va_start(ap, methodID);
1831 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1834 return jni_NewLocalRef(env, (jobject) ret);
1838 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1845 o = (java_handle_t *) obj;
1846 m = (methodinfo *) methodID;
1848 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1850 return jni_NewLocalRef(env, (jobject) ret);
1854 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1861 o = (java_handle_t *) obj;
1862 m = (methodinfo *) methodID;
1864 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1866 return jni_NewLocalRef(env, (jobject) ret);
1871 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1877 o = (java_handle_t *) obj;
1878 m = (methodinfo *) methodID;
1880 va_start(ap, methodID);
1881 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1886 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1892 o = (java_handle_t *) obj;
1893 m = (methodinfo *) methodID;
1895 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1899 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1905 o = (java_handle_t *) obj;
1906 m = (methodinfo *) methodID;
1908 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1913 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1914 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1915 jclass clazz, jmethodID methodID, \
1924 o = (java_handle_t *) obj; \
1925 c = LLNI_classinfo_unwrap(clazz); \
1926 m = (methodinfo *) methodID; \
1928 va_start(ap, methodID); \
1929 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1935 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1936 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1937 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1938 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1939 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1940 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1941 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1942 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1945 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1946 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1947 jclass clazz, jmethodID methodID, \
1955 o = (java_handle_t *) obj; \
1956 c = LLNI_classinfo_unwrap(clazz); \
1957 m = (methodinfo *) methodID; \
1959 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1964 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1965 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1966 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1967 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1968 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1969 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1970 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1971 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1974 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1975 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1976 jclass clazz, jmethodID methodID, \
1977 const jvalue *args) \
1979 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1984 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1985 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1986 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1987 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1988 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1989 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1990 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1991 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1993 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1994 jclass clazz, jmethodID methodID,
2003 o = (java_handle_t *) obj;
2004 c = LLNI_classinfo_unwrap(clazz);
2005 m = (methodinfo *) methodID;
2007 va_start(ap, methodID);
2008 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2011 return jni_NewLocalRef(env, (jobject) r);
2015 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2016 jclass clazz, jmethodID methodID,
2024 o = (java_handle_t *) obj;
2025 c = LLNI_classinfo_unwrap(clazz);
2026 m = (methodinfo *) methodID;
2028 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2030 return jni_NewLocalRef(env, (jobject) r);
2034 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2035 jclass clazz, jmethodID methodID,
2038 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2040 return jni_NewLocalRef(env, NULL);
2044 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2045 jmethodID methodID, ...)
2052 o = (java_handle_t *) obj;
2053 c = LLNI_classinfo_unwrap(clazz);
2054 m = (methodinfo *) methodID;
2056 va_start(ap, methodID);
2057 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2062 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2063 jmethodID methodID, va_list args)
2069 o = (java_handle_t *) obj;
2070 c = LLNI_classinfo_unwrap(clazz);
2071 m = (methodinfo *) methodID;
2073 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2077 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2078 jmethodID methodID, const jvalue * args)
2084 o = (java_handle_t *) obj;
2085 c = LLNI_classinfo_unwrap(clazz);
2086 m = (methodinfo *) methodID;
2088 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2092 /* Accessing Fields of Objects ************************************************/
2094 /* GetFieldID ******************************************************************
2096 Returns the field ID for an instance (nonstatic) field of a
2097 class. The field is specified by its name and signature. The
2098 Get<type>Field and Set<type>Field families of accessor functions
2099 use field IDs to retrieve object fields.
2101 *******************************************************************************/
2103 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2111 STATISTICS(jniinvokation());
2113 c = LLNI_classinfo_unwrap(clazz);
2115 /* XXX NPE check? */
2117 uname = utf_new_char((char *) name);
2118 udesc = utf_new_char((char *) sig);
2120 f = class_findfield(c, uname, udesc);
2123 exceptions_throw_nosuchfielderror(c, uname);
2125 return (jfieldID) f;
2129 /* Get<type>Field Routines *****************************************************
2131 This family of accessor routines returns the value of an instance
2132 (nonstatic) field of an object. The field to access is specified by
2133 a field ID obtained by calling GetFieldID().
2135 *******************************************************************************/
2137 #define GET_FIELD(o,type,f) \
2138 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2140 #define JNI_GET_FIELD(name, type, intern) \
2141 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2145 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2147 LLNI_CRITICAL_START; \
2149 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2151 LLNI_CRITICAL_END; \
2153 return (type) ret; \
2156 JNI_GET_FIELD(Boolean, jboolean, s4)
2157 JNI_GET_FIELD(Byte, jbyte, s4)
2158 JNI_GET_FIELD(Char, jchar, s4)
2159 JNI_GET_FIELD(Short, jshort, s4)
2160 JNI_GET_FIELD(Int, jint, s4)
2161 JNI_GET_FIELD(Long, jlong, s8)
2162 JNI_GET_FIELD(Float, jfloat, float)
2163 JNI_GET_FIELD(Double, jdouble, double)
2166 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2170 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2172 LLNI_CRITICAL_START;
2174 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2178 return jni_NewLocalRef(env, (jobject) o);
2182 /* Set<type>Field Routines *****************************************************
2184 This family of accessor routines sets the value of an instance
2185 (nonstatic) field of an object. The field to access is specified by
2186 a field ID obtained by calling GetFieldID().
2188 *******************************************************************************/
2190 #define SET_FIELD(o,type,f,value) \
2191 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2193 #define JNI_SET_FIELD(name, type, intern) \
2194 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2197 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2199 LLNI_CRITICAL_START; \
2201 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2203 LLNI_CRITICAL_START; \
2206 JNI_SET_FIELD(Boolean, jboolean, s4)
2207 JNI_SET_FIELD(Byte, jbyte, s4)
2208 JNI_SET_FIELD(Char, jchar, s4)
2209 JNI_SET_FIELD(Short, jshort, s4)
2210 JNI_SET_FIELD(Int, jint, s4)
2211 JNI_SET_FIELD(Long, jlong, s8)
2212 JNI_SET_FIELD(Float, jfloat, float)
2213 JNI_SET_FIELD(Double, jdouble, double)
2216 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2219 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2221 LLNI_CRITICAL_START;
2223 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2229 /* Calling Static Methods *****************************************************/
2231 /* GetStaticMethodID ***********************************************************
2233 Returns the method ID for a static method of a class. The method is
2234 specified by its name and signature.
2236 GetStaticMethodID() causes an uninitialized class to be
2239 *******************************************************************************/
2241 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2249 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2251 c = LLNI_classinfo_unwrap(clazz);
2256 if (!(c->state & CLASS_INITIALIZED))
2257 if (!initialize_class(c))
2260 /* try to get the static method of the class */
2262 uname = utf_new_char((char *) name);
2263 udesc = utf_new_char((char *) sig);
2265 m = class_resolvemethod(c, uname, udesc);
2267 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2268 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2273 return (jmethodID) m;
2277 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2278 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2279 jmethodID methodID, ...) \
2285 m = (methodinfo *) methodID; \
2287 va_start(ap, methodID); \
2288 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2294 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2295 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2296 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2297 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2298 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2299 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2300 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2301 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2304 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2305 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2306 jmethodID methodID, va_list args) \
2311 m = (methodinfo *) methodID; \
2313 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2318 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2319 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2320 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2321 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2322 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2323 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2324 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2325 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2328 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2329 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2330 jmethodID methodID, const jvalue *args) \
2335 m = (methodinfo *) methodID; \
2337 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2342 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2343 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2344 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2345 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2346 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2347 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2348 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2349 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2352 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2353 jmethodID methodID, ...)
2359 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2361 m = (methodinfo *) methodID;
2363 va_start(ap, methodID);
2364 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2367 return jni_NewLocalRef(env, (jobject) o);
2371 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2372 jmethodID methodID, va_list args)
2377 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2379 m = (methodinfo *) methodID;
2381 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2383 return jni_NewLocalRef(env, (jobject) o);
2387 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2388 jmethodID methodID, const jvalue *args)
2393 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2395 m = (methodinfo *) methodID;
2397 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2399 return jni_NewLocalRef(env, (jobject) o);
2403 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2404 jmethodID methodID, ...)
2409 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2411 m = (methodinfo *) methodID;
2413 va_start(ap, methodID);
2414 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2419 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2420 jmethodID methodID, va_list args)
2424 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2426 m = (methodinfo *) methodID;
2428 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2432 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2433 jmethodID methodID, const jvalue * args)
2437 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2439 m = (methodinfo *) methodID;
2441 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2445 /* Accessing Static Fields ****************************************************/
2447 /* GetStaticFieldID ************************************************************
2449 Returns the field ID for a static field of a class. The field is
2450 specified by its name and signature. The GetStatic<type>Field and
2451 SetStatic<type>Field families of accessor functions use field IDs
2452 to retrieve static fields.
2454 *******************************************************************************/
2456 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2464 STATISTICS(jniinvokation());
2466 c = LLNI_classinfo_unwrap(clazz);
2468 uname = utf_new_char((char *) name);
2469 usig = utf_new_char((char *) sig);
2471 f = class_findfield(c, uname, usig);
2474 exceptions_throw_nosuchfielderror(c, uname);
2476 return (jfieldID) f;
2480 /* GetStatic<type>Field ********************************************************
2482 This family of accessor routines returns the value of a static
2485 *******************************************************************************/
2487 #define JNI_GET_STATIC_FIELD(name, type, field) \
2488 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2494 STATISTICS(jniinvokation()); \
2496 c = LLNI_classinfo_unwrap(clazz); \
2497 f = (fieldinfo *) fieldID; \
2499 if (!(c->state & CLASS_INITIALIZED)) \
2500 if (!initialize_class(c)) \
2503 return f->value->field; \
2506 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2507 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2508 JNI_GET_STATIC_FIELD(Char, jchar, i)
2509 JNI_GET_STATIC_FIELD(Short, jshort, i)
2510 JNI_GET_STATIC_FIELD(Int, jint, i)
2511 JNI_GET_STATIC_FIELD(Long, jlong, l)
2512 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2513 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2516 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2523 STATISTICS(jniinvokation());
2525 c = LLNI_classinfo_unwrap(clazz);
2526 f = (fieldinfo *) fieldID;
2528 if (!(c->state & CLASS_INITIALIZED))
2529 if (!initialize_class(c))
2532 h = LLNI_WRAP(f->value->a);
2534 return jni_NewLocalRef(env, (jobject) h);
2538 /* SetStatic<type>Field *******************************************************
2540 This family of accessor routines sets the value of a static field
2543 *******************************************************************************/
2545 #define JNI_SET_STATIC_FIELD(name, type, field) \
2546 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2553 STATISTICS(jniinvokation()); \
2555 c = LLNI_classinfo_unwrap(clazz); \
2556 f = (fieldinfo *) fieldID; \
2558 if (!(c->state & CLASS_INITIALIZED)) \
2559 if (!initialize_class(c)) \
2562 f->value->field = value; \
2565 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2566 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2567 JNI_SET_STATIC_FIELD(Char, jchar, i)
2568 JNI_SET_STATIC_FIELD(Short, jshort, i)
2569 JNI_SET_STATIC_FIELD(Int, jint, i)
2570 JNI_SET_STATIC_FIELD(Long, jlong, l)
2571 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2572 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2575 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2581 STATISTICS(jniinvokation());
2583 c = LLNI_classinfo_unwrap(clazz);
2584 f = (fieldinfo *) fieldID;
2586 if (!(c->state & CLASS_INITIALIZED))
2587 if (!initialize_class(c))
2590 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2594 /* String Operations **********************************************************/
2596 /* NewString *******************************************************************
2598 Create new java.lang.String object from an array of Unicode
2601 *******************************************************************************/
2603 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2605 java_lang_String *s;
2606 java_handle_chararray_t *a;
2609 STATISTICS(jniinvokation());
2611 s = (java_lang_String *) builtin_new(class_java_lang_String);
2612 a = builtin_newarray_char(len);
2614 /* javastring or characterarray could not be created */
2615 if ((a == NULL) || (s == NULL))
2619 for (i = 0; i < len; i++)
2620 LLNI_array_direct(a, i) = buf[i];
2622 LLNI_field_set_ref(s, value , a);
2623 LLNI_field_set_val(s, offset, 0);
2624 LLNI_field_set_val(s, count , len);
2626 return (jstring) jni_NewLocalRef(env, (jobject) s);
2630 static jchar emptyStringJ[]={0,0};
2632 /* GetStringLength *************************************************************
2634 Returns the length (the count of Unicode characters) of a Java
2637 *******************************************************************************/
2639 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2641 java_lang_String *s;
2644 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2646 s = (java_lang_String *) str;
2648 LLNI_field_get_val(s, count, len);
2654 /******************** convertes javastring to u2-array ****************************/
2656 u2 *javastring_tou2(jstring so)
2658 java_lang_String *s;
2659 java_handle_chararray_t *a;
2665 STATISTICS(jniinvokation());
2667 s = (java_lang_String *) so;
2672 LLNI_field_get_ref(s, value, a);
2677 LLNI_field_get_val(s, count, count);
2678 LLNI_field_get_val(s, offset, offset);
2680 /* allocate memory */
2682 stringbuffer = MNEW(u2, count + 1);
2686 for (i = 0; i < count; i++)
2687 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2689 /* terminate string */
2691 stringbuffer[i] = '\0';
2693 return stringbuffer;
2697 /* GetStringChars **************************************************************
2699 Returns a pointer to the array of Unicode characters of the
2700 string. This pointer is valid until ReleaseStringChars() is called.
2702 *******************************************************************************/
2704 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2708 STATISTICS(jniinvokation());
2710 jc = javastring_tou2(str);
2722 return emptyStringJ;
2726 /* ReleaseStringChars **********************************************************
2728 Informs the VM that the native code no longer needs access to
2729 chars. The chars argument is a pointer obtained from string using
2732 *******************************************************************************/
2734 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2736 java_lang_String *s;
2738 STATISTICS(jniinvokation());
2740 if (chars == emptyStringJ)
2743 s = (java_lang_String *) str;
2745 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2749 /* NewStringUTF ****************************************************************
2751 Constructs a new java.lang.String object from an array of UTF-8
2754 *******************************************************************************/
2756 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2758 java_lang_String *s;
2760 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2762 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2764 return (jstring) jni_NewLocalRef(env, (jobject) s);
2768 /****************** returns the utf8 length in bytes of a string *******************/
2770 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2772 java_lang_String *s;
2775 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2777 s = (java_lang_String *) string;
2779 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2785 /* GetStringUTFChars ***********************************************************
2787 Returns a pointer to an array of UTF-8 characters of the
2788 string. This array is valid until it is released by
2789 ReleaseStringUTFChars().
2791 *******************************************************************************/
2793 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2798 STATISTICS(jniinvokation());
2806 u = javastring_toutf((java_handle_t *) string, false);
2815 /* ReleaseStringUTFChars *******************************************************
2817 Informs the VM that the native code no longer needs access to
2818 utf. The utf argument is a pointer derived from string using
2819 GetStringUTFChars().
2821 *******************************************************************************/
2823 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2825 STATISTICS(jniinvokation());
2827 /* XXX we don't release utf chars right now, perhaps that should be done
2828 later. Since there is always one reference the garbage collector will
2833 /* Array Operations ***********************************************************/
2835 /* GetArrayLength **************************************************************
2837 Returns the number of elements in the array.
2839 *******************************************************************************/
2841 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2846 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2848 a = (java_handle_t *) array;
2850 size = LLNI_array_size(a);
2856 /* NewObjectArray **************************************************************
2858 Constructs a new array holding objects in class elementClass. All
2859 elements are initially set to initialElement.
2861 *******************************************************************************/
2863 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2864 jclass elementClass, jobject initialElement)
2868 java_handle_objectarray_t *oa;
2871 STATISTICS(jniinvokation());
2873 c = LLNI_classinfo_unwrap(elementClass);
2874 o = (java_handle_t *) initialElement;
2877 exceptions_throw_negativearraysizeexception();
2881 oa = builtin_anewarray(length, c);
2886 /* set all elements to initialElement */
2888 for (i = 0; i < length; i++)
2889 array_objectarray_element_set(oa, i, o);
2891 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2895 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2898 java_handle_objectarray_t *oa;
2901 STATISTICS(jniinvokation());
2903 oa = (java_handle_objectarray_t *) array;
2905 if (index >= LLNI_array_size(oa)) {
2906 exceptions_throw_arrayindexoutofboundsexception();
2910 o = array_objectarray_element_get(oa, index);
2912 return jni_NewLocalRef(env, (jobject) o);
2916 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2917 jsize index, jobject val)
2919 java_handle_objectarray_t *oa;
2922 STATISTICS(jniinvokation());
2924 oa = (java_handle_objectarray_t *) array;
2925 o = (java_handle_t *) val;
2927 if (index >= LLNI_array_size(oa)) {
2928 exceptions_throw_arrayindexoutofboundsexception();
2932 /* check if the class of value is a subclass of the element class
2935 if (!builtin_canstore(oa, o))
2938 array_objectarray_element_set(oa, index, o);
2942 #define JNI_NEW_ARRAY(name, type, intern) \
2943 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2945 java_handle_##intern##array_t *a; \
2947 STATISTICS(jniinvokation()); \
2950 exceptions_throw_negativearraysizeexception(); \
2954 a = builtin_newarray_##intern(len); \
2956 return (type) jni_NewLocalRef(env, (jobject) a); \
2959 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2960 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2961 JNI_NEW_ARRAY(Char, jcharArray, char)
2962 JNI_NEW_ARRAY(Short, jshortArray, short)
2963 JNI_NEW_ARRAY(Int, jintArray, int)
2964 JNI_NEW_ARRAY(Long, jlongArray, long)
2965 JNI_NEW_ARRAY(Float, jfloatArray, float)
2966 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2969 /* Get<PrimitiveType>ArrayElements *********************************************
2971 A family of functions that returns the body of the primitive array.
2973 *******************************************************************************/
2975 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2976 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2979 java_handle_##intern##array_t *a; \
2981 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2983 a = (java_handle_##intern##array_t *) array; \
2986 *isCopy = JNI_FALSE; \
2988 return (type *) LLNI_array_data(a); \
2991 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2992 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2993 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2994 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2995 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2996 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2997 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2998 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3001 /* Release<PrimitiveType>ArrayElements *****************************************
3003 A family of functions that informs the VM that the native code no
3004 longer needs access to elems. The elems argument is a pointer
3005 derived from array using the corresponding
3006 Get<PrimitiveType>ArrayElements() function. If necessary, this
3007 function copies back all changes made to elems to the original
3010 *******************************************************************************/
3012 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3013 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3014 type *elems, jint mode) \
3016 java_handle_##intern##array_t *a; \
3018 STATISTICS(jniinvokation()); \
3020 a = (java_handle_##intern##array_t *) array; \
3022 if (elems != (type *) LLNI_array_data(a)) { \
3025 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3028 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3029 /* XXX TWISTI how should it be freed? */ \
3032 /* XXX TWISTI how should it be freed? */ \
3038 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3039 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3040 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3041 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3042 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3043 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3044 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3045 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3048 /* Get<PrimitiveType>ArrayRegion **********************************************
3050 A family of functions that copies a region of a primitive array
3053 *******************************************************************************/
3055 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3056 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3057 jsize start, jsize len, type *buf) \
3059 java_handle_##intern##array_t *a; \
3061 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3063 a = (java_handle_##intern##array_t *) array; \
3065 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3066 exceptions_throw_arrayindexoutofboundsexception(); \
3068 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3071 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3072 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3073 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3074 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3075 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3076 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3077 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3078 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3081 /* Set<PrimitiveType>ArrayRegion **********************************************
3083 A family of functions that copies back a region of a primitive
3084 array from a buffer.
3086 *******************************************************************************/
3088 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3089 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3090 jsize start, jsize len, const type *buf) \
3092 java_handle_##intern##array_t *a; \
3094 STATISTICS(jniinvokation()); \
3096 a = (java_handle_##intern##array_t *) array; \
3098 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3099 exceptions_throw_arrayindexoutofboundsexception(); \
3101 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3104 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3105 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3106 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3107 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3108 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3109 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3110 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3111 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3114 /* Registering Native Methods *************************************************/
3116 /* RegisterNatives *************************************************************
3118 Registers native methods with the class specified by the clazz
3119 argument. The methods parameter specifies an array of
3120 JNINativeMethod structures that contain the names, signatures, and
3121 function pointers of the native methods. The nMethods parameter
3122 specifies the number of native methods in the array.
3124 *******************************************************************************/
3126 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3127 const JNINativeMethod *methods, jint nMethods)
3131 STATISTICS(jniinvokation());
3133 c = LLNI_classinfo_unwrap(clazz);
3135 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3136 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3139 native_method_register(c->name, methods, nMethods);
3145 /* UnregisterNatives ***********************************************************
3147 Unregisters native methods of a class. The class goes back to the
3148 state before it was linked or registered with its native method
3151 This function should not be used in normal native code. Instead, it
3152 provides special programs a way to reload and relink native
3155 *******************************************************************************/
3157 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3159 STATISTICS(jniinvokation());
3161 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3163 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3169 /* Monitor Operations *********************************************************/
3171 /* MonitorEnter ****************************************************************
3173 Enters the monitor associated with the underlying Java object
3176 *******************************************************************************/
3178 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3180 STATISTICS(jniinvokation());
3183 exceptions_throw_nullpointerexception();
3187 LOCK_MONITOR_ENTER(obj);
3193 /* MonitorExit *****************************************************************
3195 The current thread must be the owner of the monitor associated with
3196 the underlying Java object referred to by obj. The thread
3197 decrements the counter indicating the number of times it has
3198 entered this monitor. If the value of the counter becomes zero, the
3199 current thread releases the monitor.
3201 *******************************************************************************/
3203 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3205 STATISTICS(jniinvokation());
3208 exceptions_throw_nullpointerexception();
3212 LOCK_MONITOR_EXIT(obj);
3218 /* JavaVM Interface ***********************************************************/
3220 /* GetJavaVM *******************************************************************
3222 Returns the Java VM interface (used in the Invocation API)
3223 associated with the current thread. The result is placed at the
3224 location pointed to by the second argument, vm.
3226 *******************************************************************************/
3228 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3230 STATISTICS(jniinvokation());
3232 *vm = VM_get_javavm();
3238 /* GetStringRegion *************************************************************
3240 Copies len number of Unicode characters beginning at offset start
3241 to the given buffer buf.
3243 Throws StringIndexOutOfBoundsException on index overflow.
3245 *******************************************************************************/
3247 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3250 java_lang_String *s;
3251 java_handle_chararray_t *ca;
3253 STATISTICS(jniinvokation());
3255 s = (java_lang_String *) str;
3256 LLNI_field_get_ref(s, value, ca);
3258 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3259 (start + len > LLNI_field_direct(s, count))) {
3260 exceptions_throw_stringindexoutofboundsexception();
3264 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3268 /* GetStringUTFRegion **********************************************************
3270 Translates len number of Unicode characters beginning at offset
3271 start into UTF-8 format and place the result in the given buffer
3274 Throws StringIndexOutOfBoundsException on index overflow.
3276 *******************************************************************************/
3278 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3279 jsize len, char *buf)
3281 java_lang_String *s;
3282 java_handle_chararray_t *ca;
3287 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3289 s = (java_lang_String *) str;
3290 LLNI_field_get_ref(s, value, ca);
3291 LLNI_field_get_val(s, count, count);
3292 LLNI_field_get_val(s, offset, offset);
3294 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3295 exceptions_throw_stringindexoutofboundsexception();
3299 for (i = 0; i < len; i++)
3300 buf[i] = LLNI_array_direct(ca, offset + start + i);
3306 /* GetPrimitiveArrayCritical ***************************************************
3308 Obtain a direct pointer to array elements.
3310 ATTENTION: Critical section keeps open when this function returns!
3311 See ReleasePrimitiveArrayCritical.
3313 *******************************************************************************/
3315 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3319 arraydescriptor* ad;
3322 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3324 if (isCopy != NULL) {
3325 *isCopy = JNI_FALSE;
3328 LLNI_CRITICAL_START;
3330 h = (java_handle_t*) array;
3331 a = (java_array_t*) LLNI_UNWRAP(h);
3332 ad = a->objheader.vftbl->arraydesc;
3338 data = (void*) (((intptr_t) a) + ad->dataoffset);
3344 /* ReleasePrimitiveArrayCritical ***********************************************
3346 No specific documentation.
3348 ATTENTION: This function closes the critical section opened in
3349 GetPrimitiveArrayCritical!
3351 *******************************************************************************/
3353 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3355 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3361 /* GetStringCritical ***********************************************************
3363 The semantics of these two functions are similar to the existing
3364 Get/ReleaseStringChars functions.
3366 *******************************************************************************/
3368 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3371 STATISTICS(jniinvokation());
3373 return _Jv_JNI_GetStringChars(env, string, isCopy);
3377 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3378 const jchar *cstring)
3380 STATISTICS(jniinvokation());
3382 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3386 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3388 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3394 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3396 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3400 /* NewGlobalRef ****************************************************************
3402 Creates a new global reference to the object referred to by the obj
3405 *******************************************************************************/
3407 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3409 hashtable_global_ref_entry *gre;
3410 u4 key; /* hashkey */
3411 u4 slot; /* slot in hashtable */
3414 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3416 o = (java_handle_t *) obj;
3418 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3420 LLNI_CRITICAL_START;
3422 /* normally addresses are aligned to 4, 8 or 16 bytes */
3424 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3425 slot = key & (hashtable_global_ref->size - 1);
3426 gre = hashtable_global_ref->ptr[slot];
3428 /* search external hash chain for the entry */
3431 if (gre->o == LLNI_DIRECT(o)) {
3432 /* global object found, increment the reference */
3439 gre = gre->hashlink; /* next element in external chain */
3444 /* global ref not found, create a new one */
3447 gre = GCNEW_UNCOLLECTABLE(hashtable_global_ref_entry, 1);
3449 #if defined(ENABLE_GC_CACAO)
3450 /* register global ref with the GC */
3452 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3455 LLNI_CRITICAL_START;
3457 gre->o = LLNI_DIRECT(o);
3462 /* insert entry into hashtable */
3464 gre->hashlink = hashtable_global_ref->ptr[slot];
3466 hashtable_global_ref->ptr[slot] = gre;
3468 /* update number of hashtable-entries */
3470 hashtable_global_ref->entries++;
3473 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3475 #if defined(ENABLE_HANDLES)
3483 /* DeleteGlobalRef *************************************************************
3485 Deletes the global reference pointed to by globalRef.
3487 *******************************************************************************/
3489 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3491 hashtable_global_ref_entry *gre;
3492 hashtable_global_ref_entry *prevgre;
3493 u4 key; /* hashkey */
3494 u4 slot; /* slot in hashtable */
3497 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3499 o = (java_handle_t *) globalRef;
3501 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3503 LLNI_CRITICAL_START;
3505 /* normally addresses are aligned to 4, 8 or 16 bytes */
3507 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3508 slot = key & (hashtable_global_ref->size - 1);
3509 gre = hashtable_global_ref->ptr[slot];
3511 /* initialize prevgre */
3515 /* search external hash chain for the entry */
3518 if (gre->o == LLNI_DIRECT(o)) {
3519 /* global object found, decrement the reference count */
3523 /* if reference count is 0, remove the entry */
3525 if (gre->refs == 0) {
3526 /* special handling if it's the first in the chain */
3528 if (prevgre == NULL)
3529 hashtable_global_ref->ptr[slot] = gre->hashlink;
3531 prevgre->hashlink = gre->hashlink;
3533 #if defined(ENABLE_GC_CACAO)
3534 /* unregister global ref with the GC */
3536 gc_reference_unregister(&(gre->o));
3544 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3549 prevgre = gre; /* save current pointer for removal */
3550 gre = gre->hashlink; /* next element in external chain */
3553 log_println("jni_DeleteGlobalRef: Global reference not found.");
3557 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3561 /* ExceptionCheck **************************************************************
3563 Returns JNI_TRUE when there is a pending exception; otherwise,
3566 *******************************************************************************/
3568 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3572 STATISTICS(jniinvokation());
3574 o = exceptions_get_exception();
3576 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3580 /* New JNI 1.4 functions ******************************************************/
3582 /* NewDirectByteBuffer *********************************************************
3584 Allocates and returns a direct java.nio.ByteBuffer referring to the
3585 block of memory starting at the memory address address and
3586 extending capacity bytes.
3588 *******************************************************************************/
3590 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3592 #if defined(ENABLE_JAVASE)
3593 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3594 java_handle_t *nbuf;
3596 # if SIZEOF_VOID_P == 8
3597 gnu_classpath_Pointer64 *paddress;
3599 gnu_classpath_Pointer32 *paddress;
3602 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3604 /* alocate a gnu.classpath.Pointer{32,64} object */
3606 # if SIZEOF_VOID_P == 8
3607 if (!(paddress = (gnu_classpath_Pointer64 *)
3608 builtin_new(class_gnu_classpath_Pointer64)))
3610 if (!(paddress = (gnu_classpath_Pointer32 *)
3611 builtin_new(class_gnu_classpath_Pointer32)))
3615 /* fill gnu.classpath.Pointer{32,64} with address */
3617 LLNI_field_set_val(paddress, data, (ptrint) address);
3619 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3621 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3622 (jmethodID) dbbirw_init, NULL, paddress,
3623 (jint) capacity, (jint) capacity, (jint) 0);
3625 /* add local reference and return the value */
3627 TRACEJNICALLSEXIT(("->%p", nbuf));
3629 return jni_NewLocalRef(env, nbuf);
3631 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3637 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3639 /* Be paranoid about address sign-extension. */
3641 addr = (int64_t) ((uintptr_t) address);
3642 cap = (int32_t) capacity;
3644 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3645 (jmethodID) dbb_init, addr, cap);
3647 /* Add local reference and return the value. */
3649 TRACEJNICALLSEXIT(("->%p", o));
3651 return jni_NewLocalRef(env, o);
3654 # error unknown classpath configuration
3658 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3660 /* keep compiler happy */
3667 /* GetDirectBufferAddress ******************************************************
3669 Fetches and returns the starting address of the memory region
3670 referenced by the given direct java.nio.Buffer.
3672 *******************************************************************************/
3674 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3676 #if defined(ENABLE_JAVASE)
3679 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3681 java_nio_DirectByteBufferImpl *nbuf;
3682 gnu_classpath_Pointer *po;
3683 # if SIZEOF_VOID_P == 8
3684 gnu_classpath_Pointer64 *paddress;
3687 gnu_classpath_Pointer32 *paddress;
3692 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3694 /* Prevent compiler warning. */
3696 h = (java_handle_t *) buf;
3698 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3701 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3703 LLNI_field_get_ref(nbuf, address, po);
3705 # if SIZEOF_VOID_P == 8
3706 paddress = (gnu_classpath_Pointer64 *) po;
3708 paddress = (gnu_classpath_Pointer32 *) po;
3711 if (paddress == NULL)
3714 LLNI_field_get_val(paddress, data, address);
3716 p = (void *) (intptr_t) address;
3720 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3726 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3728 /* Prevent compiler warning. */
3730 h = (java_handle_t *) buf;
3732 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3735 o = (java_nio_Buffer *) buf;
3737 LLNI_field_get_val(o, address, address);
3739 p = (void *) (intptr_t) address;
3744 # error unknown classpath configuration
3749 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3751 /* keep compiler happy */
3759 /* GetDirectBufferCapacity *****************************************************
3761 Fetches and returns the capacity in bytes of the memory region
3762 referenced by the given direct java.nio.Buffer.
3764 *******************************************************************************/
3766 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3768 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3770 java_nio_Buffer *nbuf;
3773 STATISTICS(jniinvokation());
3775 o = (java_handle_t *) buf;
3777 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3780 nbuf = (java_nio_Buffer *) o;
3782 LLNI_field_get_val(nbuf, cap, capacity);
3786 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3788 /* keep compiler happy */
3795 /* GetObjectRefType ************************************************************
3797 Returns the type of the object referred to by the obj argument. The
3798 argument obj can either be a local, global or weak global
3801 *******************************************************************************/
3803 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3805 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3811 /* DestroyJavaVM ***************************************************************
3813 Unloads a Java VM and reclaims its resources. Only the main thread
3814 can unload the VM. The system waits until the main thread is only
3815 remaining user thread before it destroys the VM.
3817 *******************************************************************************/
3819 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3823 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3825 if (VM_is_created() == false)
3828 status = vm_destroy(vm);
3834 /* AttachCurrentThread *********************************************************
3836 Attaches the current thread to a Java VM. Returns a JNI interface
3837 pointer in the JNIEnv argument.
3839 Trying to attach a thread that is already attached is a no-op.
3841 A native thread cannot be attached simultaneously to two Java VMs.
3843 When a thread is attached to the VM, the context class loader is
3844 the bootstrap loader.
3846 *******************************************************************************/
3848 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3850 #if defined(ENABLE_THREADS)
3851 JavaVMAttachArgs *vm_aargs;
3854 /* If the current thread has already been attached, this operation
3857 result = thread_current_is_attached();
3859 if (result == true) {
3860 *p_env = VM_get_jnienv();
3865 vm_aargs = (JavaVMAttachArgs *) thr_args;
3867 if (vm_aargs != NULL) {
3868 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3869 (vm_aargs->version != JNI_VERSION_1_4))
3870 return JNI_EVERSION;
3873 if (!thread_attach_current_external_thread(vm_aargs, false))
3876 if (!localref_table_init())
3880 *p_env = VM_get_jnienv();
3886 jint jni_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3890 TRACEJNICALLS(("jni_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3892 if (VM_is_created() == false)
3895 result = jni_attach_current_thread(p_env, thr_args, false);
3901 /* DetachCurrentThread *********************************************************
3903 Detaches the current thread from a Java VM. All Java monitors held
3904 by this thread are released. All Java threads waiting for this
3905 thread to die are notified.
3907 In JDK 1.1, the main thread cannot be detached from the VM. It must
3908 call DestroyJavaVM to unload the entire VM.
3910 In the JDK, the main thread can be detached from the VM.
3912 The main thread, which is the thread that created the Java VM,
3913 cannot be detached from the VM. Instead, the main thread must call
3914 JNI_DestroyJavaVM() to unload the entire VM.
3916 *******************************************************************************/
3918 jint jni_DetachCurrentThread(JavaVM *vm)
3920 #if defined(ENABLE_THREADS)
3923 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3925 /* If the current thread has already been detached, this operation
3928 result = thread_current_is_attached();
3930 if (result == false)
3933 /* We need to pop all frames before we can destroy the table. */
3935 localref_frame_pop_all();
3937 if (!localref_table_destroy())
3940 if (!thread_detach_current_external_thread())
3948 /* GetEnv **********************************************************************
3950 If the current thread is not attached to the VM, sets *env to NULL,
3951 and returns JNI_EDETACHED. If the specified version is not
3952 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3953 sets *env to the appropriate interface, and returns JNI_OK.
3955 *******************************************************************************/
3957 jint jni_GetEnv(JavaVM *vm, void **env, jint version)
3959 TRACEJNICALLS(("jni_GetEnv(vm=%p, env=%p, version=%d)", vm, env, version));
3961 if (VM_is_created() == false) {
3963 return JNI_EDETACHED;
3966 #if defined(ENABLE_THREADS)
3967 if (thread_get_current() == NULL) {
3970 return JNI_EDETACHED;
3974 /* Check the JNI version. */
3976 if (jni_version_check(version) == true) {
3977 *env = VM_get_jnienv();
3981 #if defined(ENABLE_JVMTI)
3982 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3983 == JVMTI_VERSION_INTERFACE_JVMTI) {
3985 *env = (void *) jvmti_new_environment();
3994 return JNI_EVERSION;
3998 /* AttachCurrentThreadAsDaemon *************************************************
4000 Same semantics as AttachCurrentThread, but the newly-created
4001 java.lang.Thread instance is a daemon.
4003 If the thread has already been attached via either
4004 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
4005 simply sets the value pointed to by penv to the JNIEnv of the
4006 current thread. In this case neither AttachCurrentThread nor this
4007 routine have any effect on the daemon status of the thread.
4009 *******************************************************************************/
4011 jint jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
4015 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
4017 if (VM_is_created() == false)
4020 result = jni_attach_current_thread(penv, args, true);
4026 /* JNI invocation table *******************************************************/
4028 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4033 _Jv_JNI_DestroyJavaVM,
4034 jni_AttachCurrentThread,
4035 jni_DetachCurrentThread,
4037 jni_AttachCurrentThreadAsDaemon
4041 /* JNI function table *********************************************************/
4043 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4050 _Jv_JNI_DefineClass,
4052 jni_FromReflectedMethod,
4053 jni_FromReflectedField,
4054 _Jv_JNI_ToReflectedMethod,
4055 _Jv_JNI_GetSuperclass,
4056 _Jv_JNI_IsAssignableFrom,
4057 _Jv_JNI_ToReflectedField,
4061 _Jv_JNI_ExceptionOccurred,
4062 jni_ExceptionDescribe,
4069 jni_DeleteGlobalRef,
4071 _Jv_JNI_IsSameObject,
4073 jni_EnsureLocalCapacity,
4075 _Jv_JNI_AllocObject,
4080 _Jv_JNI_GetObjectClass,
4081 _Jv_JNI_IsInstanceOf,
4083 _Jv_JNI_GetMethodID,
4085 _Jv_JNI_CallObjectMethod,
4086 _Jv_JNI_CallObjectMethodV,
4087 _Jv_JNI_CallObjectMethodA,
4088 _Jv_JNI_CallBooleanMethod,
4089 _Jv_JNI_CallBooleanMethodV,
4090 _Jv_JNI_CallBooleanMethodA,
4091 _Jv_JNI_CallByteMethod,
4092 _Jv_JNI_CallByteMethodV,
4093 _Jv_JNI_CallByteMethodA,
4094 _Jv_JNI_CallCharMethod,
4095 _Jv_JNI_CallCharMethodV,
4096 _Jv_JNI_CallCharMethodA,
4097 _Jv_JNI_CallShortMethod,
4098 _Jv_JNI_CallShortMethodV,
4099 _Jv_JNI_CallShortMethodA,
4100 _Jv_JNI_CallIntMethod,
4101 _Jv_JNI_CallIntMethodV,
4102 _Jv_JNI_CallIntMethodA,
4103 _Jv_JNI_CallLongMethod,
4104 _Jv_JNI_CallLongMethodV,
4105 _Jv_JNI_CallLongMethodA,
4106 _Jv_JNI_CallFloatMethod,
4107 _Jv_JNI_CallFloatMethodV,
4108 _Jv_JNI_CallFloatMethodA,
4109 _Jv_JNI_CallDoubleMethod,
4110 _Jv_JNI_CallDoubleMethodV,
4111 _Jv_JNI_CallDoubleMethodA,
4112 _Jv_JNI_CallVoidMethod,
4113 _Jv_JNI_CallVoidMethodV,
4114 _Jv_JNI_CallVoidMethodA,
4116 _Jv_JNI_CallNonvirtualObjectMethod,
4117 _Jv_JNI_CallNonvirtualObjectMethodV,
4118 _Jv_JNI_CallNonvirtualObjectMethodA,
4119 _Jv_JNI_CallNonvirtualBooleanMethod,
4120 _Jv_JNI_CallNonvirtualBooleanMethodV,
4121 _Jv_JNI_CallNonvirtualBooleanMethodA,
4122 _Jv_JNI_CallNonvirtualByteMethod,
4123 _Jv_JNI_CallNonvirtualByteMethodV,
4124 _Jv_JNI_CallNonvirtualByteMethodA,
4125 _Jv_JNI_CallNonvirtualCharMethod,
4126 _Jv_JNI_CallNonvirtualCharMethodV,
4127 _Jv_JNI_CallNonvirtualCharMethodA,
4128 _Jv_JNI_CallNonvirtualShortMethod,
4129 _Jv_JNI_CallNonvirtualShortMethodV,
4130 _Jv_JNI_CallNonvirtualShortMethodA,
4131 _Jv_JNI_CallNonvirtualIntMethod,
4132 _Jv_JNI_CallNonvirtualIntMethodV,
4133 _Jv_JNI_CallNonvirtualIntMethodA,
4134 _Jv_JNI_CallNonvirtualLongMethod,
4135 _Jv_JNI_CallNonvirtualLongMethodV,
4136 _Jv_JNI_CallNonvirtualLongMethodA,
4137 _Jv_JNI_CallNonvirtualFloatMethod,
4138 _Jv_JNI_CallNonvirtualFloatMethodV,
4139 _Jv_JNI_CallNonvirtualFloatMethodA,
4140 _Jv_JNI_CallNonvirtualDoubleMethod,
4141 _Jv_JNI_CallNonvirtualDoubleMethodV,
4142 _Jv_JNI_CallNonvirtualDoubleMethodA,
4143 _Jv_JNI_CallNonvirtualVoidMethod,
4144 _Jv_JNI_CallNonvirtualVoidMethodV,
4145 _Jv_JNI_CallNonvirtualVoidMethodA,
4149 _Jv_JNI_GetObjectField,
4150 _Jv_JNI_GetBooleanField,
4151 _Jv_JNI_GetByteField,
4152 _Jv_JNI_GetCharField,
4153 _Jv_JNI_GetShortField,
4154 _Jv_JNI_GetIntField,
4155 _Jv_JNI_GetLongField,
4156 _Jv_JNI_GetFloatField,
4157 _Jv_JNI_GetDoubleField,
4158 _Jv_JNI_SetObjectField,
4159 _Jv_JNI_SetBooleanField,
4160 _Jv_JNI_SetByteField,
4161 _Jv_JNI_SetCharField,
4162 _Jv_JNI_SetShortField,
4163 _Jv_JNI_SetIntField,
4164 _Jv_JNI_SetLongField,
4165 _Jv_JNI_SetFloatField,
4166 _Jv_JNI_SetDoubleField,
4168 _Jv_JNI_GetStaticMethodID,
4170 _Jv_JNI_CallStaticObjectMethod,
4171 _Jv_JNI_CallStaticObjectMethodV,
4172 _Jv_JNI_CallStaticObjectMethodA,
4173 _Jv_JNI_CallStaticBooleanMethod,
4174 _Jv_JNI_CallStaticBooleanMethodV,
4175 _Jv_JNI_CallStaticBooleanMethodA,
4176 _Jv_JNI_CallStaticByteMethod,
4177 _Jv_JNI_CallStaticByteMethodV,
4178 _Jv_JNI_CallStaticByteMethodA,
4179 _Jv_JNI_CallStaticCharMethod,
4180 _Jv_JNI_CallStaticCharMethodV,
4181 _Jv_JNI_CallStaticCharMethodA,
4182 _Jv_JNI_CallStaticShortMethod,
4183 _Jv_JNI_CallStaticShortMethodV,
4184 _Jv_JNI_CallStaticShortMethodA,
4185 _Jv_JNI_CallStaticIntMethod,
4186 _Jv_JNI_CallStaticIntMethodV,
4187 _Jv_JNI_CallStaticIntMethodA,
4188 _Jv_JNI_CallStaticLongMethod,
4189 _Jv_JNI_CallStaticLongMethodV,
4190 _Jv_JNI_CallStaticLongMethodA,
4191 _Jv_JNI_CallStaticFloatMethod,
4192 _Jv_JNI_CallStaticFloatMethodV,
4193 _Jv_JNI_CallStaticFloatMethodA,
4194 _Jv_JNI_CallStaticDoubleMethod,
4195 _Jv_JNI_CallStaticDoubleMethodV,
4196 _Jv_JNI_CallStaticDoubleMethodA,
4197 _Jv_JNI_CallStaticVoidMethod,
4198 _Jv_JNI_CallStaticVoidMethodV,
4199 _Jv_JNI_CallStaticVoidMethodA,
4201 _Jv_JNI_GetStaticFieldID,
4203 _Jv_JNI_GetStaticObjectField,
4204 _Jv_JNI_GetStaticBooleanField,
4205 _Jv_JNI_GetStaticByteField,
4206 _Jv_JNI_GetStaticCharField,
4207 _Jv_JNI_GetStaticShortField,
4208 _Jv_JNI_GetStaticIntField,
4209 _Jv_JNI_GetStaticLongField,
4210 _Jv_JNI_GetStaticFloatField,
4211 _Jv_JNI_GetStaticDoubleField,
4212 _Jv_JNI_SetStaticObjectField,
4213 _Jv_JNI_SetStaticBooleanField,
4214 _Jv_JNI_SetStaticByteField,
4215 _Jv_JNI_SetStaticCharField,
4216 _Jv_JNI_SetStaticShortField,
4217 _Jv_JNI_SetStaticIntField,
4218 _Jv_JNI_SetStaticLongField,
4219 _Jv_JNI_SetStaticFloatField,
4220 _Jv_JNI_SetStaticDoubleField,
4223 _Jv_JNI_GetStringLength,
4224 _Jv_JNI_GetStringChars,
4225 _Jv_JNI_ReleaseStringChars,
4227 _Jv_JNI_NewStringUTF,
4228 _Jv_JNI_GetStringUTFLength,
4229 _Jv_JNI_GetStringUTFChars,
4230 _Jv_JNI_ReleaseStringUTFChars,
4232 _Jv_JNI_GetArrayLength,
4234 _Jv_JNI_NewObjectArray,
4235 _Jv_JNI_GetObjectArrayElement,
4236 _Jv_JNI_SetObjectArrayElement,
4238 _Jv_JNI_NewBooleanArray,
4239 _Jv_JNI_NewByteArray,
4240 _Jv_JNI_NewCharArray,
4241 _Jv_JNI_NewShortArray,
4242 _Jv_JNI_NewIntArray,
4243 _Jv_JNI_NewLongArray,
4244 _Jv_JNI_NewFloatArray,
4245 _Jv_JNI_NewDoubleArray,
4247 _Jv_JNI_GetBooleanArrayElements,
4248 _Jv_JNI_GetByteArrayElements,
4249 _Jv_JNI_GetCharArrayElements,
4250 _Jv_JNI_GetShortArrayElements,
4251 _Jv_JNI_GetIntArrayElements,
4252 _Jv_JNI_GetLongArrayElements,
4253 _Jv_JNI_GetFloatArrayElements,
4254 _Jv_JNI_GetDoubleArrayElements,
4256 _Jv_JNI_ReleaseBooleanArrayElements,
4257 _Jv_JNI_ReleaseByteArrayElements,
4258 _Jv_JNI_ReleaseCharArrayElements,
4259 _Jv_JNI_ReleaseShortArrayElements,
4260 _Jv_JNI_ReleaseIntArrayElements,
4261 _Jv_JNI_ReleaseLongArrayElements,
4262 _Jv_JNI_ReleaseFloatArrayElements,
4263 _Jv_JNI_ReleaseDoubleArrayElements,
4265 _Jv_JNI_GetBooleanArrayRegion,
4266 _Jv_JNI_GetByteArrayRegion,
4267 _Jv_JNI_GetCharArrayRegion,
4268 _Jv_JNI_GetShortArrayRegion,
4269 _Jv_JNI_GetIntArrayRegion,
4270 _Jv_JNI_GetLongArrayRegion,
4271 _Jv_JNI_GetFloatArrayRegion,
4272 _Jv_JNI_GetDoubleArrayRegion,
4273 _Jv_JNI_SetBooleanArrayRegion,
4274 _Jv_JNI_SetByteArrayRegion,
4275 _Jv_JNI_SetCharArrayRegion,
4276 _Jv_JNI_SetShortArrayRegion,
4277 _Jv_JNI_SetIntArrayRegion,
4278 _Jv_JNI_SetLongArrayRegion,
4279 _Jv_JNI_SetFloatArrayRegion,
4280 _Jv_JNI_SetDoubleArrayRegion,
4282 _Jv_JNI_RegisterNatives,
4283 _Jv_JNI_UnregisterNatives,
4285 _Jv_JNI_MonitorEnter,
4286 _Jv_JNI_MonitorExit,
4290 /* New JNI 1.2 functions. */
4292 _Jv_JNI_GetStringRegion,
4293 _Jv_JNI_GetStringUTFRegion,
4295 jni_GetPrimitiveArrayCritical,
4296 jni_ReleasePrimitiveArrayCritical,
4298 _Jv_JNI_GetStringCritical,
4299 _Jv_JNI_ReleaseStringCritical,
4301 _Jv_JNI_NewWeakGlobalRef,
4302 _Jv_JNI_DeleteWeakGlobalRef,
4304 _Jv_JNI_ExceptionCheck,
4306 /* New JNI 1.4 functions. */
4308 jni_NewDirectByteBuffer,
4309 _Jv_JNI_GetDirectBufferAddress,
4310 _Jv_JNI_GetDirectBufferCapacity,
4312 /* New JNI 1.6 functions. */
4314 jni_GetObjectRefType
4318 /* Invocation API Functions ***************************************************/
4320 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4322 Returns a default configuration for the Java VM.
4324 *******************************************************************************/
4326 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4328 JavaVMInitArgs *_vm_args;
4330 _vm_args = (JavaVMInitArgs *) vm_args;
4332 /* GNU classpath currently supports JNI 1.2 */
4334 switch (_vm_args->version) {
4335 case JNI_VERSION_1_1:
4336 _vm_args->version = JNI_VERSION_1_1;
4339 case JNI_VERSION_1_2:
4340 case JNI_VERSION_1_4:
4341 _vm_args->ignoreUnrecognized = JNI_FALSE;
4342 _vm_args->options = NULL;
4343 _vm_args->nOptions = 0;
4354 /* JNI_GetCreatedJavaVMs *******************************************************
4356 Returns all Java VMs that have been created. Pointers to VMs are written in
4357 the buffer vmBuf in the order they are created. At most bufLen number of
4358 entries will be written. The total number of created VMs is returned in
4361 *******************************************************************************/
4363 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4365 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4370 /* We currently only support 1 VM running. */
4372 vmBuf[0] = VM_get_javavm();
4379 /* JNI_CreateJavaVM ************************************************************
4381 Loads and initializes a Java VM. The current thread becomes the main thread.
4382 Sets the env argument to the JNI interface pointer of the main thread.
4384 *******************************************************************************/
4386 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4388 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4390 /* actually create the JVM */
4392 if (!VM_create(p_vm, p_env, vm_args))
4400 * These are local overrides for various environment variables in Emacs.
4401 * Please do not remove this and leave it at the end of the file, where
4402 * Emacs will automagically detect them.
4403 * ---------------------------------------------------------------------
4406 * indent-tabs-mode: t
4410 * vim:noexpandtab:sw=4:ts=4: