1 /* src/native/jni.cpp - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/memory.h"
37 #include "native/jni.h"
38 #include "native/llni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
42 #if defined(ENABLE_JAVASE)
43 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
44 # include "native/include/gnu_classpath_Pointer.h"
46 # if SIZEOF_VOID_P == 8
47 # include "native/include/gnu_classpath_Pointer64.h"
49 # include "native/include/gnu_classpath_Pointer32.h"
54 #include "native/include/java_lang_Object.h"
55 #include "native/include/java_lang_String.h"
56 #include "native/include/java_lang_Throwable.h"
58 #if defined(ENABLE_JAVASE)
60 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
61 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
64 /* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
65 we pre-define it here to prevent a compiler warning for Sun
68 struct java_lang_ClassLoader;
70 # include "native/include/java_lang_Class.h"
71 # include "native/include/java_lang_ClassLoader.h"
73 # include "native/include/java_lang_reflect_Constructor.h"
74 # include "native/include/java_lang_reflect_Field.h"
75 # include "native/include/java_lang_reflect_Method.h"
77 # include "native/include/java_nio_Buffer.h"
79 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
80 # include "native/include/java_lang_reflect_VMConstructor.h"
81 # include "native/include/java_lang_reflect_VMField.h"
82 # include "native/include/java_lang_reflect_VMMethod.h"
84 # include "native/include/java_nio_DirectByteBufferImpl.h"
86 #elif defined(ENABLE_JAVAME_CLDC1_1)
87 # include "native/include/java_lang_Class.h"
90 #if defined(ENABLE_JVMTI)
91 # include "native/jvmti/cacaodbg.h"
94 #if defined(ENABLE_JAVASE)
95 # include "native/vm/reflect.h"
98 #include "threads/lock-common.h"
99 #include "threads/thread.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 **************************************************/
202 jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
206 /* jni_init ********************************************************************
208 Initialize the JNI subsystem.
210 *******************************************************************************/
214 TRACESUBSYSTEMINITIALIZATION("jni_init");
216 /* create global ref hashtable */
218 hashtable_global_ref = NEW(hashtable);
220 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
223 #if defined(ENABLE_JAVASE)
224 /* Direct buffer stuff. */
226 if (!(class_java_nio_Buffer =
227 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
228 !link_class(class_java_nio_Buffer))
231 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
233 if (!(class_java_nio_DirectByteBufferImpl =
234 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
235 !link_class(class_java_nio_DirectByteBufferImpl))
238 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
239 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
240 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
244 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
246 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
249 # if SIZEOF_VOID_P == 8
250 if (!(class_gnu_classpath_Pointer64 =
251 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
252 !link_class(class_gnu_classpath_Pointer64))
255 if (!(class_gnu_classpath_Pointer32 =
256 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
257 !link_class(class_gnu_classpath_Pointer32))
261 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
263 if (!(class_sun_nio_ch_DirectBuffer =
264 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
265 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
267 if (!link_class(class_sun_nio_ch_DirectBuffer))
268 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
270 if (!(class_java_nio_DirectByteBuffer =
271 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
272 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
274 if (!link_class(class_java_nio_DirectByteBuffer))
275 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
278 class_resolvemethod(class_java_nio_DirectByteBuffer,
280 utf_new_char("(JI)V"))))
281 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
285 #endif /* defined(ENABLE_JAVASE) */
291 /* jni_version_check ***********************************************************
293 Check if the given JNI version is supported.
296 version....JNI version to check
300 false......not supported
302 *******************************************************************************/
304 bool jni_version_check(int version)
307 case JNI_VERSION_1_1:
308 case JNI_VERSION_1_2:
309 case JNI_VERSION_1_4:
310 case JNI_VERSION_1_6:
318 /* _Jv_jni_CallObjectMethod ****************************************************
320 Internal function to call Java Object methods.
322 *******************************************************************************/
324 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
326 methodinfo *m, va_list ap)
331 STATISTICS(jniinvokation());
334 exceptions_throw_nullpointerexception();
338 /* Class initialization is done by the JIT compiler. This is ok
339 since a static method always belongs to the declaring class. */
341 if (m->flags & ACC_STATIC) {
342 /* For static methods we reset the object. */
347 /* for convenience */
352 /* For instance methods we make a virtual function table lookup. */
354 resm = method_vftbl_lookup(vftbl, m);
357 STATISTICS(jnicallXmethodnvokation());
359 ro = vm_call_method_valist(resm, o, ap);
365 /* _Jv_jni_CallObjectMethodA ***************************************************
367 Internal function to call Java Object methods.
369 *******************************************************************************/
371 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
379 STATISTICS(jniinvokation());
382 exceptions_throw_nullpointerexception();
386 /* Class initialization is done by the JIT compiler. This is ok
387 since a static method always belongs to the declaring class. */
389 if (m->flags & ACC_STATIC) {
390 /* For static methods we reset the object. */
395 /* for convenience */
400 /* For instance methods we make a virtual function table lookup. */
402 resm = method_vftbl_lookup(vftbl, m);
405 STATISTICS(jnicallXmethodnvokation());
407 ro = vm_call_method_jvalue(resm, o, args);
413 /* _Jv_jni_CallIntMethod *******************************************************
415 Internal function to call Java integer class methods (boolean,
416 byte, char, short, int).
418 *******************************************************************************/
420 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
421 methodinfo *m, va_list ap)
426 STATISTICS(jniinvokation());
429 exceptions_throw_nullpointerexception();
433 /* Class initialization is done by the JIT compiler. This is ok
434 since a static method always belongs to the declaring class. */
436 if (m->flags & ACC_STATIC) {
437 /* For static methods we reset the object. */
442 /* for convenience */
447 /* For instance methods we make a virtual function table lookup. */
449 resm = method_vftbl_lookup(vftbl, m);
452 STATISTICS(jnicallXmethodnvokation());
454 i = vm_call_method_int_valist(resm, o, ap);
460 /* _Jv_jni_CallIntMethodA ******************************************************
462 Internal function to call Java integer class methods (boolean,
463 byte, char, short, int).
465 *******************************************************************************/
467 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
468 methodinfo *m, const jvalue *args)
473 STATISTICS(jniinvokation());
476 exceptions_throw_nullpointerexception();
480 /* Class initialization is done by the JIT compiler. This is ok
481 since a static method always belongs to the declaring class. */
483 if (m->flags & ACC_STATIC) {
484 /* For static methods we reset the object. */
489 /* for convenience */
494 /* For instance methods we make a virtual function table lookup. */
496 resm = method_vftbl_lookup(vftbl, m);
499 STATISTICS(jnicallXmethodnvokation());
501 i = vm_call_method_int_jvalue(resm, o, args);
507 /* _Jv_jni_CallLongMethod ******************************************************
509 Internal function to call Java long methods.
511 *******************************************************************************/
513 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
514 methodinfo *m, va_list ap)
519 STATISTICS(jniinvokation());
522 exceptions_throw_nullpointerexception();
526 /* Class initialization is done by the JIT compiler. This is ok
527 since a static method always belongs to the declaring class. */
529 if (m->flags & ACC_STATIC) {
530 /* For static methods we reset the object. */
535 /* for convenience */
540 /* For instance methods we make a virtual function table lookup. */
542 resm = method_vftbl_lookup(vftbl, m);
545 STATISTICS(jnicallXmethodnvokation());
547 l = vm_call_method_long_valist(resm, o, ap);
553 /* _Jv_jni_CallLongMethodA *****************************************************
555 Internal function to call Java long methods.
557 *******************************************************************************/
559 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
560 methodinfo *m, const jvalue *args)
565 STATISTICS(jniinvokation());
568 exceptions_throw_nullpointerexception();
572 /* Class initialization is done by the JIT compiler. This is ok
573 since a static method always belongs to the declaring class. */
575 if (m->flags & ACC_STATIC) {
576 /* For static methods we reset the object. */
581 /* for convenience */
586 /* For instance methods we make a virtual function table lookup. */
588 resm = method_vftbl_lookup(vftbl, m);
591 STATISTICS(jnicallXmethodnvokation());
593 l = vm_call_method_long_jvalue(resm, o, args);
599 /* _Jv_jni_CallFloatMethod *****************************************************
601 Internal function to call Java float methods.
603 *******************************************************************************/
605 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
606 methodinfo *m, va_list ap)
611 /* Class initialization is done by the JIT compiler. This is ok
612 since a static method always belongs to the declaring class. */
614 if (m->flags & ACC_STATIC) {
615 /* For static methods we reset the object. */
620 /* for convenience */
625 /* For instance methods we make a virtual function table lookup. */
627 resm = method_vftbl_lookup(vftbl, m);
630 STATISTICS(jnicallXmethodnvokation());
632 f = vm_call_method_float_valist(resm, o, ap);
638 /* _Jv_jni_CallFloatMethodA ****************************************************
640 Internal function to call Java float methods.
642 *******************************************************************************/
644 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
645 methodinfo *m, const jvalue *args)
650 /* Class initialization is done by the JIT compiler. This is ok
651 since a static method always belongs to the declaring class. */
653 if (m->flags & ACC_STATIC) {
654 /* For static methods we reset the object. */
659 /* for convenience */
664 /* For instance methods we make a virtual function table lookup. */
666 resm = method_vftbl_lookup(vftbl, m);
669 STATISTICS(jnicallXmethodnvokation());
671 f = vm_call_method_float_jvalue(resm, o, args);
677 /* _Jv_jni_CallDoubleMethod ****************************************************
679 Internal function to call Java double methods.
681 *******************************************************************************/
683 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
684 methodinfo *m, va_list ap)
689 /* Class initialization is done by the JIT compiler. This is ok
690 since a static method always belongs to the declaring class. */
692 if (m->flags & ACC_STATIC) {
693 /* For static methods we reset the object. */
698 /* for convenience */
703 /* For instance methods we make a virtual function table lookup. */
705 resm = method_vftbl_lookup(vftbl, m);
708 d = vm_call_method_double_valist(resm, o, ap);
714 /* _Jv_jni_CallDoubleMethodA ***************************************************
716 Internal function to call Java double methods.
718 *******************************************************************************/
720 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
721 methodinfo *m, const jvalue *args)
726 /* Class initialization is done by the JIT compiler. This is ok
727 since a static method always belongs to the declaring class. */
729 if (m->flags & ACC_STATIC) {
730 /* For static methods we reset the object. */
735 /* for convenience */
740 /* For instance methods we make a virtual function table lookup. */
742 resm = method_vftbl_lookup(vftbl, m);
745 d = vm_call_method_double_jvalue(resm, o, args);
751 /* _Jv_jni_CallVoidMethod ******************************************************
753 Internal function to call Java void methods.
755 *******************************************************************************/
757 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
758 methodinfo *m, va_list ap)
763 exceptions_throw_nullpointerexception();
767 /* Class initialization is done by the JIT compiler. This is ok
768 since a static method always belongs to the declaring class. */
770 if (m->flags & ACC_STATIC) {
771 /* For static methods we reset the object. */
776 /* for convenience */
781 /* For instance methods we make a virtual function table lookup. */
783 resm = method_vftbl_lookup(vftbl, m);
786 STATISTICS(jnicallXmethodnvokation());
788 (void) vm_call_method_valist(resm, o, ap);
792 /* _Jv_jni_CallVoidMethodA *****************************************************
794 Internal function to call Java void methods.
796 *******************************************************************************/
798 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
799 methodinfo *m, const jvalue *args)
804 exceptions_throw_nullpointerexception();
808 /* Class initialization is done by the JIT compiler. This is ok
809 since a static method always belongs to the declaring class. */
811 if (m->flags & ACC_STATIC) {
812 /* For static methods we reset the object. */
817 /* for convenience */
822 /* For instance methods we make a virtual function table lookup. */
824 resm = method_vftbl_lookup(vftbl, m);
827 STATISTICS(jnicallXmethodnvokation());
829 (void) vm_call_method_jvalue(resm, o, args);
833 // JNI functions are exported as C functions.
836 /* GetVersion ******************************************************************
838 Returns the major version number in the higher 16 bits and the
839 minor version number in the lower 16 bits.
841 *******************************************************************************/
843 jint _Jv_JNI_GetVersion(JNIEnv *env)
845 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
847 /* We support JNI 1.6. */
849 return JNI_VERSION_1_6;
853 /* Class Operations ***********************************************************/
855 /* DefineClass *****************************************************************
857 Loads a class from a buffer of raw class data. The buffer
858 containing the raw class data is not referenced by the VM after the
859 DefineClass call returns, and it may be discarded if desired.
861 *******************************************************************************/
863 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
864 const jbyte *buf, jsize bufLen)
866 #if defined(ENABLE_JAVASE)
872 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
874 u = utf_new_char(name);
875 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
877 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
879 co = LLNI_classinfo_wrap(c);
881 return (jclass) jni_NewLocalRef(env, (jobject) co);
883 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
885 /* keep compiler happy */
892 /* FindClass *******************************************************************
894 This function loads a locally-defined class. It searches the
895 directories and zip files specified by the CLASSPATH environment
896 variable for the class with the specified name.
898 *******************************************************************************/
900 jclass jni_FindClass(JNIEnv *env, const char *name)
902 #if defined(ENABLE_JAVASE)
909 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
911 /* FIXME If name is NULL we have a problem here. */
913 u = utf_new_char_classname((char *) name);
915 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
916 exceptions_throw_noclassdeffounderror(u);
920 /* Check stacktrace for classloader, if one found use it,
921 otherwise use the system classloader. */
923 /* Quote from the JNI documentation:
925 In the Java 2 Platform, FindClass locates the class loader
926 associated with the current native method. If the native code
927 belongs to a system class, no class loader will be
928 involved. Otherwise, the proper class loader will be invoked to
929 load and link the named class. When FindClass is called through
930 the Invocation Interface, there is no current native method or
931 its associated class loader. In that case, the result of
932 ClassLoader.getBaseClassLoader is used." */
934 cc = stacktrace_get_current_class();
937 c = load_class_from_sysloader(u);
939 c = load_class_from_classloader(u, cc->classloader);
942 resolve_handle_pending_exception(true);
949 co = LLNI_classinfo_wrap(c);
951 return (jclass) jni_NewLocalRef(env, (jobject) co);
953 #elif defined(ENABLE_JAVAME_CLDC1_1)
958 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
960 u = utf_new_char_classname((char *) name);
961 c = load_class_bootstrap(u);
964 resolve_handle_pending_exception(true);
971 return (jclass) jni_NewLocalRef(env, (jobject) c);
974 vm_abort("jni_FindClass: not implemented in this configuration");
976 /* keep compiler happy */
983 /* GetSuperclass ***************************************************************
985 If clazz represents any class other than the class Object, then
986 this function returns the object that represents the superclass of
987 the class specified by clazz.
989 *******************************************************************************/
991 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
997 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
999 c = LLNI_classinfo_unwrap(sub);
1004 super = class_get_superclass(c);
1006 co = LLNI_classinfo_wrap(super);
1008 return (jclass) jni_NewLocalRef(env, (jobject) co);
1012 /* IsAssignableFrom ************************************************************
1014 Determines whether an object of sub can be safely cast to sup.
1016 *******************************************************************************/
1018 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1023 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
1025 to = (classinfo *) sup;
1026 from = (classinfo *) sub;
1028 return class_is_assignable_from(to, from);
1032 /* Throw ***********************************************************************
1034 Causes a java.lang.Throwable object to be thrown.
1036 *******************************************************************************/
1038 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1042 STATISTICS(jniinvokation());
1044 o = (java_handle_t *) obj;
1046 exceptions_set_exception(o);
1052 /* ThrowNew ********************************************************************
1054 Constructs an exception object from the specified class with the
1055 message specified by message and causes that exception to be
1058 *******************************************************************************/
1060 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1066 STATISTICS(jniinvokation());
1068 c = LLNI_classinfo_unwrap(clazz);
1071 s = javastring_new_from_utf_string(msg);
1073 /* instantiate exception object */
1075 o = native_new_and_init_string(c, s);
1080 exceptions_set_exception(o);
1086 /* ExceptionOccurred ***********************************************************
1088 Determines if an exception is being thrown. The exception stays
1089 being thrown until either the native code calls ExceptionClear(),
1090 or the Java code handles the exception.
1092 *******************************************************************************/
1094 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1098 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1100 o = exceptions_get_exception();
1102 return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1106 /* ExceptionDescribe ***********************************************************
1108 Prints an exception and a backtrace of the stack to a system
1109 error-reporting channel, such as stderr. This is a convenience
1110 routine provided for debugging.
1112 *******************************************************************************/
1114 void jni_ExceptionDescribe(JNIEnv *env)
1116 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1118 exceptions_print_stacktrace();
1122 /* ExceptionClear **************************************************************
1124 Clears any exception that is currently being thrown. If no
1125 exception is currently being thrown, this routine has no effect.
1127 *******************************************************************************/
1129 void jni_ExceptionClear(JNIEnv *env)
1131 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1133 exceptions_clear_exception();
1137 /* FatalError ******************************************************************
1139 Raises a fatal error and does not expect the VM to recover. This
1140 function does not return.
1142 *******************************************************************************/
1144 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1146 STATISTICS(jniinvokation());
1148 /* this seems to be the best way */
1150 vm_abort("JNI Fatal error: %s", msg);
1154 /* PushLocalFrame **************************************************************
1156 Creates a new local reference frame, in which at least a given
1157 number of local references can be created.
1159 *******************************************************************************/
1161 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1163 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1168 /* add new local reference frame to current table */
1170 if (!localref_frame_push(capacity))
1177 /* PopLocalFrame ***************************************************************
1179 Pops off the current local reference frame, frees all the local
1180 references, and returns a local reference in the previous local
1181 reference frame for the given result object.
1183 *******************************************************************************/
1185 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1187 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1189 /* release all current local frames */
1191 localref_frame_pop_all();
1193 /* add local reference and return the value */
1195 return jni_NewLocalRef(env, result);
1199 /* DeleteLocalRef **************************************************************
1201 Deletes the local reference pointed to by localRef.
1203 *******************************************************************************/
1205 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1209 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1211 o = (java_handle_t *) localRef;
1216 /* delete the reference */
1222 /* IsSameObject ****************************************************************
1224 Tests whether two references refer to the same Java object.
1226 *******************************************************************************/
1228 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1234 STATISTICS(jniinvokation());
1236 o1 = (java_handle_t *) ref1;
1237 o2 = (java_handle_t *) ref2;
1239 LLNI_CRITICAL_START;
1241 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1252 /* NewLocalRef *****************************************************************
1254 Creates a new local reference that refers to the same object as ref.
1256 *******************************************************************************/
1258 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1261 java_handle_t *localref;
1263 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1265 o = (java_handle_t *) ref;
1270 /* insert the reference */
1272 localref = localref_add(LLNI_DIRECT(o));
1274 return (jobject) localref;
1278 /* EnsureLocalCapacity *********************************************************
1280 Ensures that at least a given number of local references can be
1281 created in the current thread
1283 *******************************************************************************/
1285 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1287 localref_table *lrt;
1289 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1291 /* get local reference table (thread specific) */
1293 lrt = LOCALREFTABLE;
1295 /* check if capacity elements are available in the local references table */
1297 if ((lrt->used + capacity) > lrt->capacity)
1298 return jni_PushLocalFrame(env, capacity);
1304 /* AllocObject *****************************************************************
1306 Allocates a new Java object without invoking any of the
1307 constructors for the object. Returns a reference to the object.
1309 *******************************************************************************/
1311 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1316 STATISTICS(jniinvokation());
1318 c = LLNI_classinfo_unwrap(clazz);
1320 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1321 exceptions_throw_instantiationexception(c);
1327 return jni_NewLocalRef(env, (jobject) o);
1331 /* NewObject *******************************************************************
1333 Programmers place all arguments that are to be passed to the
1334 constructor immediately following the methodID
1335 argument. NewObject() accepts these arguments and passes them to
1336 the Java method that the programmer wishes to invoke.
1338 *******************************************************************************/
1340 jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1347 TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1349 c = LLNI_classinfo_unwrap(clazz);
1350 m = (methodinfo *) methodID;
1359 /* call constructor */
1361 va_start(ap, methodID);
1362 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1365 TRACEJNICALLSEXIT(("->%p", o));
1367 return jni_NewLocalRef(env, (jobject) o);
1371 /* NewObjectV ******************************************************************
1373 Programmers place all arguments that are to be passed to the
1374 constructor in an args argument of type va_list that immediately
1375 follows the methodID argument. NewObjectV() accepts these
1376 arguments, and, in turn, passes them to the Java method that the
1377 programmer wishes to invoke.
1379 *******************************************************************************/
1381 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1388 STATISTICS(jniinvokation());
1390 c = LLNI_classinfo_unwrap(clazz);
1391 m = (methodinfo *) methodID;
1400 /* call constructor */
1402 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1404 return jni_NewLocalRef(env, (jobject) o);
1408 /* NewObjectA *****************************************************************
1410 Programmers place all arguments that are to be passed to the
1411 constructor in an args array of jvalues that immediately follows
1412 the methodID argument. NewObjectA() accepts the arguments in this
1413 array, and, in turn, passes them to the Java method that the
1414 programmer wishes to invoke.
1416 *******************************************************************************/
1418 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1425 STATISTICS(jniinvokation());
1427 c = LLNI_classinfo_unwrap(clazz);
1428 m = (methodinfo *) methodID;
1437 /* call constructor */
1439 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1441 return jni_NewLocalRef(env, (jobject) o);
1445 /* GetObjectClass **************************************************************
1447 Returns the class of an object.
1449 *******************************************************************************/
1451 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1455 java_lang_Class *co;
1457 STATISTICS(jniinvokation());
1459 o = (java_handle_t *) obj;
1461 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1464 LLNI_class_get(o, c);
1466 co = LLNI_classinfo_wrap(c);
1468 return (jclass) jni_NewLocalRef(env, (jobject) co);
1472 /* IsInstanceOf ****************************************************************
1474 Tests whether an object is an instance of a class.
1476 *******************************************************************************/
1478 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1483 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1485 /* XXX Is this correct? */
1486 c = LLNI_classinfo_unwrap(clazz);
1487 h = (java_handle_t *) obj;
1489 return class_is_instance(c, h);
1493 /* Reflection Support *********************************************************/
1495 /* FromReflectedMethod *********************************************************
1497 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1498 object to a method ID.
1500 *******************************************************************************/
1502 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1504 #if defined(ENABLE_JAVASE)
1506 java_lang_reflect_Method *rm;
1507 java_lang_reflect_Constructor *rc;
1512 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1513 java_lang_reflect_VMMethod *rvmm;
1514 java_lang_reflect_VMConstructor *rvmc;
1517 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1519 o = (java_handle_t *) method;
1524 if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
1525 rc = (java_lang_reflect_Constructor *) method;
1527 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1529 LLNI_field_get_ref(rc, cons , rvmc);
1530 LLNI_field_get_cls(rvmc, clazz, c);
1531 LLNI_field_get_val(rvmc, slot , slot);
1533 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1535 LLNI_field_get_cls(rc, clazz, c);
1536 LLNI_field_get_val(rc, slot , slot);
1539 # error unknown configuration
1543 assert(o->vftbl->clazz == class_java_lang_reflect_Method);
1545 rm = (java_lang_reflect_Method *) method;
1547 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1549 LLNI_field_get_ref(rm, m , rvmm);
1550 LLNI_field_get_cls(rvmm, clazz, c);
1551 LLNI_field_get_val(rvmm, slot , slot);
1553 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1555 LLNI_field_get_cls(rm, clazz, c);
1556 LLNI_field_get_val(rm, slot , slot);
1559 # error unknown configuration
1563 m = &(c->methods[slot]);
1565 return (jmethodID) m;
1567 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1569 /* Keep compiler happy. */
1576 /* FromReflectedField **********************************************************
1578 Converts a java.lang.reflect.Field to a field ID.
1580 *******************************************************************************/
1582 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1584 #if defined(ENABLE_JAVASE)
1585 java_lang_reflect_Field *rf;
1590 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1591 java_lang_reflect_VMField *rvmf;
1594 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1596 rf = (java_lang_reflect_Field *) field;
1601 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1603 LLNI_field_get_ref(rf, f, rvmf);
1604 LLNI_field_get_cls(rvmf, clazz, c);
1605 LLNI_field_get_val(rvmf, slot , slot);
1607 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1609 LLNI_field_get_cls(rf, clazz, c);
1610 LLNI_field_get_val(rf, slot , slot);
1613 # error unknown configuration
1616 f = &(c->fields[slot]);
1618 return (jfieldID) f;
1620 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1622 /* Keep compiler happy. */
1629 /* ToReflectedMethod ***********************************************************
1631 Converts a method ID derived from cls to an instance of the
1632 java.lang.reflect.Method class or to an instance of the
1633 java.lang.reflect.Constructor class.
1635 *******************************************************************************/
1637 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1640 #if defined(ENABLE_JAVASE)
1642 java_lang_reflect_Constructor *rc;
1643 java_lang_reflect_Method *rm;
1645 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1647 m = (methodinfo *) methodID;
1649 /* HotSpot does the same assert. */
1651 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1653 if (m->name == utf_init) {
1654 rc = reflect_constructor_new(m);
1656 return (jobject) rc;
1659 rm = reflect_method_new(m);
1661 return (jobject) rm;
1664 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1666 /* keep compiler happy */
1673 /* ToReflectedField ************************************************************
1675 Converts a field ID derived from cls to an instance of the
1676 java.lang.reflect.Field class.
1678 *******************************************************************************/
1680 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1683 STATISTICS(jniinvokation());
1685 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1691 /* Calling Instance Methods ***************************************************/
1693 /* GetMethodID *****************************************************************
1695 Returns the method ID for an instance (nonstatic) method of a class
1696 or interface. The method may be defined in one of the clazz's
1697 superclasses and inherited by clazz. The method is determined by
1698 its name and signature.
1700 GetMethodID() causes an uninitialized class to be initialized.
1702 *******************************************************************************/
1704 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1712 STATISTICS(jniinvokation());
1714 c = LLNI_classinfo_unwrap(clazz);
1719 if (!(c->state & CLASS_INITIALIZED))
1720 if (!initialize_class(c))
1723 /* try to get the method of the class or one of it's superclasses */
1725 uname = utf_new_char((char *) name);
1726 udesc = utf_new_char((char *) sig);
1728 m = class_resolvemethod(c, uname, udesc);
1730 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1731 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1736 return (jmethodID) m;
1740 /* JNI-functions for calling instance methods *********************************/
1742 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1743 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1744 jmethodID methodID, ...) \
1751 o = (java_handle_t *) obj; \
1752 m = (methodinfo *) methodID; \
1754 va_start(ap, methodID); \
1755 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1761 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1762 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1763 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1764 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1765 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1766 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1767 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1768 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1771 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1772 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1773 jmethodID methodID, va_list args) \
1779 o = (java_handle_t *) obj; \
1780 m = (methodinfo *) methodID; \
1782 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1787 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1788 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1789 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1790 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1791 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1792 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1793 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1794 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1797 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1798 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1799 jmethodID methodID, \
1800 const jvalue *args) \
1806 o = (java_handle_t *) obj; \
1807 m = (methodinfo *) methodID; \
1809 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1814 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1815 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1816 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1817 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1818 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1819 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1820 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1821 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1824 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1832 o = (java_handle_t *) obj;
1833 m = (methodinfo *) methodID;
1835 va_start(ap, methodID);
1836 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1839 return jni_NewLocalRef(env, (jobject) ret);
1843 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1850 o = (java_handle_t *) obj;
1851 m = (methodinfo *) methodID;
1853 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1855 return jni_NewLocalRef(env, (jobject) ret);
1859 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1866 o = (java_handle_t *) obj;
1867 m = (methodinfo *) methodID;
1869 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1871 return jni_NewLocalRef(env, (jobject) ret);
1876 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1882 o = (java_handle_t *) obj;
1883 m = (methodinfo *) methodID;
1885 va_start(ap, methodID);
1886 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1891 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1897 o = (java_handle_t *) obj;
1898 m = (methodinfo *) methodID;
1900 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1904 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1910 o = (java_handle_t *) obj;
1911 m = (methodinfo *) methodID;
1913 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1918 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1919 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1920 jclass clazz, jmethodID methodID, \
1929 o = (java_handle_t *) obj; \
1930 c = LLNI_classinfo_unwrap(clazz); \
1931 m = (methodinfo *) methodID; \
1933 va_start(ap, methodID); \
1934 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1940 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1941 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1942 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1943 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1944 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1945 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1946 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1947 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1950 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1951 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1952 jclass clazz, jmethodID methodID, \
1960 o = (java_handle_t *) obj; \
1961 c = LLNI_classinfo_unwrap(clazz); \
1962 m = (methodinfo *) methodID; \
1964 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1969 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1970 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1971 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1972 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1973 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1974 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1975 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1976 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1979 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1980 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1981 jclass clazz, jmethodID methodID, \
1982 const jvalue *args) \
1984 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1989 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1990 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1991 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1992 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1993 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1994 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1995 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1996 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1998 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1999 jclass clazz, jmethodID methodID,
2008 o = (java_handle_t *) obj;
2009 c = LLNI_classinfo_unwrap(clazz);
2010 m = (methodinfo *) methodID;
2012 va_start(ap, methodID);
2013 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2016 return jni_NewLocalRef(env, (jobject) r);
2020 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2021 jclass clazz, jmethodID methodID,
2029 o = (java_handle_t *) obj;
2030 c = LLNI_classinfo_unwrap(clazz);
2031 m = (methodinfo *) methodID;
2033 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2035 return jni_NewLocalRef(env, (jobject) r);
2039 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2040 jclass clazz, jmethodID methodID,
2043 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2045 return jni_NewLocalRef(env, NULL);
2049 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2050 jmethodID methodID, ...)
2057 o = (java_handle_t *) obj;
2058 c = LLNI_classinfo_unwrap(clazz);
2059 m = (methodinfo *) methodID;
2061 va_start(ap, methodID);
2062 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2067 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2068 jmethodID methodID, va_list args)
2074 o = (java_handle_t *) obj;
2075 c = LLNI_classinfo_unwrap(clazz);
2076 m = (methodinfo *) methodID;
2078 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2082 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2083 jmethodID methodID, const jvalue * args)
2089 o = (java_handle_t *) obj;
2090 c = LLNI_classinfo_unwrap(clazz);
2091 m = (methodinfo *) methodID;
2093 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2097 /* Accessing Fields of Objects ************************************************/
2099 /* GetFieldID ******************************************************************
2101 Returns the field ID for an instance (nonstatic) field of a
2102 class. The field is specified by its name and signature. The
2103 Get<type>Field and Set<type>Field families of accessor functions
2104 use field IDs to retrieve object fields.
2106 *******************************************************************************/
2108 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2116 STATISTICS(jniinvokation());
2118 c = LLNI_classinfo_unwrap(clazz);
2120 /* XXX NPE check? */
2122 uname = utf_new_char((char *) name);
2123 udesc = utf_new_char((char *) sig);
2125 f = class_findfield(c, uname, udesc);
2128 exceptions_throw_nosuchfielderror(c, uname);
2130 return (jfieldID) f;
2134 /* Get<type>Field Routines *****************************************************
2136 This family of accessor routines returns the value of an instance
2137 (nonstatic) field of an object. The field to access is specified by
2138 a field ID obtained by calling GetFieldID().
2140 *******************************************************************************/
2142 #define GET_FIELD(o,type,f) \
2143 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2145 #define JNI_GET_FIELD(name, type, intern) \
2146 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2150 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2152 LLNI_CRITICAL_START; \
2154 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2156 LLNI_CRITICAL_END; \
2158 return (type) ret; \
2161 JNI_GET_FIELD(Boolean, jboolean, s4)
2162 JNI_GET_FIELD(Byte, jbyte, s4)
2163 JNI_GET_FIELD(Char, jchar, s4)
2164 JNI_GET_FIELD(Short, jshort, s4)
2165 JNI_GET_FIELD(Int, jint, s4)
2166 JNI_GET_FIELD(Long, jlong, s8)
2167 JNI_GET_FIELD(Float, jfloat, float)
2168 JNI_GET_FIELD(Double, jdouble, double)
2171 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2175 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2177 LLNI_CRITICAL_START;
2179 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2183 return jni_NewLocalRef(env, (jobject) o);
2187 /* Set<type>Field Routines *****************************************************
2189 This family of accessor routines sets the value of an instance
2190 (nonstatic) field of an object. The field to access is specified by
2191 a field ID obtained by calling GetFieldID().
2193 *******************************************************************************/
2195 #define SET_FIELD(o,type,f,value) \
2196 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2198 #define JNI_SET_FIELD(name, type, intern) \
2199 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2202 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2204 LLNI_CRITICAL_START; \
2206 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2208 LLNI_CRITICAL_START; \
2211 JNI_SET_FIELD(Boolean, jboolean, s4)
2212 JNI_SET_FIELD(Byte, jbyte, s4)
2213 JNI_SET_FIELD(Char, jchar, s4)
2214 JNI_SET_FIELD(Short, jshort, s4)
2215 JNI_SET_FIELD(Int, jint, s4)
2216 JNI_SET_FIELD(Long, jlong, s8)
2217 JNI_SET_FIELD(Float, jfloat, float)
2218 JNI_SET_FIELD(Double, jdouble, double)
2221 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2224 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2226 LLNI_CRITICAL_START;
2228 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2234 /* Calling Static Methods *****************************************************/
2236 /* GetStaticMethodID ***********************************************************
2238 Returns the method ID for a static method of a class. The method is
2239 specified by its name and signature.
2241 GetStaticMethodID() causes an uninitialized class to be
2244 *******************************************************************************/
2246 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2254 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2256 c = LLNI_classinfo_unwrap(clazz);
2261 if (!(c->state & CLASS_INITIALIZED))
2262 if (!initialize_class(c))
2265 /* try to get the static method of the class */
2267 uname = utf_new_char((char *) name);
2268 udesc = utf_new_char((char *) sig);
2270 m = class_resolvemethod(c, uname, udesc);
2272 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2273 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2278 return (jmethodID) m;
2282 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2283 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2284 jmethodID methodID, ...) \
2290 m = (methodinfo *) methodID; \
2292 va_start(ap, methodID); \
2293 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2299 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2300 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2301 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2302 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2303 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2304 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2305 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2306 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2309 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2310 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2311 jmethodID methodID, va_list args) \
2316 m = (methodinfo *) methodID; \
2318 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2323 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2324 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2325 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2326 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2327 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2328 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2329 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2330 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2333 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2334 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2335 jmethodID methodID, const jvalue *args) \
2340 m = (methodinfo *) methodID; \
2342 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2347 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2348 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2349 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2350 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2351 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2352 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2353 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2354 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2357 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2358 jmethodID methodID, ...)
2364 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2366 m = (methodinfo *) methodID;
2368 va_start(ap, methodID);
2369 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2372 return jni_NewLocalRef(env, (jobject) o);
2376 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2377 jmethodID methodID, va_list args)
2382 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2384 m = (methodinfo *) methodID;
2386 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2388 return jni_NewLocalRef(env, (jobject) o);
2392 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2393 jmethodID methodID, const jvalue *args)
2398 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2400 m = (methodinfo *) methodID;
2402 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2404 return jni_NewLocalRef(env, (jobject) o);
2408 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2409 jmethodID methodID, ...)
2414 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2416 m = (methodinfo *) methodID;
2418 va_start(ap, methodID);
2419 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2424 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2425 jmethodID methodID, va_list args)
2429 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2431 m = (methodinfo *) methodID;
2433 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2437 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2438 jmethodID methodID, const jvalue * args)
2442 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2444 m = (methodinfo *) methodID;
2446 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2450 /* Accessing Static Fields ****************************************************/
2452 /* GetStaticFieldID ************************************************************
2454 Returns the field ID for a static field of a class. The field is
2455 specified by its name and signature. The GetStatic<type>Field and
2456 SetStatic<type>Field families of accessor functions use field IDs
2457 to retrieve static fields.
2459 *******************************************************************************/
2461 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2469 STATISTICS(jniinvokation());
2471 c = LLNI_classinfo_unwrap(clazz);
2473 uname = utf_new_char((char *) name);
2474 usig = utf_new_char((char *) sig);
2476 f = class_findfield(c, uname, usig);
2479 exceptions_throw_nosuchfielderror(c, uname);
2481 return (jfieldID) f;
2485 /* GetStatic<type>Field ********************************************************
2487 This family of accessor routines returns the value of a static
2490 *******************************************************************************/
2492 #define JNI_GET_STATIC_FIELD(name, type, field) \
2493 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2499 STATISTICS(jniinvokation()); \
2501 c = LLNI_classinfo_unwrap(clazz); \
2502 f = (fieldinfo *) fieldID; \
2504 if (!(c->state & CLASS_INITIALIZED)) \
2505 if (!initialize_class(c)) \
2508 return f->value->field; \
2511 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2512 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2513 JNI_GET_STATIC_FIELD(Char, jchar, i)
2514 JNI_GET_STATIC_FIELD(Short, jshort, i)
2515 JNI_GET_STATIC_FIELD(Int, jint, i)
2516 JNI_GET_STATIC_FIELD(Long, jlong, l)
2517 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2518 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2521 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2528 STATISTICS(jniinvokation());
2530 c = LLNI_classinfo_unwrap(clazz);
2531 f = (fieldinfo *) fieldID;
2533 if (!(c->state & CLASS_INITIALIZED))
2534 if (!initialize_class(c))
2537 h = (java_handle_t*) LLNI_WRAP(f->value->a);
2539 return jni_NewLocalRef(env, (jobject) h);
2543 /* SetStatic<type>Field *******************************************************
2545 This family of accessor routines sets the value of a static field
2548 *******************************************************************************/
2550 #define JNI_SET_STATIC_FIELD(name, type, field) \
2551 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2558 STATISTICS(jniinvokation()); \
2560 c = LLNI_classinfo_unwrap(clazz); \
2561 f = (fieldinfo *) fieldID; \
2563 if (!(c->state & CLASS_INITIALIZED)) \
2564 if (!initialize_class(c)) \
2567 f->value->field = value; \
2570 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2571 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2572 JNI_SET_STATIC_FIELD(Char, jchar, i)
2573 JNI_SET_STATIC_FIELD(Short, jshort, i)
2574 JNI_SET_STATIC_FIELD(Int, jint, i)
2575 JNI_SET_STATIC_FIELD(Long, jlong, l)
2576 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2577 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2580 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2586 STATISTICS(jniinvokation());
2588 c = LLNI_classinfo_unwrap(clazz);
2589 f = (fieldinfo *) fieldID;
2591 if (!(c->state & CLASS_INITIALIZED))
2592 if (!initialize_class(c))
2595 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2599 /* String Operations **********************************************************/
2601 /* NewString *******************************************************************
2603 Create new java.lang.String object from an array of Unicode
2606 *******************************************************************************/
2608 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2610 java_lang_String *s;
2611 java_handle_chararray_t *a;
2614 STATISTICS(jniinvokation());
2616 s = (java_lang_String *) builtin_new(class_java_lang_String);
2617 a = builtin_newarray_char(len);
2619 /* javastring or characterarray could not be created */
2620 if ((a == NULL) || (s == NULL))
2624 for (i = 0; i < len; i++)
2625 LLNI_array_direct(a, i) = buf[i];
2627 LLNI_field_set_ref(s, value , a);
2628 LLNI_field_set_val(s, offset, 0);
2629 LLNI_field_set_val(s, count , len);
2631 return (jstring) jni_NewLocalRef(env, (jobject) s);
2635 static jchar emptyStringJ[]={0,0};
2637 /* GetStringLength *************************************************************
2639 Returns the length (the count of Unicode characters) of a Java
2642 *******************************************************************************/
2644 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2646 java_lang_String *s;
2649 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2651 s = (java_lang_String *) str;
2653 LLNI_field_get_val(s, count, len);
2659 /* GetStringChars **************************************************************
2661 Returns a pointer to the array of Unicode characters of the
2662 string. This pointer is valid until ReleaseStringChars() is called.
2664 *******************************************************************************/
2666 const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2668 java_lang_String *s;
2669 java_handle_chararray_t *a;
2675 TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2678 // FIXME This is really ugly.
2679 return emptyStringJ;
2681 s = (java_lang_String *) str;
2683 LLNI_field_get_ref(s, value, a);
2688 LLNI_field_get_val(s, count, count);
2689 LLNI_field_get_val(s, offset, offset);
2691 /* allocate memory */
2693 stringbuffer = MNEW(u2, count + 1);
2697 for (i = 0; i < count; i++)
2698 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2700 /* terminate string */
2702 stringbuffer[i] = '\0';
2707 return (jchar*) stringbuffer;
2711 /* ReleaseStringChars **********************************************************
2713 Informs the VM that the native code no longer needs access to
2714 chars. The chars argument is a pointer obtained from string using
2717 *******************************************************************************/
2719 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2721 java_lang_String *s;
2723 STATISTICS(jniinvokation());
2725 if (chars == emptyStringJ)
2728 s = (java_lang_String *) str;
2730 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2734 /* NewStringUTF ****************************************************************
2736 Constructs a new java.lang.String object from an array of UTF-8
2739 *******************************************************************************/
2741 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2743 java_lang_String *s;
2745 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2747 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2749 return (jstring) jni_NewLocalRef(env, (jobject) s);
2753 /****************** returns the utf8 length in bytes of a string *******************/
2755 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2757 java_lang_String *s;
2760 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2762 s = (java_lang_String *) string;
2764 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2770 /* GetStringUTFChars ***********************************************************
2772 Returns a pointer to an array of UTF-8 characters of the
2773 string. This array is valid until it is released by
2774 ReleaseStringUTFChars().
2776 *******************************************************************************/
2778 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2783 STATISTICS(jniinvokation());
2791 u = javastring_toutf((java_handle_t *) string, false);
2800 /* ReleaseStringUTFChars *******************************************************
2802 Informs the VM that the native code no longer needs access to
2803 utf. The utf argument is a pointer derived from string using
2804 GetStringUTFChars().
2806 *******************************************************************************/
2808 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2810 STATISTICS(jniinvokation());
2812 /* XXX we don't release utf chars right now, perhaps that should be done
2813 later. Since there is always one reference the garbage collector will
2818 /* Array Operations ***********************************************************/
2820 /* GetArrayLength **************************************************************
2822 Returns the number of elements in the array.
2824 *******************************************************************************/
2826 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2831 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2833 a = (java_handle_t *) array;
2835 size = LLNI_array_size(a);
2841 /* NewObjectArray **************************************************************
2843 Constructs a new array holding objects in class elementClass. All
2844 elements are initially set to initialElement.
2846 *******************************************************************************/
2848 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2849 jclass elementClass, jobject initialElement)
2853 java_handle_objectarray_t *oa;
2856 STATISTICS(jniinvokation());
2858 c = LLNI_classinfo_unwrap(elementClass);
2859 o = (java_handle_t *) initialElement;
2862 exceptions_throw_negativearraysizeexception();
2866 oa = builtin_anewarray(length, c);
2871 /* set all elements to initialElement */
2873 for (i = 0; i < length; i++)
2874 array_objectarray_element_set(oa, i, o);
2876 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2880 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2883 java_handle_objectarray_t *oa;
2886 STATISTICS(jniinvokation());
2888 oa = (java_handle_objectarray_t *) array;
2890 if (index >= LLNI_array_size(oa)) {
2891 exceptions_throw_arrayindexoutofboundsexception();
2895 o = array_objectarray_element_get(oa, index);
2897 return jni_NewLocalRef(env, (jobject) o);
2901 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2902 jsize index, jobject val)
2904 java_handle_objectarray_t *oa;
2907 STATISTICS(jniinvokation());
2909 oa = (java_handle_objectarray_t *) array;
2910 o = (java_handle_t *) val;
2912 if (index >= LLNI_array_size(oa)) {
2913 exceptions_throw_arrayindexoutofboundsexception();
2917 /* check if the class of value is a subclass of the element class
2920 if (!builtin_canstore(oa, o))
2923 array_objectarray_element_set(oa, index, o);
2927 #define JNI_NEW_ARRAY(name, type, intern) \
2928 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2930 java_handle_##intern##array_t *a; \
2932 STATISTICS(jniinvokation()); \
2935 exceptions_throw_negativearraysizeexception(); \
2939 a = builtin_newarray_##intern(len); \
2941 return (type) jni_NewLocalRef(env, (jobject) a); \
2944 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2945 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2946 JNI_NEW_ARRAY(Char, jcharArray, char)
2947 JNI_NEW_ARRAY(Short, jshortArray, short)
2948 JNI_NEW_ARRAY(Int, jintArray, int)
2949 JNI_NEW_ARRAY(Long, jlongArray, long)
2950 JNI_NEW_ARRAY(Float, jfloatArray, float)
2951 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2954 /* Get<PrimitiveType>ArrayElements *********************************************
2956 A family of functions that returns the body of the primitive array.
2958 *******************************************************************************/
2960 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2961 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2964 java_handle_##intern##array_t *a; \
2966 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2968 a = (java_handle_##intern##array_t *) array; \
2971 *isCopy = JNI_FALSE; \
2973 return (type *) LLNI_array_data(a); \
2976 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2977 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2978 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2979 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2980 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2981 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2982 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2983 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2986 /* Release<PrimitiveType>ArrayElements *****************************************
2988 A family of functions that informs the VM that the native code no
2989 longer needs access to elems. The elems argument is a pointer
2990 derived from array using the corresponding
2991 Get<PrimitiveType>ArrayElements() function. If necessary, this
2992 function copies back all changes made to elems to the original
2995 *******************************************************************************/
2997 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2998 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2999 type *elems, jint mode) \
3001 java_handle_##intern##array_t *a; \
3003 STATISTICS(jniinvokation()); \
3005 a = (java_handle_##intern##array_t *) array; \
3007 if (elems != (type *) LLNI_array_data(a)) { \
3010 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3013 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3014 /* XXX TWISTI how should it be freed? */ \
3017 /* XXX TWISTI how should it be freed? */ \
3023 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3024 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3025 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3026 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3027 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3028 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3029 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3030 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3033 /* Get<PrimitiveType>ArrayRegion **********************************************
3035 A family of functions that copies a region of a primitive array
3038 *******************************************************************************/
3040 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3041 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3042 jsize start, jsize len, type *buf) \
3044 java_handle_##intern##array_t *a; \
3046 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3048 a = (java_handle_##intern##array_t *) array; \
3050 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3051 exceptions_throw_arrayindexoutofboundsexception(); \
3053 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3056 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3057 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3058 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3059 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3060 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3061 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3062 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3063 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3066 /* Set<PrimitiveType>ArrayRegion **********************************************
3068 A family of functions that copies back a region of a primitive
3069 array from a buffer.
3071 *******************************************************************************/
3073 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3074 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3075 jsize start, jsize len, const type *buf) \
3077 java_handle_##intern##array_t *a; \
3079 STATISTICS(jniinvokation()); \
3081 a = (java_handle_##intern##array_t *) array; \
3083 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3084 exceptions_throw_arrayindexoutofboundsexception(); \
3086 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3089 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3090 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3091 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3092 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3093 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3094 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3095 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3096 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3099 /* Registering Native Methods *************************************************/
3101 /* RegisterNatives *************************************************************
3103 Registers native methods with the class specified by the clazz
3104 argument. The methods parameter specifies an array of
3105 JNINativeMethod structures that contain the names, signatures, and
3106 function pointers of the native methods. The nMethods parameter
3107 specifies the number of native methods in the array.
3109 *******************************************************************************/
3111 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3112 const JNINativeMethod *methods, jint nMethods)
3116 STATISTICS(jniinvokation());
3118 c = LLNI_classinfo_unwrap(clazz);
3120 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3121 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3124 native_method_register(c->name, methods, nMethods);
3130 /* UnregisterNatives ***********************************************************
3132 Unregisters native methods of a class. The class goes back to the
3133 state before it was linked or registered with its native method
3136 This function should not be used in normal native code. Instead, it
3137 provides special programs a way to reload and relink native
3140 *******************************************************************************/
3142 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3144 STATISTICS(jniinvokation());
3146 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3148 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3154 /* Monitor Operations *********************************************************/
3156 /* MonitorEnter ****************************************************************
3158 Enters the monitor associated with the underlying Java object
3161 *******************************************************************************/
3163 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3165 STATISTICS(jniinvokation());
3168 exceptions_throw_nullpointerexception();
3172 LOCK_MONITOR_ENTER(obj);
3178 /* MonitorExit *****************************************************************
3180 The current thread must be the owner of the monitor associated with
3181 the underlying Java object referred to by obj. The thread
3182 decrements the counter indicating the number of times it has
3183 entered this monitor. If the value of the counter becomes zero, the
3184 current thread releases the monitor.
3186 *******************************************************************************/
3188 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3190 STATISTICS(jniinvokation());
3193 exceptions_throw_nullpointerexception();
3197 LOCK_MONITOR_EXIT(obj);
3203 /* JavaVM Interface ***********************************************************/
3205 /* GetJavaVM *******************************************************************
3207 Returns the Java VM interface (used in the Invocation API)
3208 associated with the current thread. The result is placed at the
3209 location pointed to by the second argument, vm.
3211 *******************************************************************************/
3213 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3215 STATISTICS(jniinvokation());
3217 *javavm = vm->get_javavm();
3223 /* GetStringRegion *************************************************************
3225 Copies len number of Unicode characters beginning at offset start
3226 to the given buffer buf.
3228 Throws StringIndexOutOfBoundsException on index overflow.
3230 *******************************************************************************/
3232 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3235 java_lang_String *s;
3236 java_handle_chararray_t *ca;
3238 STATISTICS(jniinvokation());
3240 s = (java_lang_String *) str;
3241 LLNI_field_get_ref(s, value, ca);
3243 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3244 (start + len > LLNI_field_direct(s, count))) {
3245 exceptions_throw_stringindexoutofboundsexception();
3249 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3253 /* GetStringUTFRegion **********************************************************
3255 Translates len number of Unicode characters beginning at offset
3256 start into UTF-8 format and place the result in the given buffer
3259 Throws StringIndexOutOfBoundsException on index overflow.
3261 *******************************************************************************/
3263 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3264 jsize len, char *buf)
3266 java_lang_String *s;
3267 java_handle_chararray_t *ca;
3272 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3274 s = (java_lang_String *) str;
3275 LLNI_field_get_ref(s, value, ca);
3276 LLNI_field_get_val(s, count, count);
3277 LLNI_field_get_val(s, offset, offset);
3279 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3280 exceptions_throw_stringindexoutofboundsexception();
3284 for (i = 0; i < len; i++)
3285 buf[i] = LLNI_array_direct(ca, offset + start + i);
3291 /* GetPrimitiveArrayCritical ***************************************************
3293 Obtain a direct pointer to array elements.
3295 ATTENTION: Critical section keeps open when this function returns!
3296 See ReleasePrimitiveArrayCritical.
3298 *******************************************************************************/
3300 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3304 arraydescriptor* ad;
3307 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3309 if (isCopy != NULL) {
3310 *isCopy = JNI_FALSE;
3313 LLNI_CRITICAL_START;
3315 h = (java_handle_t*) array;
3316 a = (java_array_t*) LLNI_UNWRAP(h);
3317 ad = a->objheader.vftbl->arraydesc;
3323 data = (void*) (((intptr_t) a) + ad->dataoffset);
3329 /* ReleasePrimitiveArrayCritical ***********************************************
3331 No specific documentation.
3333 ATTENTION: This function closes the critical section opened in
3334 GetPrimitiveArrayCritical!
3336 *******************************************************************************/
3338 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3340 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3346 /* GetStringCritical ***********************************************************
3348 The semantics of these two functions are similar to the existing
3349 Get/ReleaseStringChars functions.
3351 *******************************************************************************/
3353 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3356 STATISTICS(jniinvokation());
3358 return jni_GetStringChars(env, string, isCopy);
3362 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3363 const jchar *cstring)
3365 STATISTICS(jniinvokation());
3367 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3371 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3373 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3379 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3381 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3385 /* NewGlobalRef ****************************************************************
3387 Creates a new global reference to the object referred to by the obj
3390 *******************************************************************************/
3392 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3394 hashtable_global_ref_entry *gre;
3395 u4 key; /* hashkey */
3396 u4 slot; /* slot in hashtable */
3399 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3401 o = (java_handle_t *) obj;
3403 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3405 LLNI_CRITICAL_START;
3407 /* normally addresses are aligned to 4, 8 or 16 bytes */
3409 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3410 slot = key & (hashtable_global_ref->size - 1);
3411 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3413 /* search external hash chain for the entry */
3416 if (gre->o == LLNI_DIRECT(o)) {
3417 /* global object found, increment the reference */
3424 gre = gre->hashlink; /* next element in external chain */
3429 /* global ref not found, create a new one */
3432 gre = GCNEW_UNCOLLECTABLE(hashtable_global_ref_entry, 1);
3434 #if defined(ENABLE_GC_CACAO)
3435 /* register global ref with the GC */
3437 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3440 LLNI_CRITICAL_START;
3442 gre->o = LLNI_DIRECT(o);
3447 /* insert entry into hashtable */
3449 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3451 hashtable_global_ref->ptr[slot] = gre;
3453 /* update number of hashtable-entries */
3455 hashtable_global_ref->entries++;
3458 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3460 #if defined(ENABLE_HANDLES)
3468 /* DeleteGlobalRef *************************************************************
3470 Deletes the global reference pointed to by globalRef.
3472 *******************************************************************************/
3474 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3476 hashtable_global_ref_entry *gre;
3477 hashtable_global_ref_entry *prevgre;
3478 u4 key; /* hashkey */
3479 u4 slot; /* slot in hashtable */
3482 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3484 o = (java_handle_t *) globalRef;
3486 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3488 LLNI_CRITICAL_START;
3490 /* normally addresses are aligned to 4, 8 or 16 bytes */
3492 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3493 slot = key & (hashtable_global_ref->size - 1);
3494 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3496 /* initialize prevgre */
3500 /* search external hash chain for the entry */
3503 if (gre->o == LLNI_DIRECT(o)) {
3504 /* global object found, decrement the reference count */
3508 /* if reference count is 0, remove the entry */
3510 if (gre->refs == 0) {
3511 /* special handling if it's the first in the chain */
3513 if (prevgre == NULL)
3514 hashtable_global_ref->ptr[slot] = gre->hashlink;
3516 prevgre->hashlink = gre->hashlink;
3518 #if defined(ENABLE_GC_CACAO)
3519 /* unregister global ref with the GC */
3521 gc_reference_unregister(&(gre->o));
3529 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3534 prevgre = gre; /* save current pointer for removal */
3535 gre = gre->hashlink; /* next element in external chain */
3538 log_println("jni_DeleteGlobalRef: Global reference not found.");
3542 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3546 /* ExceptionCheck **************************************************************
3548 Returns JNI_TRUE when there is a pending exception; otherwise,
3551 *******************************************************************************/
3553 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3557 STATISTICS(jniinvokation());
3559 o = exceptions_get_exception();
3561 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3565 /* New JNI 1.4 functions ******************************************************/
3567 /* NewDirectByteBuffer *********************************************************
3569 Allocates and returns a direct java.nio.ByteBuffer referring to the
3570 block of memory starting at the memory address address and
3571 extending capacity bytes.
3573 *******************************************************************************/
3575 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3577 #if defined(ENABLE_JAVASE)
3578 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3579 java_handle_t *nbuf;
3581 # if SIZEOF_VOID_P == 8
3582 gnu_classpath_Pointer64 *paddress;
3584 gnu_classpath_Pointer32 *paddress;
3587 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3589 /* alocate a gnu.classpath.Pointer{32,64} object */
3591 # if SIZEOF_VOID_P == 8
3592 if (!(paddress = (gnu_classpath_Pointer64 *)
3593 builtin_new(class_gnu_classpath_Pointer64)))
3595 if (!(paddress = (gnu_classpath_Pointer32 *)
3596 builtin_new(class_gnu_classpath_Pointer32)))
3600 /* fill gnu.classpath.Pointer{32,64} with address */
3602 LLNI_field_set_val(paddress, data, (ptrint) address);
3604 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3606 nbuf = (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3607 (jmethodID) dbbirw_init, NULL, paddress,
3608 (jint) capacity, (jint) capacity, (jint) 0);
3610 /* add local reference and return the value */
3612 TRACEJNICALLSEXIT(("->%p", nbuf));
3614 return jni_NewLocalRef(env, (jobject) nbuf);
3616 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3622 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3624 /* Be paranoid about address sign-extension. */
3626 addr = (int64_t) ((uintptr_t) address);
3627 cap = (int32_t) capacity;
3629 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3630 (jmethodID) dbb_init, addr, cap);
3632 /* Add local reference and return the value. */
3634 TRACEJNICALLSEXIT(("->%p", o));
3636 return jni_NewLocalRef(env, o);
3639 # error unknown classpath configuration
3643 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3645 /* keep compiler happy */
3652 /* GetDirectBufferAddress ******************************************************
3654 Fetches and returns the starting address of the memory region
3655 referenced by the given direct java.nio.Buffer.
3657 *******************************************************************************/
3659 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3661 #if defined(ENABLE_JAVASE)
3664 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3666 java_nio_DirectByteBufferImpl *nbuf;
3667 gnu_classpath_Pointer *po;
3668 # if SIZEOF_VOID_P == 8
3669 gnu_classpath_Pointer64 *paddress;
3672 gnu_classpath_Pointer32 *paddress;
3677 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3679 /* Prevent compiler warning. */
3681 h = (java_handle_t *) buf;
3683 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3686 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3688 LLNI_field_get_ref(nbuf, address, po);
3690 # if SIZEOF_VOID_P == 8
3691 paddress = (gnu_classpath_Pointer64 *) po;
3693 paddress = (gnu_classpath_Pointer32 *) po;
3696 if (paddress == NULL)
3699 LLNI_field_get_val(paddress, data, address);
3701 p = (void *) (intptr_t) address;
3705 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3711 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3713 /* Prevent compiler warning. */
3715 h = (java_handle_t *) buf;
3717 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3720 o = (java_nio_Buffer *) buf;
3722 LLNI_field_get_val(o, address, address);
3724 p = (void *) (intptr_t) address;
3729 # error unknown classpath configuration
3734 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3736 /* keep compiler happy */
3744 /* GetDirectBufferCapacity *****************************************************
3746 Fetches and returns the capacity in bytes of the memory region
3747 referenced by the given direct java.nio.Buffer.
3749 *******************************************************************************/
3751 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3753 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3755 java_nio_Buffer *nbuf;
3758 STATISTICS(jniinvokation());
3760 o = (java_handle_t *) buf;
3762 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3765 nbuf = (java_nio_Buffer *) o;
3767 LLNI_field_get_val(nbuf, cap, capacity);
3771 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3773 /* keep compiler happy */
3780 /* GetObjectRefType ************************************************************
3782 Returns the type of the object referred to by the obj argument. The
3783 argument obj can either be a local, global or weak global
3786 *******************************************************************************/
3788 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3790 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3792 return (jobjectRefType) NULL;
3796 /* DestroyJavaVM ***************************************************************
3798 Unloads a Java VM and reclaims its resources. Only the main thread
3799 can unload the VM. The system waits until the main thread is only
3800 remaining user thread before it destroys the VM.
3802 *******************************************************************************/
3804 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3808 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3810 if (vm->is_created() == false)
3813 status = vm_destroy(javavm);
3819 /* AttachCurrentThread *********************************************************
3821 Attaches the current thread to a Java VM. Returns a JNI interface
3822 pointer in the JNIEnv argument.
3824 Trying to attach a thread that is already attached is a no-op.
3826 A native thread cannot be attached simultaneously to two Java VMs.
3828 When a thread is attached to the VM, the context class loader is
3829 the bootstrap loader.
3831 *******************************************************************************/
3833 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3835 #if defined(ENABLE_THREADS)
3836 JavaVMAttachArgs *vm_aargs;
3839 /* If the current thread has already been attached, this operation
3842 result = thread_current_is_attached();
3844 if (result == true) {
3845 *p_env = vm->get_jnienv();
3849 vm_aargs = (JavaVMAttachArgs *) thr_args;
3851 if (vm_aargs != NULL) {
3852 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3853 (vm_aargs->version != JNI_VERSION_1_4))
3854 return JNI_EVERSION;
3857 if (!thread_attach_current_external_thread(vm_aargs, false))
3860 if (!localref_table_init())
3864 *p_env = vm->get_jnienv();
3870 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3874 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3876 if (vm->is_created() == false)
3879 result = jni_attach_current_thread(p_env, thr_args, false);
3885 /* DetachCurrentThread *********************************************************
3887 Detaches the current thread from a Java VM. All Java monitors held
3888 by this thread are released. All Java threads waiting for this
3889 thread to die are notified.
3891 In JDK 1.1, the main thread cannot be detached from the VM. It must
3892 call DestroyJavaVM to unload the entire VM.
3894 In the JDK, the main thread can be detached from the VM.
3896 The main thread, which is the thread that created the Java VM,
3897 cannot be detached from the VM. Instead, the main thread must call
3898 JNI_DestroyJavaVM() to unload the entire VM.
3900 *******************************************************************************/
3902 jint jni_DetachCurrentThread(JavaVM *vm)
3904 #if defined(ENABLE_THREADS)
3907 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3909 /* If the current thread has already been detached, this operation
3912 result = thread_current_is_attached();
3914 if (result == false)
3917 /* We need to pop all frames before we can destroy the table. */
3919 localref_frame_pop_all();
3921 if (!localref_table_destroy())
3924 if (!thread_detach_current_external_thread())
3932 /* GetEnv **********************************************************************
3934 If the current thread is not attached to the VM, sets *env to NULL,
3935 and returns JNI_EDETACHED. If the specified version is not
3936 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3937 sets *env to the appropriate interface, and returns JNI_OK.
3939 *******************************************************************************/
3941 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3943 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3945 if (vm->is_created() == false) {
3947 return JNI_EDETACHED;
3950 #if defined(ENABLE_THREADS)
3951 if (thread_get_current() == NULL) {
3954 return JNI_EDETACHED;
3958 /* Check the JNI version. */
3960 if (jni_version_check(version) == true) {
3961 *env = vm->get_jnienv();
3965 #if defined(ENABLE_JVMTI)
3966 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3967 == JVMTI_VERSION_INTERFACE_JVMTI) {
3969 *env = (void *) jvmti_new_environment();
3978 return JNI_EVERSION;
3982 /* AttachCurrentThreadAsDaemon *************************************************
3984 Same semantics as AttachCurrentThread, but the newly-created
3985 java.lang.Thread instance is a daemon.
3987 If the thread has already been attached via either
3988 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3989 simply sets the value pointed to by penv to the JNIEnv of the
3990 current thread. In this case neither AttachCurrentThread nor this
3991 routine have any effect on the daemon status of the thread.
3993 *******************************************************************************/
3995 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3999 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
4001 if (vm->is_created() == false)
4004 result = jni_attach_current_thread(penv, args, true);
4010 /* JNI invocation table *******************************************************/
4012 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4017 _Jv_JNI_DestroyJavaVM,
4018 jni_AttachCurrentThread,
4019 jni_DetachCurrentThread,
4021 jni_AttachCurrentThreadAsDaemon
4025 /* JNI function table *********************************************************/
4027 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4034 _Jv_JNI_DefineClass,
4036 jni_FromReflectedMethod,
4037 jni_FromReflectedField,
4038 _Jv_JNI_ToReflectedMethod,
4039 _Jv_JNI_GetSuperclass,
4040 _Jv_JNI_IsAssignableFrom,
4041 _Jv_JNI_ToReflectedField,
4045 _Jv_JNI_ExceptionOccurred,
4046 jni_ExceptionDescribe,
4053 jni_DeleteGlobalRef,
4055 _Jv_JNI_IsSameObject,
4057 jni_EnsureLocalCapacity,
4059 _Jv_JNI_AllocObject,
4064 _Jv_JNI_GetObjectClass,
4065 _Jv_JNI_IsInstanceOf,
4067 _Jv_JNI_GetMethodID,
4069 _Jv_JNI_CallObjectMethod,
4070 _Jv_JNI_CallObjectMethodV,
4071 _Jv_JNI_CallObjectMethodA,
4072 _Jv_JNI_CallBooleanMethod,
4073 _Jv_JNI_CallBooleanMethodV,
4074 _Jv_JNI_CallBooleanMethodA,
4075 _Jv_JNI_CallByteMethod,
4076 _Jv_JNI_CallByteMethodV,
4077 _Jv_JNI_CallByteMethodA,
4078 _Jv_JNI_CallCharMethod,
4079 _Jv_JNI_CallCharMethodV,
4080 _Jv_JNI_CallCharMethodA,
4081 _Jv_JNI_CallShortMethod,
4082 _Jv_JNI_CallShortMethodV,
4083 _Jv_JNI_CallShortMethodA,
4084 _Jv_JNI_CallIntMethod,
4085 _Jv_JNI_CallIntMethodV,
4086 _Jv_JNI_CallIntMethodA,
4087 _Jv_JNI_CallLongMethod,
4088 _Jv_JNI_CallLongMethodV,
4089 _Jv_JNI_CallLongMethodA,
4090 _Jv_JNI_CallFloatMethod,
4091 _Jv_JNI_CallFloatMethodV,
4092 _Jv_JNI_CallFloatMethodA,
4093 _Jv_JNI_CallDoubleMethod,
4094 _Jv_JNI_CallDoubleMethodV,
4095 _Jv_JNI_CallDoubleMethodA,
4096 _Jv_JNI_CallVoidMethod,
4097 _Jv_JNI_CallVoidMethodV,
4098 _Jv_JNI_CallVoidMethodA,
4100 _Jv_JNI_CallNonvirtualObjectMethod,
4101 _Jv_JNI_CallNonvirtualObjectMethodV,
4102 _Jv_JNI_CallNonvirtualObjectMethodA,
4103 _Jv_JNI_CallNonvirtualBooleanMethod,
4104 _Jv_JNI_CallNonvirtualBooleanMethodV,
4105 _Jv_JNI_CallNonvirtualBooleanMethodA,
4106 _Jv_JNI_CallNonvirtualByteMethod,
4107 _Jv_JNI_CallNonvirtualByteMethodV,
4108 _Jv_JNI_CallNonvirtualByteMethodA,
4109 _Jv_JNI_CallNonvirtualCharMethod,
4110 _Jv_JNI_CallNonvirtualCharMethodV,
4111 _Jv_JNI_CallNonvirtualCharMethodA,
4112 _Jv_JNI_CallNonvirtualShortMethod,
4113 _Jv_JNI_CallNonvirtualShortMethodV,
4114 _Jv_JNI_CallNonvirtualShortMethodA,
4115 _Jv_JNI_CallNonvirtualIntMethod,
4116 _Jv_JNI_CallNonvirtualIntMethodV,
4117 _Jv_JNI_CallNonvirtualIntMethodA,
4118 _Jv_JNI_CallNonvirtualLongMethod,
4119 _Jv_JNI_CallNonvirtualLongMethodV,
4120 _Jv_JNI_CallNonvirtualLongMethodA,
4121 _Jv_JNI_CallNonvirtualFloatMethod,
4122 _Jv_JNI_CallNonvirtualFloatMethodV,
4123 _Jv_JNI_CallNonvirtualFloatMethodA,
4124 _Jv_JNI_CallNonvirtualDoubleMethod,
4125 _Jv_JNI_CallNonvirtualDoubleMethodV,
4126 _Jv_JNI_CallNonvirtualDoubleMethodA,
4127 _Jv_JNI_CallNonvirtualVoidMethod,
4128 _Jv_JNI_CallNonvirtualVoidMethodV,
4129 _Jv_JNI_CallNonvirtualVoidMethodA,
4133 _Jv_JNI_GetObjectField,
4134 _Jv_JNI_GetBooleanField,
4135 _Jv_JNI_GetByteField,
4136 _Jv_JNI_GetCharField,
4137 _Jv_JNI_GetShortField,
4138 _Jv_JNI_GetIntField,
4139 _Jv_JNI_GetLongField,
4140 _Jv_JNI_GetFloatField,
4141 _Jv_JNI_GetDoubleField,
4142 _Jv_JNI_SetObjectField,
4143 _Jv_JNI_SetBooleanField,
4144 _Jv_JNI_SetByteField,
4145 _Jv_JNI_SetCharField,
4146 _Jv_JNI_SetShortField,
4147 _Jv_JNI_SetIntField,
4148 _Jv_JNI_SetLongField,
4149 _Jv_JNI_SetFloatField,
4150 _Jv_JNI_SetDoubleField,
4152 _Jv_JNI_GetStaticMethodID,
4154 _Jv_JNI_CallStaticObjectMethod,
4155 _Jv_JNI_CallStaticObjectMethodV,
4156 _Jv_JNI_CallStaticObjectMethodA,
4157 _Jv_JNI_CallStaticBooleanMethod,
4158 _Jv_JNI_CallStaticBooleanMethodV,
4159 _Jv_JNI_CallStaticBooleanMethodA,
4160 _Jv_JNI_CallStaticByteMethod,
4161 _Jv_JNI_CallStaticByteMethodV,
4162 _Jv_JNI_CallStaticByteMethodA,
4163 _Jv_JNI_CallStaticCharMethod,
4164 _Jv_JNI_CallStaticCharMethodV,
4165 _Jv_JNI_CallStaticCharMethodA,
4166 _Jv_JNI_CallStaticShortMethod,
4167 _Jv_JNI_CallStaticShortMethodV,
4168 _Jv_JNI_CallStaticShortMethodA,
4169 _Jv_JNI_CallStaticIntMethod,
4170 _Jv_JNI_CallStaticIntMethodV,
4171 _Jv_JNI_CallStaticIntMethodA,
4172 _Jv_JNI_CallStaticLongMethod,
4173 _Jv_JNI_CallStaticLongMethodV,
4174 _Jv_JNI_CallStaticLongMethodA,
4175 _Jv_JNI_CallStaticFloatMethod,
4176 _Jv_JNI_CallStaticFloatMethodV,
4177 _Jv_JNI_CallStaticFloatMethodA,
4178 _Jv_JNI_CallStaticDoubleMethod,
4179 _Jv_JNI_CallStaticDoubleMethodV,
4180 _Jv_JNI_CallStaticDoubleMethodA,
4181 _Jv_JNI_CallStaticVoidMethod,
4182 _Jv_JNI_CallStaticVoidMethodV,
4183 _Jv_JNI_CallStaticVoidMethodA,
4185 _Jv_JNI_GetStaticFieldID,
4187 _Jv_JNI_GetStaticObjectField,
4188 _Jv_JNI_GetStaticBooleanField,
4189 _Jv_JNI_GetStaticByteField,
4190 _Jv_JNI_GetStaticCharField,
4191 _Jv_JNI_GetStaticShortField,
4192 _Jv_JNI_GetStaticIntField,
4193 _Jv_JNI_GetStaticLongField,
4194 _Jv_JNI_GetStaticFloatField,
4195 _Jv_JNI_GetStaticDoubleField,
4196 _Jv_JNI_SetStaticObjectField,
4197 _Jv_JNI_SetStaticBooleanField,
4198 _Jv_JNI_SetStaticByteField,
4199 _Jv_JNI_SetStaticCharField,
4200 _Jv_JNI_SetStaticShortField,
4201 _Jv_JNI_SetStaticIntField,
4202 _Jv_JNI_SetStaticLongField,
4203 _Jv_JNI_SetStaticFloatField,
4204 _Jv_JNI_SetStaticDoubleField,
4207 _Jv_JNI_GetStringLength,
4209 _Jv_JNI_ReleaseStringChars,
4211 _Jv_JNI_NewStringUTF,
4212 _Jv_JNI_GetStringUTFLength,
4213 _Jv_JNI_GetStringUTFChars,
4214 _Jv_JNI_ReleaseStringUTFChars,
4216 _Jv_JNI_GetArrayLength,
4218 _Jv_JNI_NewObjectArray,
4219 _Jv_JNI_GetObjectArrayElement,
4220 _Jv_JNI_SetObjectArrayElement,
4222 _Jv_JNI_NewBooleanArray,
4223 _Jv_JNI_NewByteArray,
4224 _Jv_JNI_NewCharArray,
4225 _Jv_JNI_NewShortArray,
4226 _Jv_JNI_NewIntArray,
4227 _Jv_JNI_NewLongArray,
4228 _Jv_JNI_NewFloatArray,
4229 _Jv_JNI_NewDoubleArray,
4231 _Jv_JNI_GetBooleanArrayElements,
4232 _Jv_JNI_GetByteArrayElements,
4233 _Jv_JNI_GetCharArrayElements,
4234 _Jv_JNI_GetShortArrayElements,
4235 _Jv_JNI_GetIntArrayElements,
4236 _Jv_JNI_GetLongArrayElements,
4237 _Jv_JNI_GetFloatArrayElements,
4238 _Jv_JNI_GetDoubleArrayElements,
4240 _Jv_JNI_ReleaseBooleanArrayElements,
4241 _Jv_JNI_ReleaseByteArrayElements,
4242 _Jv_JNI_ReleaseCharArrayElements,
4243 _Jv_JNI_ReleaseShortArrayElements,
4244 _Jv_JNI_ReleaseIntArrayElements,
4245 _Jv_JNI_ReleaseLongArrayElements,
4246 _Jv_JNI_ReleaseFloatArrayElements,
4247 _Jv_JNI_ReleaseDoubleArrayElements,
4249 _Jv_JNI_GetBooleanArrayRegion,
4250 _Jv_JNI_GetByteArrayRegion,
4251 _Jv_JNI_GetCharArrayRegion,
4252 _Jv_JNI_GetShortArrayRegion,
4253 _Jv_JNI_GetIntArrayRegion,
4254 _Jv_JNI_GetLongArrayRegion,
4255 _Jv_JNI_GetFloatArrayRegion,
4256 _Jv_JNI_GetDoubleArrayRegion,
4257 _Jv_JNI_SetBooleanArrayRegion,
4258 _Jv_JNI_SetByteArrayRegion,
4259 _Jv_JNI_SetCharArrayRegion,
4260 _Jv_JNI_SetShortArrayRegion,
4261 _Jv_JNI_SetIntArrayRegion,
4262 _Jv_JNI_SetLongArrayRegion,
4263 _Jv_JNI_SetFloatArrayRegion,
4264 _Jv_JNI_SetDoubleArrayRegion,
4266 _Jv_JNI_RegisterNatives,
4267 _Jv_JNI_UnregisterNatives,
4269 _Jv_JNI_MonitorEnter,
4270 _Jv_JNI_MonitorExit,
4274 /* New JNI 1.2 functions. */
4276 _Jv_JNI_GetStringRegion,
4277 _Jv_JNI_GetStringUTFRegion,
4279 jni_GetPrimitiveArrayCritical,
4280 jni_ReleasePrimitiveArrayCritical,
4282 _Jv_JNI_GetStringCritical,
4283 _Jv_JNI_ReleaseStringCritical,
4285 _Jv_JNI_NewWeakGlobalRef,
4286 _Jv_JNI_DeleteWeakGlobalRef,
4288 _Jv_JNI_ExceptionCheck,
4290 /* New JNI 1.4 functions. */
4292 jni_NewDirectByteBuffer,
4293 _Jv_JNI_GetDirectBufferAddress,
4294 _Jv_JNI_GetDirectBufferCapacity,
4296 /* New JNI 1.6 functions. */
4298 jni_GetObjectRefType
4302 /* Invocation API Functions ***************************************************/
4304 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4306 Returns a default configuration for the Java VM.
4308 *******************************************************************************/
4310 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4312 JavaVMInitArgs *_vm_args;
4314 _vm_args = (JavaVMInitArgs *) vm_args;
4316 /* GNU classpath currently supports JNI 1.2 */
4318 switch (_vm_args->version) {
4319 case JNI_VERSION_1_1:
4320 _vm_args->version = JNI_VERSION_1_1;
4323 case JNI_VERSION_1_2:
4324 case JNI_VERSION_1_4:
4325 _vm_args->ignoreUnrecognized = JNI_FALSE;
4326 _vm_args->options = NULL;
4327 _vm_args->nOptions = 0;
4338 /* JNI_GetCreatedJavaVMs *******************************************************
4340 Returns all Java VMs that have been created. Pointers to VMs are written in
4341 the buffer vmBuf in the order they are created. At most bufLen number of
4342 entries will be written. The total number of created VMs is returned in
4345 *******************************************************************************/
4347 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4349 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4354 // We currently only support 1 VM running.
4356 vmBuf[0] = vm->get_javavm();
4363 /* JNI_CreateJavaVM ************************************************************
4365 Loads and initializes a Java VM. The current thread becomes the main thread.
4366 Sets the env argument to the JNI interface pointer of the main thread.
4368 *******************************************************************************/
4370 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4372 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4374 /* actually create the JVM */
4376 if (!VM_create(p_vm, p_env, vm_args))
4386 * These are local overrides for various environment variables in Emacs.
4387 * Please do not remove this and leave it at the end of the file, where
4388 * Emacs will automagically detect them.
4389 * ---------------------------------------------------------------------
4392 * indent-tabs-mode: t
4396 * vim:noexpandtab:sw=4:ts=4: