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 /******************** convertes javastring to u2-array ****************************/
2661 u2 *javastring_tou2(jstring so)
2663 java_lang_String *s;
2664 java_handle_chararray_t *a;
2670 STATISTICS(jniinvokation());
2672 s = (java_lang_String *) so;
2677 LLNI_field_get_ref(s, value, a);
2682 LLNI_field_get_val(s, count, count);
2683 LLNI_field_get_val(s, offset, offset);
2685 /* allocate memory */
2687 stringbuffer = MNEW(u2, count + 1);
2691 for (i = 0; i < count; i++)
2692 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2694 /* terminate string */
2696 stringbuffer[i] = '\0';
2698 return stringbuffer;
2702 /* GetStringChars **************************************************************
2704 Returns a pointer to the array of Unicode characters of the
2705 string. This pointer is valid until ReleaseStringChars() is called.
2707 *******************************************************************************/
2709 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2713 STATISTICS(jniinvokation());
2715 jc = javastring_tou2(str);
2727 return emptyStringJ;
2731 /* ReleaseStringChars **********************************************************
2733 Informs the VM that the native code no longer needs access to
2734 chars. The chars argument is a pointer obtained from string using
2737 *******************************************************************************/
2739 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2741 java_lang_String *s;
2743 STATISTICS(jniinvokation());
2745 if (chars == emptyStringJ)
2748 s = (java_lang_String *) str;
2750 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2754 /* NewStringUTF ****************************************************************
2756 Constructs a new java.lang.String object from an array of UTF-8
2759 *******************************************************************************/
2761 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2763 java_lang_String *s;
2765 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2767 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2769 return (jstring) jni_NewLocalRef(env, (jobject) s);
2773 /****************** returns the utf8 length in bytes of a string *******************/
2775 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2777 java_lang_String *s;
2780 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2782 s = (java_lang_String *) string;
2784 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2790 /* GetStringUTFChars ***********************************************************
2792 Returns a pointer to an array of UTF-8 characters of the
2793 string. This array is valid until it is released by
2794 ReleaseStringUTFChars().
2796 *******************************************************************************/
2798 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2803 STATISTICS(jniinvokation());
2811 u = javastring_toutf((java_handle_t *) string, false);
2820 /* ReleaseStringUTFChars *******************************************************
2822 Informs the VM that the native code no longer needs access to
2823 utf. The utf argument is a pointer derived from string using
2824 GetStringUTFChars().
2826 *******************************************************************************/
2828 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2830 STATISTICS(jniinvokation());
2832 /* XXX we don't release utf chars right now, perhaps that should be done
2833 later. Since there is always one reference the garbage collector will
2838 /* Array Operations ***********************************************************/
2840 /* GetArrayLength **************************************************************
2842 Returns the number of elements in the array.
2844 *******************************************************************************/
2846 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2851 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2853 a = (java_handle_t *) array;
2855 size = LLNI_array_size(a);
2861 /* NewObjectArray **************************************************************
2863 Constructs a new array holding objects in class elementClass. All
2864 elements are initially set to initialElement.
2866 *******************************************************************************/
2868 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2869 jclass elementClass, jobject initialElement)
2873 java_handle_objectarray_t *oa;
2876 STATISTICS(jniinvokation());
2878 c = LLNI_classinfo_unwrap(elementClass);
2879 o = (java_handle_t *) initialElement;
2882 exceptions_throw_negativearraysizeexception();
2886 oa = builtin_anewarray(length, c);
2891 /* set all elements to initialElement */
2893 for (i = 0; i < length; i++)
2894 array_objectarray_element_set(oa, i, o);
2896 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2900 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2903 java_handle_objectarray_t *oa;
2906 STATISTICS(jniinvokation());
2908 oa = (java_handle_objectarray_t *) array;
2910 if (index >= LLNI_array_size(oa)) {
2911 exceptions_throw_arrayindexoutofboundsexception();
2915 o = array_objectarray_element_get(oa, index);
2917 return jni_NewLocalRef(env, (jobject) o);
2921 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2922 jsize index, jobject val)
2924 java_handle_objectarray_t *oa;
2927 STATISTICS(jniinvokation());
2929 oa = (java_handle_objectarray_t *) array;
2930 o = (java_handle_t *) val;
2932 if (index >= LLNI_array_size(oa)) {
2933 exceptions_throw_arrayindexoutofboundsexception();
2937 /* check if the class of value is a subclass of the element class
2940 if (!builtin_canstore(oa, o))
2943 array_objectarray_element_set(oa, index, o);
2947 #define JNI_NEW_ARRAY(name, type, intern) \
2948 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2950 java_handle_##intern##array_t *a; \
2952 STATISTICS(jniinvokation()); \
2955 exceptions_throw_negativearraysizeexception(); \
2959 a = builtin_newarray_##intern(len); \
2961 return (type) jni_NewLocalRef(env, (jobject) a); \
2964 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2965 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2966 JNI_NEW_ARRAY(Char, jcharArray, char)
2967 JNI_NEW_ARRAY(Short, jshortArray, short)
2968 JNI_NEW_ARRAY(Int, jintArray, int)
2969 JNI_NEW_ARRAY(Long, jlongArray, long)
2970 JNI_NEW_ARRAY(Float, jfloatArray, float)
2971 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2974 /* Get<PrimitiveType>ArrayElements *********************************************
2976 A family of functions that returns the body of the primitive array.
2978 *******************************************************************************/
2980 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2981 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2984 java_handle_##intern##array_t *a; \
2986 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2988 a = (java_handle_##intern##array_t *) array; \
2991 *isCopy = JNI_FALSE; \
2993 return (type *) LLNI_array_data(a); \
2996 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2997 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2998 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2999 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3000 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3001 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3002 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3003 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3006 /* Release<PrimitiveType>ArrayElements *****************************************
3008 A family of functions that informs the VM that the native code no
3009 longer needs access to elems. The elems argument is a pointer
3010 derived from array using the corresponding
3011 Get<PrimitiveType>ArrayElements() function. If necessary, this
3012 function copies back all changes made to elems to the original
3015 *******************************************************************************/
3017 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3018 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3019 type *elems, jint mode) \
3021 java_handle_##intern##array_t *a; \
3023 STATISTICS(jniinvokation()); \
3025 a = (java_handle_##intern##array_t *) array; \
3027 if (elems != (type *) LLNI_array_data(a)) { \
3030 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3033 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3034 /* XXX TWISTI how should it be freed? */ \
3037 /* XXX TWISTI how should it be freed? */ \
3043 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3044 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3045 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3046 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3047 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3048 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3049 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3050 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3053 /* Get<PrimitiveType>ArrayRegion **********************************************
3055 A family of functions that copies a region of a primitive array
3058 *******************************************************************************/
3060 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3061 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3062 jsize start, jsize len, type *buf) \
3064 java_handle_##intern##array_t *a; \
3066 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3068 a = (java_handle_##intern##array_t *) array; \
3070 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3071 exceptions_throw_arrayindexoutofboundsexception(); \
3073 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3076 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3077 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3078 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3079 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3080 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3081 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3082 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3083 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3086 /* Set<PrimitiveType>ArrayRegion **********************************************
3088 A family of functions that copies back a region of a primitive
3089 array from a buffer.
3091 *******************************************************************************/
3093 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3094 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3095 jsize start, jsize len, const type *buf) \
3097 java_handle_##intern##array_t *a; \
3099 STATISTICS(jniinvokation()); \
3101 a = (java_handle_##intern##array_t *) array; \
3103 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3104 exceptions_throw_arrayindexoutofboundsexception(); \
3106 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3109 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3110 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3111 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3112 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3113 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3114 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3115 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3116 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3119 /* Registering Native Methods *************************************************/
3121 /* RegisterNatives *************************************************************
3123 Registers native methods with the class specified by the clazz
3124 argument. The methods parameter specifies an array of
3125 JNINativeMethod structures that contain the names, signatures, and
3126 function pointers of the native methods. The nMethods parameter
3127 specifies the number of native methods in the array.
3129 *******************************************************************************/
3131 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3132 const JNINativeMethod *methods, jint nMethods)
3136 STATISTICS(jniinvokation());
3138 c = LLNI_classinfo_unwrap(clazz);
3140 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3141 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3144 native_method_register(c->name, methods, nMethods);
3150 /* UnregisterNatives ***********************************************************
3152 Unregisters native methods of a class. The class goes back to the
3153 state before it was linked or registered with its native method
3156 This function should not be used in normal native code. Instead, it
3157 provides special programs a way to reload and relink native
3160 *******************************************************************************/
3162 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3164 STATISTICS(jniinvokation());
3166 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3168 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3174 /* Monitor Operations *********************************************************/
3176 /* MonitorEnter ****************************************************************
3178 Enters the monitor associated with the underlying Java object
3181 *******************************************************************************/
3183 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3185 STATISTICS(jniinvokation());
3188 exceptions_throw_nullpointerexception();
3192 LOCK_MONITOR_ENTER(obj);
3198 /* MonitorExit *****************************************************************
3200 The current thread must be the owner of the monitor associated with
3201 the underlying Java object referred to by obj. The thread
3202 decrements the counter indicating the number of times it has
3203 entered this monitor. If the value of the counter becomes zero, the
3204 current thread releases the monitor.
3206 *******************************************************************************/
3208 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3210 STATISTICS(jniinvokation());
3213 exceptions_throw_nullpointerexception();
3217 LOCK_MONITOR_EXIT(obj);
3223 /* JavaVM Interface ***********************************************************/
3225 /* GetJavaVM *******************************************************************
3227 Returns the Java VM interface (used in the Invocation API)
3228 associated with the current thread. The result is placed at the
3229 location pointed to by the second argument, vm.
3231 *******************************************************************************/
3233 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3235 STATISTICS(jniinvokation());
3237 *javavm = vm->get_javavm();
3243 /* GetStringRegion *************************************************************
3245 Copies len number of Unicode characters beginning at offset start
3246 to the given buffer buf.
3248 Throws StringIndexOutOfBoundsException on index overflow.
3250 *******************************************************************************/
3252 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3255 java_lang_String *s;
3256 java_handle_chararray_t *ca;
3258 STATISTICS(jniinvokation());
3260 s = (java_lang_String *) str;
3261 LLNI_field_get_ref(s, value, ca);
3263 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3264 (start + len > LLNI_field_direct(s, count))) {
3265 exceptions_throw_stringindexoutofboundsexception();
3269 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3273 /* GetStringUTFRegion **********************************************************
3275 Translates len number of Unicode characters beginning at offset
3276 start into UTF-8 format and place the result in the given buffer
3279 Throws StringIndexOutOfBoundsException on index overflow.
3281 *******************************************************************************/
3283 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3284 jsize len, char *buf)
3286 java_lang_String *s;
3287 java_handle_chararray_t *ca;
3292 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3294 s = (java_lang_String *) str;
3295 LLNI_field_get_ref(s, value, ca);
3296 LLNI_field_get_val(s, count, count);
3297 LLNI_field_get_val(s, offset, offset);
3299 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3300 exceptions_throw_stringindexoutofboundsexception();
3304 for (i = 0; i < len; i++)
3305 buf[i] = LLNI_array_direct(ca, offset + start + i);
3311 /* GetPrimitiveArrayCritical ***************************************************
3313 Obtain a direct pointer to array elements.
3315 ATTENTION: Critical section keeps open when this function returns!
3316 See ReleasePrimitiveArrayCritical.
3318 *******************************************************************************/
3320 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3324 arraydescriptor* ad;
3327 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3329 if (isCopy != NULL) {
3330 *isCopy = JNI_FALSE;
3333 LLNI_CRITICAL_START;
3335 h = (java_handle_t*) array;
3336 a = (java_array_t*) LLNI_UNWRAP(h);
3337 ad = a->objheader.vftbl->arraydesc;
3343 data = (void*) (((intptr_t) a) + ad->dataoffset);
3349 /* ReleasePrimitiveArrayCritical ***********************************************
3351 No specific documentation.
3353 ATTENTION: This function closes the critical section opened in
3354 GetPrimitiveArrayCritical!
3356 *******************************************************************************/
3358 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3360 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3366 /* GetStringCritical ***********************************************************
3368 The semantics of these two functions are similar to the existing
3369 Get/ReleaseStringChars functions.
3371 *******************************************************************************/
3373 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3376 STATISTICS(jniinvokation());
3378 return _Jv_JNI_GetStringChars(env, string, isCopy);
3382 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3383 const jchar *cstring)
3385 STATISTICS(jniinvokation());
3387 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3391 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3393 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3399 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3401 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3405 /* NewGlobalRef ****************************************************************
3407 Creates a new global reference to the object referred to by the obj
3410 *******************************************************************************/
3412 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3414 hashtable_global_ref_entry *gre;
3415 u4 key; /* hashkey */
3416 u4 slot; /* slot in hashtable */
3419 TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3421 o = (java_handle_t *) obj;
3423 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3425 LLNI_CRITICAL_START;
3427 /* normally addresses are aligned to 4, 8 or 16 bytes */
3429 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3430 slot = key & (hashtable_global_ref->size - 1);
3431 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3433 /* search external hash chain for the entry */
3436 if (gre->o == LLNI_DIRECT(o)) {
3437 /* global object found, increment the reference */
3444 gre = gre->hashlink; /* next element in external chain */
3449 /* global ref not found, create a new one */
3452 gre = GCNEW_UNCOLLECTABLE(hashtable_global_ref_entry, 1);
3454 #if defined(ENABLE_GC_CACAO)
3455 /* register global ref with the GC */
3457 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3460 LLNI_CRITICAL_START;
3462 gre->o = LLNI_DIRECT(o);
3467 /* insert entry into hashtable */
3469 gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3471 hashtable_global_ref->ptr[slot] = gre;
3473 /* update number of hashtable-entries */
3475 hashtable_global_ref->entries++;
3478 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3480 #if defined(ENABLE_HANDLES)
3488 /* DeleteGlobalRef *************************************************************
3490 Deletes the global reference pointed to by globalRef.
3492 *******************************************************************************/
3494 void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3496 hashtable_global_ref_entry *gre;
3497 hashtable_global_ref_entry *prevgre;
3498 u4 key; /* hashkey */
3499 u4 slot; /* slot in hashtable */
3502 TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3504 o = (java_handle_t *) globalRef;
3506 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3508 LLNI_CRITICAL_START;
3510 /* normally addresses are aligned to 4, 8 or 16 bytes */
3512 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3513 slot = key & (hashtable_global_ref->size - 1);
3514 gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3516 /* initialize prevgre */
3520 /* search external hash chain for the entry */
3523 if (gre->o == LLNI_DIRECT(o)) {
3524 /* global object found, decrement the reference count */
3528 /* if reference count is 0, remove the entry */
3530 if (gre->refs == 0) {
3531 /* special handling if it's the first in the chain */
3533 if (prevgre == NULL)
3534 hashtable_global_ref->ptr[slot] = gre->hashlink;
3536 prevgre->hashlink = gre->hashlink;
3538 #if defined(ENABLE_GC_CACAO)
3539 /* unregister global ref with the GC */
3541 gc_reference_unregister(&(gre->o));
3549 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3554 prevgre = gre; /* save current pointer for removal */
3555 gre = gre->hashlink; /* next element in external chain */
3558 log_println("jni_DeleteGlobalRef: Global reference not found.");
3562 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3566 /* ExceptionCheck **************************************************************
3568 Returns JNI_TRUE when there is a pending exception; otherwise,
3571 *******************************************************************************/
3573 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3577 STATISTICS(jniinvokation());
3579 o = exceptions_get_exception();
3581 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3585 /* New JNI 1.4 functions ******************************************************/
3587 /* NewDirectByteBuffer *********************************************************
3589 Allocates and returns a direct java.nio.ByteBuffer referring to the
3590 block of memory starting at the memory address address and
3591 extending capacity bytes.
3593 *******************************************************************************/
3595 jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3597 #if defined(ENABLE_JAVASE)
3598 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3599 java_handle_t *nbuf;
3601 # if SIZEOF_VOID_P == 8
3602 gnu_classpath_Pointer64 *paddress;
3604 gnu_classpath_Pointer32 *paddress;
3607 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3609 /* alocate a gnu.classpath.Pointer{32,64} object */
3611 # if SIZEOF_VOID_P == 8
3612 if (!(paddress = (gnu_classpath_Pointer64 *)
3613 builtin_new(class_gnu_classpath_Pointer64)))
3615 if (!(paddress = (gnu_classpath_Pointer32 *)
3616 builtin_new(class_gnu_classpath_Pointer32)))
3620 /* fill gnu.classpath.Pointer{32,64} with address */
3622 LLNI_field_set_val(paddress, data, (ptrint) address);
3624 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3626 nbuf = (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3627 (jmethodID) dbbirw_init, NULL, paddress,
3628 (jint) capacity, (jint) capacity, (jint) 0);
3630 /* add local reference and return the value */
3632 TRACEJNICALLSEXIT(("->%p", nbuf));
3634 return jni_NewLocalRef(env, (jobject) nbuf);
3636 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3642 TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3644 /* Be paranoid about address sign-extension. */
3646 addr = (int64_t) ((uintptr_t) address);
3647 cap = (int32_t) capacity;
3649 o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3650 (jmethodID) dbb_init, addr, cap);
3652 /* Add local reference and return the value. */
3654 TRACEJNICALLSEXIT(("->%p", o));
3656 return jni_NewLocalRef(env, o);
3659 # error unknown classpath configuration
3663 vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3665 /* keep compiler happy */
3672 /* GetDirectBufferAddress ******************************************************
3674 Fetches and returns the starting address of the memory region
3675 referenced by the given direct java.nio.Buffer.
3677 *******************************************************************************/
3679 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3681 #if defined(ENABLE_JAVASE)
3684 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3686 java_nio_DirectByteBufferImpl *nbuf;
3687 gnu_classpath_Pointer *po;
3688 # if SIZEOF_VOID_P == 8
3689 gnu_classpath_Pointer64 *paddress;
3692 gnu_classpath_Pointer32 *paddress;
3697 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3699 /* Prevent compiler warning. */
3701 h = (java_handle_t *) buf;
3703 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3706 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3708 LLNI_field_get_ref(nbuf, address, po);
3710 # if SIZEOF_VOID_P == 8
3711 paddress = (gnu_classpath_Pointer64 *) po;
3713 paddress = (gnu_classpath_Pointer32 *) po;
3716 if (paddress == NULL)
3719 LLNI_field_get_val(paddress, data, address);
3721 p = (void *) (intptr_t) address;
3725 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3731 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3733 /* Prevent compiler warning. */
3735 h = (java_handle_t *) buf;
3737 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3740 o = (java_nio_Buffer *) buf;
3742 LLNI_field_get_val(o, address, address);
3744 p = (void *) (intptr_t) address;
3749 # error unknown classpath configuration
3754 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3756 /* keep compiler happy */
3764 /* GetDirectBufferCapacity *****************************************************
3766 Fetches and returns the capacity in bytes of the memory region
3767 referenced by the given direct java.nio.Buffer.
3769 *******************************************************************************/
3771 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3773 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3775 java_nio_Buffer *nbuf;
3778 STATISTICS(jniinvokation());
3780 o = (java_handle_t *) buf;
3782 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3785 nbuf = (java_nio_Buffer *) o;
3787 LLNI_field_get_val(nbuf, cap, capacity);
3791 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3793 /* keep compiler happy */
3800 /* GetObjectRefType ************************************************************
3802 Returns the type of the object referred to by the obj argument. The
3803 argument obj can either be a local, global or weak global
3806 *******************************************************************************/
3808 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3810 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3812 return (jobjectRefType) NULL;
3816 /* DestroyJavaVM ***************************************************************
3818 Unloads a Java VM and reclaims its resources. Only the main thread
3819 can unload the VM. The system waits until the main thread is only
3820 remaining user thread before it destroys the VM.
3822 *******************************************************************************/
3824 jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3828 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3830 if (vm->is_created() == false)
3833 status = vm_destroy(javavm);
3839 /* AttachCurrentThread *********************************************************
3841 Attaches the current thread to a Java VM. Returns a JNI interface
3842 pointer in the JNIEnv argument.
3844 Trying to attach a thread that is already attached is a no-op.
3846 A native thread cannot be attached simultaneously to two Java VMs.
3848 When a thread is attached to the VM, the context class loader is
3849 the bootstrap loader.
3851 *******************************************************************************/
3853 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3855 #if defined(ENABLE_THREADS)
3856 JavaVMAttachArgs *vm_aargs;
3859 /* If the current thread has already been attached, this operation
3862 result = thread_current_is_attached();
3864 if (result == true) {
3865 *p_env = vm->get_jnienv();
3869 vm_aargs = (JavaVMAttachArgs *) thr_args;
3871 if (vm_aargs != NULL) {
3872 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3873 (vm_aargs->version != JNI_VERSION_1_4))
3874 return JNI_EVERSION;
3877 if (!thread_attach_current_external_thread(vm_aargs, false))
3880 if (!localref_table_init())
3884 *p_env = vm->get_jnienv();
3890 jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3894 TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3896 if (vm->is_created() == false)
3899 result = jni_attach_current_thread(p_env, thr_args, false);
3905 /* DetachCurrentThread *********************************************************
3907 Detaches the current thread from a Java VM. All Java monitors held
3908 by this thread are released. All Java threads waiting for this
3909 thread to die are notified.
3911 In JDK 1.1, the main thread cannot be detached from the VM. It must
3912 call DestroyJavaVM to unload the entire VM.
3914 In the JDK, the main thread can be detached from the VM.
3916 The main thread, which is the thread that created the Java VM,
3917 cannot be detached from the VM. Instead, the main thread must call
3918 JNI_DestroyJavaVM() to unload the entire VM.
3920 *******************************************************************************/
3922 jint jni_DetachCurrentThread(JavaVM *vm)
3924 #if defined(ENABLE_THREADS)
3927 TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3929 /* If the current thread has already been detached, this operation
3932 result = thread_current_is_attached();
3934 if (result == false)
3937 /* We need to pop all frames before we can destroy the table. */
3939 localref_frame_pop_all();
3941 if (!localref_table_destroy())
3944 if (!thread_detach_current_external_thread())
3952 /* GetEnv **********************************************************************
3954 If the current thread is not attached to the VM, sets *env to NULL,
3955 and returns JNI_EDETACHED. If the specified version is not
3956 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3957 sets *env to the appropriate interface, and returns JNI_OK.
3959 *******************************************************************************/
3961 jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3963 TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3965 if (vm->is_created() == false) {
3967 return JNI_EDETACHED;
3970 #if defined(ENABLE_THREADS)
3971 if (thread_get_current() == NULL) {
3974 return JNI_EDETACHED;
3978 /* Check the JNI version. */
3980 if (jni_version_check(version) == true) {
3981 *env = vm->get_jnienv();
3985 #if defined(ENABLE_JVMTI)
3986 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3987 == JVMTI_VERSION_INTERFACE_JVMTI) {
3989 *env = (void *) jvmti_new_environment();
3998 return JNI_EVERSION;
4002 /* AttachCurrentThreadAsDaemon *************************************************
4004 Same semantics as AttachCurrentThread, but the newly-created
4005 java.lang.Thread instance is a daemon.
4007 If the thread has already been attached via either
4008 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
4009 simply sets the value pointed to by penv to the JNIEnv of the
4010 current thread. In this case neither AttachCurrentThread nor this
4011 routine have any effect on the daemon status of the thread.
4013 *******************************************************************************/
4015 jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
4019 TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
4021 if (vm->is_created() == false)
4024 result = jni_attach_current_thread(penv, args, true);
4030 /* JNI invocation table *******************************************************/
4032 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4037 _Jv_JNI_DestroyJavaVM,
4038 jni_AttachCurrentThread,
4039 jni_DetachCurrentThread,
4041 jni_AttachCurrentThreadAsDaemon
4045 /* JNI function table *********************************************************/
4047 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4054 _Jv_JNI_DefineClass,
4056 jni_FromReflectedMethod,
4057 jni_FromReflectedField,
4058 _Jv_JNI_ToReflectedMethod,
4059 _Jv_JNI_GetSuperclass,
4060 _Jv_JNI_IsAssignableFrom,
4061 _Jv_JNI_ToReflectedField,
4065 _Jv_JNI_ExceptionOccurred,
4066 jni_ExceptionDescribe,
4073 jni_DeleteGlobalRef,
4075 _Jv_JNI_IsSameObject,
4077 jni_EnsureLocalCapacity,
4079 _Jv_JNI_AllocObject,
4084 _Jv_JNI_GetObjectClass,
4085 _Jv_JNI_IsInstanceOf,
4087 _Jv_JNI_GetMethodID,
4089 _Jv_JNI_CallObjectMethod,
4090 _Jv_JNI_CallObjectMethodV,
4091 _Jv_JNI_CallObjectMethodA,
4092 _Jv_JNI_CallBooleanMethod,
4093 _Jv_JNI_CallBooleanMethodV,
4094 _Jv_JNI_CallBooleanMethodA,
4095 _Jv_JNI_CallByteMethod,
4096 _Jv_JNI_CallByteMethodV,
4097 _Jv_JNI_CallByteMethodA,
4098 _Jv_JNI_CallCharMethod,
4099 _Jv_JNI_CallCharMethodV,
4100 _Jv_JNI_CallCharMethodA,
4101 _Jv_JNI_CallShortMethod,
4102 _Jv_JNI_CallShortMethodV,
4103 _Jv_JNI_CallShortMethodA,
4104 _Jv_JNI_CallIntMethod,
4105 _Jv_JNI_CallIntMethodV,
4106 _Jv_JNI_CallIntMethodA,
4107 _Jv_JNI_CallLongMethod,
4108 _Jv_JNI_CallLongMethodV,
4109 _Jv_JNI_CallLongMethodA,
4110 _Jv_JNI_CallFloatMethod,
4111 _Jv_JNI_CallFloatMethodV,
4112 _Jv_JNI_CallFloatMethodA,
4113 _Jv_JNI_CallDoubleMethod,
4114 _Jv_JNI_CallDoubleMethodV,
4115 _Jv_JNI_CallDoubleMethodA,
4116 _Jv_JNI_CallVoidMethod,
4117 _Jv_JNI_CallVoidMethodV,
4118 _Jv_JNI_CallVoidMethodA,
4120 _Jv_JNI_CallNonvirtualObjectMethod,
4121 _Jv_JNI_CallNonvirtualObjectMethodV,
4122 _Jv_JNI_CallNonvirtualObjectMethodA,
4123 _Jv_JNI_CallNonvirtualBooleanMethod,
4124 _Jv_JNI_CallNonvirtualBooleanMethodV,
4125 _Jv_JNI_CallNonvirtualBooleanMethodA,
4126 _Jv_JNI_CallNonvirtualByteMethod,
4127 _Jv_JNI_CallNonvirtualByteMethodV,
4128 _Jv_JNI_CallNonvirtualByteMethodA,
4129 _Jv_JNI_CallNonvirtualCharMethod,
4130 _Jv_JNI_CallNonvirtualCharMethodV,
4131 _Jv_JNI_CallNonvirtualCharMethodA,
4132 _Jv_JNI_CallNonvirtualShortMethod,
4133 _Jv_JNI_CallNonvirtualShortMethodV,
4134 _Jv_JNI_CallNonvirtualShortMethodA,
4135 _Jv_JNI_CallNonvirtualIntMethod,
4136 _Jv_JNI_CallNonvirtualIntMethodV,
4137 _Jv_JNI_CallNonvirtualIntMethodA,
4138 _Jv_JNI_CallNonvirtualLongMethod,
4139 _Jv_JNI_CallNonvirtualLongMethodV,
4140 _Jv_JNI_CallNonvirtualLongMethodA,
4141 _Jv_JNI_CallNonvirtualFloatMethod,
4142 _Jv_JNI_CallNonvirtualFloatMethodV,
4143 _Jv_JNI_CallNonvirtualFloatMethodA,
4144 _Jv_JNI_CallNonvirtualDoubleMethod,
4145 _Jv_JNI_CallNonvirtualDoubleMethodV,
4146 _Jv_JNI_CallNonvirtualDoubleMethodA,
4147 _Jv_JNI_CallNonvirtualVoidMethod,
4148 _Jv_JNI_CallNonvirtualVoidMethodV,
4149 _Jv_JNI_CallNonvirtualVoidMethodA,
4153 _Jv_JNI_GetObjectField,
4154 _Jv_JNI_GetBooleanField,
4155 _Jv_JNI_GetByteField,
4156 _Jv_JNI_GetCharField,
4157 _Jv_JNI_GetShortField,
4158 _Jv_JNI_GetIntField,
4159 _Jv_JNI_GetLongField,
4160 _Jv_JNI_GetFloatField,
4161 _Jv_JNI_GetDoubleField,
4162 _Jv_JNI_SetObjectField,
4163 _Jv_JNI_SetBooleanField,
4164 _Jv_JNI_SetByteField,
4165 _Jv_JNI_SetCharField,
4166 _Jv_JNI_SetShortField,
4167 _Jv_JNI_SetIntField,
4168 _Jv_JNI_SetLongField,
4169 _Jv_JNI_SetFloatField,
4170 _Jv_JNI_SetDoubleField,
4172 _Jv_JNI_GetStaticMethodID,
4174 _Jv_JNI_CallStaticObjectMethod,
4175 _Jv_JNI_CallStaticObjectMethodV,
4176 _Jv_JNI_CallStaticObjectMethodA,
4177 _Jv_JNI_CallStaticBooleanMethod,
4178 _Jv_JNI_CallStaticBooleanMethodV,
4179 _Jv_JNI_CallStaticBooleanMethodA,
4180 _Jv_JNI_CallStaticByteMethod,
4181 _Jv_JNI_CallStaticByteMethodV,
4182 _Jv_JNI_CallStaticByteMethodA,
4183 _Jv_JNI_CallStaticCharMethod,
4184 _Jv_JNI_CallStaticCharMethodV,
4185 _Jv_JNI_CallStaticCharMethodA,
4186 _Jv_JNI_CallStaticShortMethod,
4187 _Jv_JNI_CallStaticShortMethodV,
4188 _Jv_JNI_CallStaticShortMethodA,
4189 _Jv_JNI_CallStaticIntMethod,
4190 _Jv_JNI_CallStaticIntMethodV,
4191 _Jv_JNI_CallStaticIntMethodA,
4192 _Jv_JNI_CallStaticLongMethod,
4193 _Jv_JNI_CallStaticLongMethodV,
4194 _Jv_JNI_CallStaticLongMethodA,
4195 _Jv_JNI_CallStaticFloatMethod,
4196 _Jv_JNI_CallStaticFloatMethodV,
4197 _Jv_JNI_CallStaticFloatMethodA,
4198 _Jv_JNI_CallStaticDoubleMethod,
4199 _Jv_JNI_CallStaticDoubleMethodV,
4200 _Jv_JNI_CallStaticDoubleMethodA,
4201 _Jv_JNI_CallStaticVoidMethod,
4202 _Jv_JNI_CallStaticVoidMethodV,
4203 _Jv_JNI_CallStaticVoidMethodA,
4205 _Jv_JNI_GetStaticFieldID,
4207 _Jv_JNI_GetStaticObjectField,
4208 _Jv_JNI_GetStaticBooleanField,
4209 _Jv_JNI_GetStaticByteField,
4210 _Jv_JNI_GetStaticCharField,
4211 _Jv_JNI_GetStaticShortField,
4212 _Jv_JNI_GetStaticIntField,
4213 _Jv_JNI_GetStaticLongField,
4214 _Jv_JNI_GetStaticFloatField,
4215 _Jv_JNI_GetStaticDoubleField,
4216 _Jv_JNI_SetStaticObjectField,
4217 _Jv_JNI_SetStaticBooleanField,
4218 _Jv_JNI_SetStaticByteField,
4219 _Jv_JNI_SetStaticCharField,
4220 _Jv_JNI_SetStaticShortField,
4221 _Jv_JNI_SetStaticIntField,
4222 _Jv_JNI_SetStaticLongField,
4223 _Jv_JNI_SetStaticFloatField,
4224 _Jv_JNI_SetStaticDoubleField,
4227 _Jv_JNI_GetStringLength,
4228 _Jv_JNI_GetStringChars,
4229 _Jv_JNI_ReleaseStringChars,
4231 _Jv_JNI_NewStringUTF,
4232 _Jv_JNI_GetStringUTFLength,
4233 _Jv_JNI_GetStringUTFChars,
4234 _Jv_JNI_ReleaseStringUTFChars,
4236 _Jv_JNI_GetArrayLength,
4238 _Jv_JNI_NewObjectArray,
4239 _Jv_JNI_GetObjectArrayElement,
4240 _Jv_JNI_SetObjectArrayElement,
4242 _Jv_JNI_NewBooleanArray,
4243 _Jv_JNI_NewByteArray,
4244 _Jv_JNI_NewCharArray,
4245 _Jv_JNI_NewShortArray,
4246 _Jv_JNI_NewIntArray,
4247 _Jv_JNI_NewLongArray,
4248 _Jv_JNI_NewFloatArray,
4249 _Jv_JNI_NewDoubleArray,
4251 _Jv_JNI_GetBooleanArrayElements,
4252 _Jv_JNI_GetByteArrayElements,
4253 _Jv_JNI_GetCharArrayElements,
4254 _Jv_JNI_GetShortArrayElements,
4255 _Jv_JNI_GetIntArrayElements,
4256 _Jv_JNI_GetLongArrayElements,
4257 _Jv_JNI_GetFloatArrayElements,
4258 _Jv_JNI_GetDoubleArrayElements,
4260 _Jv_JNI_ReleaseBooleanArrayElements,
4261 _Jv_JNI_ReleaseByteArrayElements,
4262 _Jv_JNI_ReleaseCharArrayElements,
4263 _Jv_JNI_ReleaseShortArrayElements,
4264 _Jv_JNI_ReleaseIntArrayElements,
4265 _Jv_JNI_ReleaseLongArrayElements,
4266 _Jv_JNI_ReleaseFloatArrayElements,
4267 _Jv_JNI_ReleaseDoubleArrayElements,
4269 _Jv_JNI_GetBooleanArrayRegion,
4270 _Jv_JNI_GetByteArrayRegion,
4271 _Jv_JNI_GetCharArrayRegion,
4272 _Jv_JNI_GetShortArrayRegion,
4273 _Jv_JNI_GetIntArrayRegion,
4274 _Jv_JNI_GetLongArrayRegion,
4275 _Jv_JNI_GetFloatArrayRegion,
4276 _Jv_JNI_GetDoubleArrayRegion,
4277 _Jv_JNI_SetBooleanArrayRegion,
4278 _Jv_JNI_SetByteArrayRegion,
4279 _Jv_JNI_SetCharArrayRegion,
4280 _Jv_JNI_SetShortArrayRegion,
4281 _Jv_JNI_SetIntArrayRegion,
4282 _Jv_JNI_SetLongArrayRegion,
4283 _Jv_JNI_SetFloatArrayRegion,
4284 _Jv_JNI_SetDoubleArrayRegion,
4286 _Jv_JNI_RegisterNatives,
4287 _Jv_JNI_UnregisterNatives,
4289 _Jv_JNI_MonitorEnter,
4290 _Jv_JNI_MonitorExit,
4294 /* New JNI 1.2 functions. */
4296 _Jv_JNI_GetStringRegion,
4297 _Jv_JNI_GetStringUTFRegion,
4299 jni_GetPrimitiveArrayCritical,
4300 jni_ReleasePrimitiveArrayCritical,
4302 _Jv_JNI_GetStringCritical,
4303 _Jv_JNI_ReleaseStringCritical,
4305 _Jv_JNI_NewWeakGlobalRef,
4306 _Jv_JNI_DeleteWeakGlobalRef,
4308 _Jv_JNI_ExceptionCheck,
4310 /* New JNI 1.4 functions. */
4312 jni_NewDirectByteBuffer,
4313 _Jv_JNI_GetDirectBufferAddress,
4314 _Jv_JNI_GetDirectBufferCapacity,
4316 /* New JNI 1.6 functions. */
4318 jni_GetObjectRefType
4322 /* Invocation API Functions ***************************************************/
4324 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4326 Returns a default configuration for the Java VM.
4328 *******************************************************************************/
4330 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4332 JavaVMInitArgs *_vm_args;
4334 _vm_args = (JavaVMInitArgs *) vm_args;
4336 /* GNU classpath currently supports JNI 1.2 */
4338 switch (_vm_args->version) {
4339 case JNI_VERSION_1_1:
4340 _vm_args->version = JNI_VERSION_1_1;
4343 case JNI_VERSION_1_2:
4344 case JNI_VERSION_1_4:
4345 _vm_args->ignoreUnrecognized = JNI_FALSE;
4346 _vm_args->options = NULL;
4347 _vm_args->nOptions = 0;
4358 /* JNI_GetCreatedJavaVMs *******************************************************
4360 Returns all Java VMs that have been created. Pointers to VMs are written in
4361 the buffer vmBuf in the order they are created. At most bufLen number of
4362 entries will be written. The total number of created VMs is returned in
4365 *******************************************************************************/
4367 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4369 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4374 // We currently only support 1 VM running.
4376 vmBuf[0] = vm->get_javavm();
4383 /* JNI_CreateJavaVM ************************************************************
4385 Loads and initializes a Java VM. The current thread becomes the main thread.
4386 Sets the env argument to the JNI interface pointer of the main thread.
4388 *******************************************************************************/
4390 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4392 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4394 /* actually create the JVM */
4396 if (!VM_create(p_vm, p_env, vm_args))
4406 * These are local overrides for various environment variables in Emacs.
4407 * Please do not remove this and leave it at the end of the file, where
4408 * Emacs will automagically detect them.
4409 * ---------------------------------------------------------------------
4412 * indent-tabs-mode: t
4416 * vim:noexpandtab:sw=4:ts=4: