1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/gc-common.h"
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.h"
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 **********************************************************************/
126 # define TRACEJNICALLS(text) \
128 if (opt_TraceJNICalls) { \
133 # define TRACEJNICALLS(text)
137 /* global variables ***********************************************************/
139 /* global reference table *****************************************************/
141 /* hashsize must be power of 2 */
143 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
145 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
148 /* direct buffer stuff ********************************************************/
150 #if defined(ENABLE_JAVASE)
151 static classinfo *class_java_nio_Buffer;
153 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
155 static classinfo *class_java_nio_DirectByteBufferImpl;
156 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
158 # if SIZEOF_VOID_P == 8
159 static classinfo *class_gnu_classpath_Pointer64;
161 static classinfo *class_gnu_classpath_Pointer32;
164 static methodinfo *dbbirw_init;
166 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
168 static classinfo *class_sun_nio_ch_DirectBuffer;
169 static classinfo *class_java_nio_DirectByteBuffer;
171 static methodinfo *dbb_init;
177 /* some forward declarations **************************************************/
179 jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
182 /* jni_init ********************************************************************
184 Initialize the JNI subsystem.
186 *******************************************************************************/
190 TRACESUBSYSTEMINITIALIZATION("jni_init");
192 /* create global ref hashtable */
194 hashtable_global_ref = NEW(hashtable);
196 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
199 #if defined(ENABLE_JAVASE)
200 /* Direct buffer stuff. */
202 if (!(class_java_nio_Buffer =
203 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
204 !link_class(class_java_nio_Buffer))
207 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
209 if (!(class_java_nio_DirectByteBufferImpl =
210 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
211 !link_class(class_java_nio_DirectByteBufferImpl))
214 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
215 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
216 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
220 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
222 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
225 # if SIZEOF_VOID_P == 8
226 if (!(class_gnu_classpath_Pointer64 =
227 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
228 !link_class(class_gnu_classpath_Pointer64))
231 if (!(class_gnu_classpath_Pointer32 =
232 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
233 !link_class(class_gnu_classpath_Pointer32))
237 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
239 if (!(class_sun_nio_ch_DirectBuffer =
240 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
241 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
243 if (!link_class(class_sun_nio_ch_DirectBuffer))
244 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
246 if (!(class_java_nio_DirectByteBuffer =
247 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
248 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
250 if (!link_class(class_java_nio_DirectByteBuffer))
251 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
254 class_resolvemethod(class_java_nio_DirectByteBuffer,
256 utf_new_char("(JI)V"))))
257 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
261 #endif /* defined(ENABLE_JAVASE) */
267 /* jni_version_check ***********************************************************
269 Check if the given JNI version is supported.
272 version....JNI version to check
276 false......not supported
278 *******************************************************************************/
280 bool jni_version_check(int version)
283 case JNI_VERSION_1_1:
284 case JNI_VERSION_1_2:
285 case JNI_VERSION_1_4:
286 case JNI_VERSION_1_6:
294 /* _Jv_jni_CallObjectMethod ****************************************************
296 Internal function to call Java Object methods.
298 *******************************************************************************/
300 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
302 methodinfo *m, va_list ap)
307 STATISTICS(jniinvokation());
310 exceptions_throw_nullpointerexception();
314 /* Class initialization is done by the JIT compiler. This is ok
315 since a static method always belongs to the declaring class. */
317 if (m->flags & ACC_STATIC) {
318 /* For static methods we reset the object. */
323 /* for convenience */
328 /* For instance methods we make a virtual function table lookup. */
330 resm = method_vftbl_lookup(vftbl, m);
333 STATISTICS(jnicallXmethodnvokation());
335 ro = vm_call_method_valist(resm, o, ap);
341 /* _Jv_jni_CallObjectMethodA ***************************************************
343 Internal function to call Java Object methods.
345 *******************************************************************************/
347 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
355 STATISTICS(jniinvokation());
358 exceptions_throw_nullpointerexception();
362 /* Class initialization is done by the JIT compiler. This is ok
363 since a static method always belongs to the declaring class. */
365 if (m->flags & ACC_STATIC) {
366 /* For static methods we reset the object. */
371 /* for convenience */
376 /* For instance methods we make a virtual function table lookup. */
378 resm = method_vftbl_lookup(vftbl, m);
381 STATISTICS(jnicallXmethodnvokation());
383 ro = vm_call_method_jvalue(resm, o, args);
389 /* _Jv_jni_CallIntMethod *******************************************************
391 Internal function to call Java integer class methods (boolean,
392 byte, char, short, int).
394 *******************************************************************************/
396 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
397 methodinfo *m, va_list ap)
402 STATISTICS(jniinvokation());
405 exceptions_throw_nullpointerexception();
409 /* Class initialization is done by the JIT compiler. This is ok
410 since a static method always belongs to the declaring class. */
412 if (m->flags & ACC_STATIC) {
413 /* For static methods we reset the object. */
418 /* for convenience */
423 /* For instance methods we make a virtual function table lookup. */
425 resm = method_vftbl_lookup(vftbl, m);
428 STATISTICS(jnicallXmethodnvokation());
430 i = vm_call_method_int_valist(resm, o, ap);
436 /* _Jv_jni_CallIntMethodA ******************************************************
438 Internal function to call Java integer class methods (boolean,
439 byte, char, short, int).
441 *******************************************************************************/
443 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
444 methodinfo *m, const jvalue *args)
449 STATISTICS(jniinvokation());
452 exceptions_throw_nullpointerexception();
456 /* Class initialization is done by the JIT compiler. This is ok
457 since a static method always belongs to the declaring class. */
459 if (m->flags & ACC_STATIC) {
460 /* For static methods we reset the object. */
465 /* for convenience */
470 /* For instance methods we make a virtual function table lookup. */
472 resm = method_vftbl_lookup(vftbl, m);
475 STATISTICS(jnicallXmethodnvokation());
477 i = vm_call_method_int_jvalue(resm, o, args);
483 /* _Jv_jni_CallLongMethod ******************************************************
485 Internal function to call Java long methods.
487 *******************************************************************************/
489 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
490 methodinfo *m, va_list ap)
495 STATISTICS(jniinvokation());
498 exceptions_throw_nullpointerexception();
502 /* Class initialization is done by the JIT compiler. This is ok
503 since a static method always belongs to the declaring class. */
505 if (m->flags & ACC_STATIC) {
506 /* For static methods we reset the object. */
511 /* for convenience */
516 /* For instance methods we make a virtual function table lookup. */
518 resm = method_vftbl_lookup(vftbl, m);
521 STATISTICS(jnicallXmethodnvokation());
523 l = vm_call_method_long_valist(resm, o, ap);
529 /* _Jv_jni_CallLongMethodA *****************************************************
531 Internal function to call Java long methods.
533 *******************************************************************************/
535 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
536 methodinfo *m, const jvalue *args)
541 STATISTICS(jniinvokation());
544 exceptions_throw_nullpointerexception();
548 /* Class initialization is done by the JIT compiler. This is ok
549 since a static method always belongs to the declaring class. */
551 if (m->flags & ACC_STATIC) {
552 /* For static methods we reset the object. */
557 /* for convenience */
562 /* For instance methods we make a virtual function table lookup. */
564 resm = method_vftbl_lookup(vftbl, m);
567 STATISTICS(jnicallXmethodnvokation());
569 l = vm_call_method_long_jvalue(resm, o, args);
575 /* _Jv_jni_CallFloatMethod *****************************************************
577 Internal function to call Java float methods.
579 *******************************************************************************/
581 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
582 methodinfo *m, va_list ap)
587 /* Class initialization is done by the JIT compiler. This is ok
588 since a static method always belongs to the declaring class. */
590 if (m->flags & ACC_STATIC) {
591 /* For static methods we reset the object. */
596 /* for convenience */
601 /* For instance methods we make a virtual function table lookup. */
603 resm = method_vftbl_lookup(vftbl, m);
606 STATISTICS(jnicallXmethodnvokation());
608 f = vm_call_method_float_valist(resm, o, ap);
614 /* _Jv_jni_CallFloatMethodA ****************************************************
616 Internal function to call Java float methods.
618 *******************************************************************************/
620 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
621 methodinfo *m, const jvalue *args)
626 /* Class initialization is done by the JIT compiler. This is ok
627 since a static method always belongs to the declaring class. */
629 if (m->flags & ACC_STATIC) {
630 /* For static methods we reset the object. */
635 /* for convenience */
640 /* For instance methods we make a virtual function table lookup. */
642 resm = method_vftbl_lookup(vftbl, m);
645 STATISTICS(jnicallXmethodnvokation());
647 f = vm_call_method_float_jvalue(resm, o, args);
653 /* _Jv_jni_CallDoubleMethod ****************************************************
655 Internal function to call Java double methods.
657 *******************************************************************************/
659 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
660 methodinfo *m, va_list ap)
665 /* Class initialization is done by the JIT compiler. This is ok
666 since a static method always belongs to the declaring class. */
668 if (m->flags & ACC_STATIC) {
669 /* For static methods we reset the object. */
674 /* for convenience */
679 /* For instance methods we make a virtual function table lookup. */
681 resm = method_vftbl_lookup(vftbl, m);
684 d = vm_call_method_double_valist(resm, o, ap);
690 /* _Jv_jni_CallDoubleMethodA ***************************************************
692 Internal function to call Java double methods.
694 *******************************************************************************/
696 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
697 methodinfo *m, const jvalue *args)
702 /* Class initialization is done by the JIT compiler. This is ok
703 since a static method always belongs to the declaring class. */
705 if (m->flags & ACC_STATIC) {
706 /* For static methods we reset the object. */
711 /* for convenience */
716 /* For instance methods we make a virtual function table lookup. */
718 resm = method_vftbl_lookup(vftbl, m);
721 d = vm_call_method_double_jvalue(resm, o, args);
727 /* _Jv_jni_CallVoidMethod ******************************************************
729 Internal function to call Java void methods.
731 *******************************************************************************/
733 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
734 methodinfo *m, va_list ap)
739 exceptions_throw_nullpointerexception();
743 /* Class initialization is done by the JIT compiler. This is ok
744 since a static method always belongs to the declaring class. */
746 if (m->flags & ACC_STATIC) {
747 /* For static methods we reset the object. */
752 /* for convenience */
757 /* For instance methods we make a virtual function table lookup. */
759 resm = method_vftbl_lookup(vftbl, m);
762 STATISTICS(jnicallXmethodnvokation());
764 (void) vm_call_method_valist(resm, o, ap);
768 /* _Jv_jni_CallVoidMethodA *****************************************************
770 Internal function to call Java void methods.
772 *******************************************************************************/
774 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
775 methodinfo *m, const jvalue *args)
780 exceptions_throw_nullpointerexception();
784 /* Class initialization is done by the JIT compiler. This is ok
785 since a static method always belongs to the declaring class. */
787 if (m->flags & ACC_STATIC) {
788 /* For static methods we reset the object. */
793 /* for convenience */
798 /* For instance methods we make a virtual function table lookup. */
800 resm = method_vftbl_lookup(vftbl, m);
803 STATISTICS(jnicallXmethodnvokation());
805 (void) vm_call_method_jvalue(resm, o, args);
809 /* GetVersion ******************************************************************
811 Returns the major version number in the higher 16 bits and the
812 minor version number in the lower 16 bits.
814 *******************************************************************************/
816 jint _Jv_JNI_GetVersion(JNIEnv *env)
818 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
820 /* We support JNI 1.6. */
822 return JNI_VERSION_1_6;
826 /* Class Operations ***********************************************************/
828 /* DefineClass *****************************************************************
830 Loads a class from a buffer of raw class data. The buffer
831 containing the raw class data is not referenced by the VM after the
832 DefineClass call returns, and it may be discarded if desired.
834 *******************************************************************************/
836 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
837 const jbyte *buf, jsize bufLen)
839 #if defined(ENABLE_JAVASE)
845 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
847 u = utf_new_char(name);
848 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
850 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
852 co = LLNI_classinfo_wrap(c);
854 return (jclass) jni_NewLocalRef(env, (jobject) co);
856 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
858 /* keep compiler happy */
865 /* FindClass *******************************************************************
867 This function loads a locally-defined class. It searches the
868 directories and zip files specified by the CLASSPATH environment
869 variable for the class with the specified name.
871 *******************************************************************************/
873 jclass jni_FindClass(JNIEnv *env, const char *name)
875 #if defined(ENABLE_JAVASE)
882 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
884 /* FIXME If name is NULL we have a problem here. */
886 u = utf_new_char_classname((char *) name);
888 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
889 exceptions_throw_noclassdeffounderror(u);
893 /* Check stacktrace for classloader, if one found use it,
894 otherwise use the system classloader. */
896 /* Quote from the JNI documentation:
898 In the Java 2 Platform, FindClass locates the class loader
899 associated with the current native method. If the native code
900 belongs to a system class, no class loader will be
901 involved. Otherwise, the proper class loader will be invoked to
902 load and link the named class. When FindClass is called through
903 the Invocation Interface, there is no current native method or
904 its associated class loader. In that case, the result of
905 ClassLoader.getBaseClassLoader is used." */
907 cc = stacktrace_get_current_class();
910 c = load_class_from_sysloader(u);
912 c = load_class_from_classloader(u, cc->classloader);
915 resolve_handle_pending_exception(true);
922 co = LLNI_classinfo_wrap(c);
924 return (jclass) jni_NewLocalRef(env, (jobject) co);
926 #elif defined(ENABLE_JAVAME_CLDC1_1)
931 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
933 u = utf_new_char_classname((char *) name);
934 c = load_class_bootstrap(u);
937 resolve_handle_pending_exception(true);
944 return (jclass) jni_NewLocalRef(env, (jobject) c);
947 vm_abort("jni_FindClass: not implemented in this configuration");
949 /* keep compiler happy */
956 /* GetSuperclass ***************************************************************
958 If clazz represents any class other than the class Object, then
959 this function returns the object that represents the superclass of
960 the class specified by clazz.
962 *******************************************************************************/
964 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
970 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
972 c = LLNI_classinfo_unwrap(sub);
977 super = class_get_superclass(c);
979 co = LLNI_classinfo_wrap(super);
981 return (jclass) jni_NewLocalRef(env, (jobject) co);
985 /* IsAssignableFrom ************************************************************
987 Determines whether an object of sub can be safely cast to sup.
989 *******************************************************************************/
991 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
996 TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
998 to = (classinfo *) sup;
999 from = (classinfo *) sub;
1001 return class_is_assignable_from(to, from);
1005 /* Throw ***********************************************************************
1007 Causes a java.lang.Throwable object to be thrown.
1009 *******************************************************************************/
1011 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1015 STATISTICS(jniinvokation());
1017 o = (java_handle_t *) obj;
1019 exceptions_set_exception(o);
1025 /* ThrowNew ********************************************************************
1027 Constructs an exception object from the specified class with the
1028 message specified by message and causes that exception to be
1031 *******************************************************************************/
1033 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1039 STATISTICS(jniinvokation());
1041 c = LLNI_classinfo_unwrap(clazz);
1044 s = javastring_new_from_utf_string(msg);
1046 /* instantiate exception object */
1048 o = native_new_and_init_string(c, s);
1053 exceptions_set_exception(o);
1059 /* ExceptionOccurred ***********************************************************
1061 Determines if an exception is being thrown. The exception stays
1062 being thrown until either the native code calls ExceptionClear(),
1063 or the Java code handles the exception.
1065 *******************************************************************************/
1067 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1071 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1073 o = exceptions_get_exception();
1075 return jni_NewLocalRef(env, (jthrowable) o);
1079 /* ExceptionDescribe ***********************************************************
1081 Prints an exception and a backtrace of the stack to a system
1082 error-reporting channel, such as stderr. This is a convenience
1083 routine provided for debugging.
1085 *******************************************************************************/
1087 void jni_ExceptionDescribe(JNIEnv *env)
1089 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1091 exceptions_print_stacktrace();
1095 /* ExceptionClear **************************************************************
1097 Clears any exception that is currently being thrown. If no
1098 exception is currently being thrown, this routine has no effect.
1100 *******************************************************************************/
1102 void jni_ExceptionClear(JNIEnv *env)
1104 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1106 exceptions_clear_exception();
1110 /* FatalError ******************************************************************
1112 Raises a fatal error and does not expect the VM to recover. This
1113 function does not return.
1115 *******************************************************************************/
1117 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1119 STATISTICS(jniinvokation());
1121 /* this seems to be the best way */
1123 vm_abort("JNI Fatal error: %s", msg);
1127 /* PushLocalFrame **************************************************************
1129 Creates a new local reference frame, in which at least a given
1130 number of local references can be created.
1132 *******************************************************************************/
1134 jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1136 TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1141 /* add new local reference frame to current table */
1143 if (!localref_frame_push(capacity))
1150 /* PopLocalFrame ***************************************************************
1152 Pops off the current local reference frame, frees all the local
1153 references, and returns a local reference in the previous local
1154 reference frame for the given result object.
1156 *******************************************************************************/
1158 jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1160 TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1162 /* release all current local frames */
1164 localref_frame_pop_all();
1166 /* add local reference and return the value */
1168 return jni_NewLocalRef(env, result);
1172 /* DeleteLocalRef **************************************************************
1174 Deletes the local reference pointed to by localRef.
1176 *******************************************************************************/
1178 void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1182 TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1184 o = (java_handle_t *) localRef;
1189 /* delete the reference */
1195 /* IsSameObject ****************************************************************
1197 Tests whether two references refer to the same Java object.
1199 *******************************************************************************/
1201 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1207 STATISTICS(jniinvokation());
1209 o1 = (java_handle_t *) ref1;
1210 o2 = (java_handle_t *) ref2;
1212 LLNI_CRITICAL_START;
1214 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1225 /* NewLocalRef *****************************************************************
1227 Creates a new local reference that refers to the same object as ref.
1229 *******************************************************************************/
1231 jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1234 java_handle_t *localref;
1236 TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1238 o = (java_handle_t *) ref;
1243 /* insert the reference */
1245 localref = localref_add(LLNI_DIRECT(o));
1247 return (jobject) localref;
1251 /* EnsureLocalCapacity *********************************************************
1253 Ensures that at least a given number of local references can be
1254 created in the current thread
1256 *******************************************************************************/
1258 jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1260 localref_table *lrt;
1262 TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1264 /* get local reference table (thread specific) */
1266 lrt = LOCALREFTABLE;
1268 /* check if capacity elements are available in the local references table */
1270 if ((lrt->used + capacity) > lrt->capacity)
1271 return jni_PushLocalFrame(env, capacity);
1277 /* AllocObject *****************************************************************
1279 Allocates a new Java object without invoking any of the
1280 constructors for the object. Returns a reference to the object.
1282 *******************************************************************************/
1284 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1289 STATISTICS(jniinvokation());
1291 c = LLNI_classinfo_unwrap(clazz);
1293 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1294 exceptions_throw_instantiationexception(c);
1300 return jni_NewLocalRef(env, (jobject) o);
1304 /* NewObject *******************************************************************
1306 Programmers place all arguments that are to be passed to the
1307 constructor immediately following the methodID
1308 argument. NewObject() accepts these arguments and passes them to
1309 the Java method that the programmer wishes to invoke.
1311 *******************************************************************************/
1313 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1320 STATISTICS(jniinvokation());
1322 c = LLNI_classinfo_unwrap(clazz);
1323 m = (methodinfo *) methodID;
1332 /* call constructor */
1334 va_start(ap, methodID);
1335 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1338 return jni_NewLocalRef(env, (jobject) o);
1342 /* NewObjectV ******************************************************************
1344 Programmers place all arguments that are to be passed to the
1345 constructor in an args argument of type va_list that immediately
1346 follows the methodID argument. NewObjectV() accepts these
1347 arguments, and, in turn, passes them to the Java method that the
1348 programmer wishes to invoke.
1350 *******************************************************************************/
1352 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1359 STATISTICS(jniinvokation());
1361 c = LLNI_classinfo_unwrap(clazz);
1362 m = (methodinfo *) methodID;
1371 /* call constructor */
1373 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1375 return jni_NewLocalRef(env, (jobject) o);
1379 /* NewObjectA *****************************************************************
1381 Programmers place all arguments that are to be passed to the
1382 constructor in an args array of jvalues that immediately follows
1383 the methodID argument. NewObjectA() accepts the arguments in this
1384 array, and, in turn, passes them to the Java method that the
1385 programmer wishes to invoke.
1387 *******************************************************************************/
1389 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1396 STATISTICS(jniinvokation());
1398 c = LLNI_classinfo_unwrap(clazz);
1399 m = (methodinfo *) methodID;
1408 /* call constructor */
1410 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1412 return jni_NewLocalRef(env, (jobject) o);
1416 /* GetObjectClass **************************************************************
1418 Returns the class of an object.
1420 *******************************************************************************/
1422 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1426 java_lang_Class *co;
1428 STATISTICS(jniinvokation());
1430 o = (java_handle_t *) obj;
1432 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1435 LLNI_class_get(o, c);
1437 co = LLNI_classinfo_wrap(c);
1439 return (jclass) jni_NewLocalRef(env, (jobject) co);
1443 /* IsInstanceOf ****************************************************************
1445 Tests whether an object is an instance of a class.
1447 *******************************************************************************/
1449 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1454 TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1456 /* XXX Is this correct? */
1457 c = LLNI_classinfo_unwrap(clazz);
1458 h = (java_handle_t *) obj;
1460 return class_is_instance(c, h);
1464 /* Reflection Support *********************************************************/
1466 /* FromReflectedMethod *********************************************************
1468 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1469 object to a method ID.
1471 *******************************************************************************/
1473 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1475 #if defined(ENABLE_JAVASE)
1477 java_lang_reflect_Method *rm;
1478 java_lang_reflect_Constructor *rc;
1483 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1484 java_lang_reflect_VMMethod *rvmm;
1485 java_lang_reflect_VMConstructor *rvmc;
1488 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1490 o = (java_handle_t *) method;
1495 if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
1496 rc = (java_lang_reflect_Constructor *) method;
1498 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1500 LLNI_field_get_ref(rc, cons , rvmc);
1501 LLNI_field_get_cls(rvmc, clazz, c);
1502 LLNI_field_get_val(rvmc, slot , slot);
1504 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1506 LLNI_field_get_cls(rc, clazz, c);
1507 LLNI_field_get_val(rc, slot , slot);
1510 # error unknown configuration
1514 assert(o->vftbl->clazz == class_java_lang_reflect_Method);
1516 rm = (java_lang_reflect_Method *) method;
1518 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1520 LLNI_field_get_ref(rm, m , rvmm);
1521 LLNI_field_get_cls(rvmm, clazz, c);
1522 LLNI_field_get_val(rvmm, slot , slot);
1524 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1526 LLNI_field_get_cls(rm, clazz, c);
1527 LLNI_field_get_val(rm, slot , slot);
1530 # error unknown configuration
1534 m = &(c->methods[slot]);
1536 return (jmethodID) m;
1538 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1540 /* Keep compiler happy. */
1547 /* FromReflectedField **********************************************************
1549 Converts a java.lang.reflect.Field to a field ID.
1551 *******************************************************************************/
1553 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1555 #if defined(ENABLE_JAVASE)
1556 java_lang_reflect_Field *rf;
1561 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1562 java_lang_reflect_VMField *rvmf;
1565 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1567 rf = (java_lang_reflect_Field *) field;
1572 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1574 LLNI_field_get_ref(rf, f, rvmf);
1575 LLNI_field_get_cls(rvmf, clazz, c);
1576 LLNI_field_get_val(rvmf, slot , slot);
1578 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1580 LLNI_field_get_cls(rf, clazz, c);
1581 LLNI_field_get_val(rf, slot , slot);
1584 # error unknown configuration
1587 f = &(c->fields[slot]);
1589 return (jfieldID) f;
1591 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1593 /* Keep compiler happy. */
1600 /* ToReflectedMethod ***********************************************************
1602 Converts a method ID derived from cls to an instance of the
1603 java.lang.reflect.Method class or to an instance of the
1604 java.lang.reflect.Constructor class.
1606 *******************************************************************************/
1608 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1611 #if defined(ENABLE_JAVASE)
1613 java_lang_reflect_Constructor *rc;
1614 java_lang_reflect_Method *rm;
1616 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1618 m = (methodinfo *) methodID;
1620 /* HotSpot does the same assert. */
1622 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1624 if (m->name == utf_init) {
1625 rc = reflect_constructor_new(m);
1627 return (jobject) rc;
1630 rm = reflect_method_new(m);
1632 return (jobject) rm;
1635 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1637 /* keep compiler happy */
1644 /* ToReflectedField ************************************************************
1646 Converts a field ID derived from cls to an instance of the
1647 java.lang.reflect.Field class.
1649 *******************************************************************************/
1651 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1654 STATISTICS(jniinvokation());
1656 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1662 /* Calling Instance Methods ***************************************************/
1664 /* GetMethodID *****************************************************************
1666 Returns the method ID for an instance (nonstatic) method of a class
1667 or interface. The method may be defined in one of the clazz's
1668 superclasses and inherited by clazz. The method is determined by
1669 its name and signature.
1671 GetMethodID() causes an uninitialized class to be initialized.
1673 *******************************************************************************/
1675 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1683 STATISTICS(jniinvokation());
1685 c = LLNI_classinfo_unwrap(clazz);
1690 if (!(c->state & CLASS_INITIALIZED))
1691 if (!initialize_class(c))
1694 /* try to get the method of the class or one of it's superclasses */
1696 uname = utf_new_char((char *) name);
1697 udesc = utf_new_char((char *) sig);
1699 m = class_resolvemethod(c, uname, udesc);
1701 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1702 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1707 return (jmethodID) m;
1711 /* JNI-functions for calling instance methods *********************************/
1713 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1714 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1715 jmethodID methodID, ...) \
1722 o = (java_handle_t *) obj; \
1723 m = (methodinfo *) methodID; \
1725 va_start(ap, methodID); \
1726 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1732 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1733 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1734 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1735 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1736 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1737 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1738 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1739 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1742 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1743 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1744 jmethodID methodID, va_list args) \
1750 o = (java_handle_t *) obj; \
1751 m = (methodinfo *) methodID; \
1753 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1758 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1759 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1760 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1761 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1762 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1763 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1764 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1765 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1768 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1769 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1770 jmethodID methodID, \
1771 const jvalue *args) \
1777 o = (java_handle_t *) obj; \
1778 m = (methodinfo *) methodID; \
1780 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1785 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1786 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1787 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1788 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1789 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1790 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1791 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1792 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1795 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1803 o = (java_handle_t *) obj;
1804 m = (methodinfo *) methodID;
1806 va_start(ap, methodID);
1807 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1810 return jni_NewLocalRef(env, (jobject) ret);
1814 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1821 o = (java_handle_t *) obj;
1822 m = (methodinfo *) methodID;
1824 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1826 return jni_NewLocalRef(env, (jobject) ret);
1830 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1837 o = (java_handle_t *) obj;
1838 m = (methodinfo *) methodID;
1840 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1842 return jni_NewLocalRef(env, (jobject) ret);
1847 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1853 o = (java_handle_t *) obj;
1854 m = (methodinfo *) methodID;
1856 va_start(ap, methodID);
1857 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1862 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1868 o = (java_handle_t *) obj;
1869 m = (methodinfo *) methodID;
1871 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1875 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1881 o = (java_handle_t *) obj;
1882 m = (methodinfo *) methodID;
1884 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1889 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1890 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1891 jclass clazz, jmethodID methodID, \
1900 o = (java_handle_t *) obj; \
1901 c = LLNI_classinfo_unwrap(clazz); \
1902 m = (methodinfo *) methodID; \
1904 va_start(ap, methodID); \
1905 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1911 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1912 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1913 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1914 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1915 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1916 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1917 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1918 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1921 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1922 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1923 jclass clazz, jmethodID methodID, \
1931 o = (java_handle_t *) obj; \
1932 c = LLNI_classinfo_unwrap(clazz); \
1933 m = (methodinfo *) methodID; \
1935 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1940 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1941 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1942 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1943 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1944 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1945 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1946 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1947 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1950 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1951 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1952 jclass clazz, jmethodID methodID, \
1953 const jvalue *args) \
1955 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1960 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1961 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1962 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1963 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1964 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1965 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1966 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1967 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1969 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1970 jclass clazz, jmethodID methodID,
1979 o = (java_handle_t *) obj;
1980 c = LLNI_classinfo_unwrap(clazz);
1981 m = (methodinfo *) methodID;
1983 va_start(ap, methodID);
1984 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1987 return jni_NewLocalRef(env, (jobject) r);
1991 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1992 jclass clazz, jmethodID methodID,
2000 o = (java_handle_t *) obj;
2001 c = LLNI_classinfo_unwrap(clazz);
2002 m = (methodinfo *) methodID;
2004 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2006 return jni_NewLocalRef(env, (jobject) r);
2010 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2011 jclass clazz, jmethodID methodID,
2014 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2016 return jni_NewLocalRef(env, NULL);
2020 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2021 jmethodID methodID, ...)
2028 o = (java_handle_t *) obj;
2029 c = LLNI_classinfo_unwrap(clazz);
2030 m = (methodinfo *) methodID;
2032 va_start(ap, methodID);
2033 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2038 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2039 jmethodID methodID, va_list args)
2045 o = (java_handle_t *) obj;
2046 c = LLNI_classinfo_unwrap(clazz);
2047 m = (methodinfo *) methodID;
2049 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2053 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2054 jmethodID methodID, const jvalue * args)
2060 o = (java_handle_t *) obj;
2061 c = LLNI_classinfo_unwrap(clazz);
2062 m = (methodinfo *) methodID;
2064 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2068 /* Accessing Fields of Objects ************************************************/
2070 /* GetFieldID ******************************************************************
2072 Returns the field ID for an instance (nonstatic) field of a
2073 class. The field is specified by its name and signature. The
2074 Get<type>Field and Set<type>Field families of accessor functions
2075 use field IDs to retrieve object fields.
2077 *******************************************************************************/
2079 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2087 STATISTICS(jniinvokation());
2089 c = LLNI_classinfo_unwrap(clazz);
2091 /* XXX NPE check? */
2093 uname = utf_new_char((char *) name);
2094 udesc = utf_new_char((char *) sig);
2096 f = class_findfield(c, uname, udesc);
2099 exceptions_throw_nosuchfielderror(c, uname);
2101 return (jfieldID) f;
2105 /* Get<type>Field Routines *****************************************************
2107 This family of accessor routines returns the value of an instance
2108 (nonstatic) field of an object. The field to access is specified by
2109 a field ID obtained by calling GetFieldID().
2111 *******************************************************************************/
2113 #define GET_FIELD(o,type,f) \
2114 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2116 #define JNI_GET_FIELD(name, type, intern) \
2117 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2121 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2123 LLNI_CRITICAL_START; \
2125 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2127 LLNI_CRITICAL_END; \
2129 return (type) ret; \
2132 JNI_GET_FIELD(Boolean, jboolean, s4)
2133 JNI_GET_FIELD(Byte, jbyte, s4)
2134 JNI_GET_FIELD(Char, jchar, s4)
2135 JNI_GET_FIELD(Short, jshort, s4)
2136 JNI_GET_FIELD(Int, jint, s4)
2137 JNI_GET_FIELD(Long, jlong, s8)
2138 JNI_GET_FIELD(Float, jfloat, float)
2139 JNI_GET_FIELD(Double, jdouble, double)
2142 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2146 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2148 LLNI_CRITICAL_START;
2150 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2154 return jni_NewLocalRef(env, (jobject) o);
2158 /* Set<type>Field Routines *****************************************************
2160 This family of accessor routines sets the value of an instance
2161 (nonstatic) field of an object. The field to access is specified by
2162 a field ID obtained by calling GetFieldID().
2164 *******************************************************************************/
2166 #define SET_FIELD(o,type,f,value) \
2167 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2169 #define JNI_SET_FIELD(name, type, intern) \
2170 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2173 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2175 LLNI_CRITICAL_START; \
2177 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2179 LLNI_CRITICAL_START; \
2182 JNI_SET_FIELD(Boolean, jboolean, s4)
2183 JNI_SET_FIELD(Byte, jbyte, s4)
2184 JNI_SET_FIELD(Char, jchar, s4)
2185 JNI_SET_FIELD(Short, jshort, s4)
2186 JNI_SET_FIELD(Int, jint, s4)
2187 JNI_SET_FIELD(Long, jlong, s8)
2188 JNI_SET_FIELD(Float, jfloat, float)
2189 JNI_SET_FIELD(Double, jdouble, double)
2192 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2195 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2197 LLNI_CRITICAL_START;
2199 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2205 /* Calling Static Methods *****************************************************/
2207 /* GetStaticMethodID ***********************************************************
2209 Returns the method ID for a static method of a class. The method is
2210 specified by its name and signature.
2212 GetStaticMethodID() causes an uninitialized class to be
2215 *******************************************************************************/
2217 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2225 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2227 c = LLNI_classinfo_unwrap(clazz);
2232 if (!(c->state & CLASS_INITIALIZED))
2233 if (!initialize_class(c))
2236 /* try to get the static method of the class */
2238 uname = utf_new_char((char *) name);
2239 udesc = utf_new_char((char *) sig);
2241 m = class_resolvemethod(c, uname, udesc);
2243 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2244 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2249 return (jmethodID) m;
2253 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2254 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2255 jmethodID methodID, ...) \
2261 m = (methodinfo *) methodID; \
2263 va_start(ap, methodID); \
2264 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2270 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2271 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2272 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2273 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2274 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2275 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2276 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2277 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2280 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2281 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2282 jmethodID methodID, va_list args) \
2287 m = (methodinfo *) methodID; \
2289 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2294 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2295 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2296 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2297 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2298 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2299 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2300 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2301 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2304 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2305 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2306 jmethodID methodID, const jvalue *args) \
2311 m = (methodinfo *) methodID; \
2313 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2318 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2319 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2320 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2321 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2322 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2323 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2324 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2325 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2328 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2329 jmethodID methodID, ...)
2335 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2337 m = (methodinfo *) methodID;
2339 va_start(ap, methodID);
2340 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2343 return jni_NewLocalRef(env, (jobject) o);
2347 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2348 jmethodID methodID, va_list args)
2353 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2355 m = (methodinfo *) methodID;
2357 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2359 return jni_NewLocalRef(env, (jobject) o);
2363 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2364 jmethodID methodID, const jvalue *args)
2369 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2371 m = (methodinfo *) methodID;
2373 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2375 return jni_NewLocalRef(env, (jobject) o);
2379 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2380 jmethodID methodID, ...)
2385 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2387 m = (methodinfo *) methodID;
2389 va_start(ap, methodID);
2390 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2395 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2396 jmethodID methodID, va_list args)
2400 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2402 m = (methodinfo *) methodID;
2404 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2408 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2409 jmethodID methodID, const jvalue * args)
2413 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2415 m = (methodinfo *) methodID;
2417 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2421 /* Accessing Static Fields ****************************************************/
2423 /* GetStaticFieldID ************************************************************
2425 Returns the field ID for a static field of a class. The field is
2426 specified by its name and signature. The GetStatic<type>Field and
2427 SetStatic<type>Field families of accessor functions use field IDs
2428 to retrieve static fields.
2430 *******************************************************************************/
2432 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2440 STATISTICS(jniinvokation());
2442 c = LLNI_classinfo_unwrap(clazz);
2444 uname = utf_new_char((char *) name);
2445 usig = utf_new_char((char *) sig);
2447 f = class_findfield(c, uname, usig);
2450 exceptions_throw_nosuchfielderror(c, uname);
2452 return (jfieldID) f;
2456 /* GetStatic<type>Field ********************************************************
2458 This family of accessor routines returns the value of a static
2461 *******************************************************************************/
2463 #define JNI_GET_STATIC_FIELD(name, type, field) \
2464 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2470 STATISTICS(jniinvokation()); \
2472 c = LLNI_classinfo_unwrap(clazz); \
2473 f = (fieldinfo *) fieldID; \
2475 if (!(c->state & CLASS_INITIALIZED)) \
2476 if (!initialize_class(c)) \
2479 return f->value->field; \
2482 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2483 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2484 JNI_GET_STATIC_FIELD(Char, jchar, i)
2485 JNI_GET_STATIC_FIELD(Short, jshort, i)
2486 JNI_GET_STATIC_FIELD(Int, jint, i)
2487 JNI_GET_STATIC_FIELD(Long, jlong, l)
2488 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2489 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2492 jobject _Jv_JNI_GetStaticObjectField(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 h = LLNI_WRAP(f->value->a);
2510 return jni_NewLocalRef(env, (jobject) h);
2514 /* SetStatic<type>Field *******************************************************
2516 This family of accessor routines sets the value of a static field
2519 *******************************************************************************/
2521 #define JNI_SET_STATIC_FIELD(name, type, field) \
2522 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2529 STATISTICS(jniinvokation()); \
2531 c = LLNI_classinfo_unwrap(clazz); \
2532 f = (fieldinfo *) fieldID; \
2534 if (!(c->state & CLASS_INITIALIZED)) \
2535 if (!initialize_class(c)) \
2538 f->value->field = value; \
2541 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2542 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2543 JNI_SET_STATIC_FIELD(Char, jchar, i)
2544 JNI_SET_STATIC_FIELD(Short, jshort, i)
2545 JNI_SET_STATIC_FIELD(Int, jint, i)
2546 JNI_SET_STATIC_FIELD(Long, jlong, l)
2547 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2548 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2551 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2557 STATISTICS(jniinvokation());
2559 c = LLNI_classinfo_unwrap(clazz);
2560 f = (fieldinfo *) fieldID;
2562 if (!(c->state & CLASS_INITIALIZED))
2563 if (!initialize_class(c))
2566 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2570 /* String Operations **********************************************************/
2572 /* NewString *******************************************************************
2574 Create new java.lang.String object from an array of Unicode
2577 *******************************************************************************/
2579 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2581 java_lang_String *s;
2582 java_handle_chararray_t *a;
2585 STATISTICS(jniinvokation());
2587 s = (java_lang_String *) builtin_new(class_java_lang_String);
2588 a = builtin_newarray_char(len);
2590 /* javastring or characterarray could not be created */
2591 if ((a == NULL) || (s == NULL))
2595 for (i = 0; i < len; i++)
2596 LLNI_array_direct(a, i) = buf[i];
2598 LLNI_field_set_ref(s, value , a);
2599 LLNI_field_set_val(s, offset, 0);
2600 LLNI_field_set_val(s, count , len);
2602 return (jstring) jni_NewLocalRef(env, (jobject) s);
2606 static jchar emptyStringJ[]={0,0};
2608 /* GetStringLength *************************************************************
2610 Returns the length (the count of Unicode characters) of a Java
2613 *******************************************************************************/
2615 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2617 java_lang_String *s;
2620 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2622 s = (java_lang_String *) str;
2624 LLNI_field_get_val(s, count, len);
2630 /******************** convertes javastring to u2-array ****************************/
2632 u2 *javastring_tou2(jstring so)
2634 java_lang_String *s;
2635 java_handle_chararray_t *a;
2641 STATISTICS(jniinvokation());
2643 s = (java_lang_String *) so;
2648 LLNI_field_get_ref(s, value, a);
2653 LLNI_field_get_val(s, count, count);
2654 LLNI_field_get_val(s, offset, offset);
2656 /* allocate memory */
2658 stringbuffer = MNEW(u2, count + 1);
2662 for (i = 0; i < count; i++)
2663 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2665 /* terminate string */
2667 stringbuffer[i] = '\0';
2669 return stringbuffer;
2673 /* GetStringChars **************************************************************
2675 Returns a pointer to the array of Unicode characters of the
2676 string. This pointer is valid until ReleaseStringChars() is called.
2678 *******************************************************************************/
2680 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2684 STATISTICS(jniinvokation());
2686 jc = javastring_tou2(str);
2698 return emptyStringJ;
2702 /* ReleaseStringChars **********************************************************
2704 Informs the VM that the native code no longer needs access to
2705 chars. The chars argument is a pointer obtained from string using
2708 *******************************************************************************/
2710 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2712 java_lang_String *s;
2714 STATISTICS(jniinvokation());
2716 if (chars == emptyStringJ)
2719 s = (java_lang_String *) str;
2721 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2725 /* NewStringUTF ****************************************************************
2727 Constructs a new java.lang.String object from an array of UTF-8
2730 *******************************************************************************/
2732 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2734 java_lang_String *s;
2736 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2738 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2740 return (jstring) jni_NewLocalRef(env, (jobject) s);
2744 /****************** returns the utf8 length in bytes of a string *******************/
2746 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2748 java_lang_String *s;
2751 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2753 s = (java_lang_String *) string;
2755 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2761 /* GetStringUTFChars ***********************************************************
2763 Returns a pointer to an array of UTF-8 characters of the
2764 string. This array is valid until it is released by
2765 ReleaseStringUTFChars().
2767 *******************************************************************************/
2769 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2774 STATISTICS(jniinvokation());
2782 u = javastring_toutf((java_handle_t *) string, false);
2791 /* ReleaseStringUTFChars *******************************************************
2793 Informs the VM that the native code no longer needs access to
2794 utf. The utf argument is a pointer derived from string using
2795 GetStringUTFChars().
2797 *******************************************************************************/
2799 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2801 STATISTICS(jniinvokation());
2803 /* XXX we don't release utf chars right now, perhaps that should be done
2804 later. Since there is always one reference the garbage collector will
2809 /* Array Operations ***********************************************************/
2811 /* GetArrayLength **************************************************************
2813 Returns the number of elements in the array.
2815 *******************************************************************************/
2817 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2822 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2824 a = (java_handle_t *) array;
2826 size = LLNI_array_size(a);
2832 /* NewObjectArray **************************************************************
2834 Constructs a new array holding objects in class elementClass. All
2835 elements are initially set to initialElement.
2837 *******************************************************************************/
2839 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2840 jclass elementClass, jobject initialElement)
2844 java_handle_objectarray_t *oa;
2847 STATISTICS(jniinvokation());
2849 c = LLNI_classinfo_unwrap(elementClass);
2850 o = (java_handle_t *) initialElement;
2853 exceptions_throw_negativearraysizeexception();
2857 oa = builtin_anewarray(length, c);
2862 /* set all elements to initialElement */
2864 for (i = 0; i < length; i++)
2865 array_objectarray_element_set(oa, i, o);
2867 return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
2871 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2874 java_handle_objectarray_t *oa;
2877 STATISTICS(jniinvokation());
2879 oa = (java_handle_objectarray_t *) array;
2881 if (index >= LLNI_array_size(oa)) {
2882 exceptions_throw_arrayindexoutofboundsexception();
2886 o = array_objectarray_element_get(oa, index);
2888 return jni_NewLocalRef(env, (jobject) o);
2892 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2893 jsize index, jobject val)
2895 java_handle_objectarray_t *oa;
2898 STATISTICS(jniinvokation());
2900 oa = (java_handle_objectarray_t *) array;
2901 o = (java_handle_t *) val;
2903 if (index >= LLNI_array_size(oa)) {
2904 exceptions_throw_arrayindexoutofboundsexception();
2908 /* check if the class of value is a subclass of the element class
2911 if (!builtin_canstore(oa, o))
2914 array_objectarray_element_set(oa, index, o);
2918 #define JNI_NEW_ARRAY(name, type, intern) \
2919 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2921 java_handle_##intern##array_t *a; \
2923 STATISTICS(jniinvokation()); \
2926 exceptions_throw_negativearraysizeexception(); \
2930 a = builtin_newarray_##intern(len); \
2932 return (type) jni_NewLocalRef(env, (jobject) a); \
2935 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2936 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2937 JNI_NEW_ARRAY(Char, jcharArray, char)
2938 JNI_NEW_ARRAY(Short, jshortArray, short)
2939 JNI_NEW_ARRAY(Int, jintArray, int)
2940 JNI_NEW_ARRAY(Long, jlongArray, long)
2941 JNI_NEW_ARRAY(Float, jfloatArray, float)
2942 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2945 /* Get<PrimitiveType>ArrayElements *********************************************
2947 A family of functions that returns the body of the primitive array.
2949 *******************************************************************************/
2951 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2952 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2955 java_handle_##intern##array_t *a; \
2957 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2959 a = (java_handle_##intern##array_t *) array; \
2962 *isCopy = JNI_FALSE; \
2964 return (type *) LLNI_array_data(a); \
2967 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2968 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2969 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2970 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2971 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2972 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2973 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2974 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2977 /* Release<PrimitiveType>ArrayElements *****************************************
2979 A family of functions that informs the VM that the native code no
2980 longer needs access to elems. The elems argument is a pointer
2981 derived from array using the corresponding
2982 Get<PrimitiveType>ArrayElements() function. If necessary, this
2983 function copies back all changes made to elems to the original
2986 *******************************************************************************/
2988 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2989 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2990 type *elems, jint mode) \
2992 java_handle_##intern##array_t *a; \
2994 STATISTICS(jniinvokation()); \
2996 a = (java_handle_##intern##array_t *) array; \
2998 if (elems != (type *) LLNI_array_data(a)) { \
3001 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3004 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3005 /* XXX TWISTI how should it be freed? */ \
3008 /* XXX TWISTI how should it be freed? */ \
3014 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3015 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3016 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3017 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3018 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3019 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3020 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3021 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3024 /* Get<PrimitiveType>ArrayRegion **********************************************
3026 A family of functions that copies a region of a primitive array
3029 *******************************************************************************/
3031 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3032 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3033 jsize start, jsize len, type *buf) \
3035 java_handle_##intern##array_t *a; \
3037 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3039 a = (java_handle_##intern##array_t *) array; \
3041 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3042 exceptions_throw_arrayindexoutofboundsexception(); \
3044 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3047 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3048 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3049 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3050 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3051 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3052 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3053 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3054 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3057 /* Set<PrimitiveType>ArrayRegion **********************************************
3059 A family of functions that copies back a region of a primitive
3060 array from a buffer.
3062 *******************************************************************************/
3064 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3065 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3066 jsize start, jsize len, const type *buf) \
3068 java_handle_##intern##array_t *a; \
3070 STATISTICS(jniinvokation()); \
3072 a = (java_handle_##intern##array_t *) array; \
3074 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3075 exceptions_throw_arrayindexoutofboundsexception(); \
3077 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3080 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3081 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3082 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3083 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3084 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3085 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3086 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3087 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3090 /* Registering Native Methods *************************************************/
3092 /* RegisterNatives *************************************************************
3094 Registers native methods with the class specified by the clazz
3095 argument. The methods parameter specifies an array of
3096 JNINativeMethod structures that contain the names, signatures, and
3097 function pointers of the native methods. The nMethods parameter
3098 specifies the number of native methods in the array.
3100 *******************************************************************************/
3102 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3103 const JNINativeMethod *methods, jint nMethods)
3107 STATISTICS(jniinvokation());
3109 c = LLNI_classinfo_unwrap(clazz);
3111 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3112 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3115 native_method_register(c->name, methods, nMethods);
3121 /* UnregisterNatives ***********************************************************
3123 Unregisters native methods of a class. The class goes back to the
3124 state before it was linked or registered with its native method
3127 This function should not be used in normal native code. Instead, it
3128 provides special programs a way to reload and relink native
3131 *******************************************************************************/
3133 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3135 STATISTICS(jniinvokation());
3137 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3139 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3145 /* Monitor Operations *********************************************************/
3147 /* MonitorEnter ****************************************************************
3149 Enters the monitor associated with the underlying Java object
3152 *******************************************************************************/
3154 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3156 STATISTICS(jniinvokation());
3159 exceptions_throw_nullpointerexception();
3163 LOCK_MONITOR_ENTER(obj);
3169 /* MonitorExit *****************************************************************
3171 The current thread must be the owner of the monitor associated with
3172 the underlying Java object referred to by obj. The thread
3173 decrements the counter indicating the number of times it has
3174 entered this monitor. If the value of the counter becomes zero, the
3175 current thread releases the monitor.
3177 *******************************************************************************/
3179 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3181 STATISTICS(jniinvokation());
3184 exceptions_throw_nullpointerexception();
3188 LOCK_MONITOR_EXIT(obj);
3194 /* JavaVM Interface ***********************************************************/
3196 /* GetJavaVM *******************************************************************
3198 Returns the Java VM interface (used in the Invocation API)
3199 associated with the current thread. The result is placed at the
3200 location pointed to by the second argument, vm.
3202 *******************************************************************************/
3204 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3206 STATISTICS(jniinvokation());
3208 *vm = (JavaVM *) _Jv_jvm;
3214 /* GetStringRegion *************************************************************
3216 Copies len number of Unicode characters beginning at offset start
3217 to the given buffer buf.
3219 Throws StringIndexOutOfBoundsException on index overflow.
3221 *******************************************************************************/
3223 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3226 java_lang_String *s;
3227 java_handle_chararray_t *ca;
3229 STATISTICS(jniinvokation());
3231 s = (java_lang_String *) str;
3232 LLNI_field_get_ref(s, value, ca);
3234 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3235 (start + len > LLNI_field_direct(s, count))) {
3236 exceptions_throw_stringindexoutofboundsexception();
3240 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3244 /* GetStringUTFRegion **********************************************************
3246 Translates len number of Unicode characters beginning at offset
3247 start into UTF-8 format and place the result in the given buffer
3250 Throws StringIndexOutOfBoundsException on index overflow.
3252 *******************************************************************************/
3254 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3255 jsize len, char *buf)
3257 java_lang_String *s;
3258 java_handle_chararray_t *ca;
3263 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3265 s = (java_lang_String *) str;
3266 LLNI_field_get_ref(s, value, ca);
3267 LLNI_field_get_val(s, count, count);
3268 LLNI_field_get_val(s, offset, offset);
3270 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3271 exceptions_throw_stringindexoutofboundsexception();
3275 for (i = 0; i < len; i++)
3276 buf[i] = LLNI_array_direct(ca, offset + start + i);
3282 /* GetPrimitiveArrayCritical ***************************************************
3284 Obtain a direct pointer to array elements.
3286 ATTENTION: Critical section keeps open when this function returns!
3287 See ReleasePrimitiveArrayCritical.
3289 *******************************************************************************/
3291 void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3295 arraydescriptor* ad;
3298 TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3300 if (isCopy != NULL) {
3301 *isCopy = JNI_FALSE;
3304 LLNI_CRITICAL_START;
3306 h = (java_handle_t*) array;
3307 a = (java_array_t*) LLNI_UNWRAP(h);
3308 ad = a->objheader.vftbl->arraydesc;
3314 data = (void*) (((intptr_t) a) + ad->dataoffset);
3320 /* ReleasePrimitiveArrayCritical ***********************************************
3322 No specific documentation.
3324 ATTENTION: This function closes the critical section opened in
3325 GetPrimitiveArrayCritical!
3327 *******************************************************************************/
3329 void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3331 TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3337 /* GetStringCritical ***********************************************************
3339 The semantics of these two functions are similar to the existing
3340 Get/ReleaseStringChars functions.
3342 *******************************************************************************/
3344 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3347 STATISTICS(jniinvokation());
3349 return _Jv_JNI_GetStringChars(env, string, isCopy);
3353 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3354 const jchar *cstring)
3356 STATISTICS(jniinvokation());
3358 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3362 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3364 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3370 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3372 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3376 /* NewGlobalRef ****************************************************************
3378 Creates a new global reference to the object referred to by the obj
3381 *******************************************************************************/
3383 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3385 hashtable_global_ref_entry *gre;
3386 u4 key; /* hashkey */
3387 u4 slot; /* slot in hashtable */
3390 STATISTICS(jniinvokation());
3392 o = (java_handle_t *) obj;
3394 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3396 LLNI_CRITICAL_START;
3398 /* normally addresses are aligned to 4, 8 or 16 bytes */
3400 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3401 slot = key & (hashtable_global_ref->size - 1);
3402 gre = hashtable_global_ref->ptr[slot];
3404 /* search external hash chain for the entry */
3407 if (gre->o == LLNI_DIRECT(o)) {
3408 /* global object found, increment the reference */
3415 gre = gre->hashlink; /* next element in external chain */
3420 /* global ref not found, create a new one */
3423 gre = NEW(hashtable_global_ref_entry);
3425 #if defined(ENABLE_GC_CACAO)
3426 /* register global ref with the GC */
3428 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3431 LLNI_CRITICAL_START;
3433 gre->o = LLNI_DIRECT(o);
3438 /* insert entry into hashtable */
3440 gre->hashlink = hashtable_global_ref->ptr[slot];
3442 hashtable_global_ref->ptr[slot] = gre;
3444 /* update number of hashtable-entries */
3446 hashtable_global_ref->entries++;
3449 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3451 #if defined(ENABLE_HANDLES)
3459 /* DeleteGlobalRef *************************************************************
3461 Deletes the global reference pointed to by globalRef.
3463 *******************************************************************************/
3465 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3467 hashtable_global_ref_entry *gre;
3468 hashtable_global_ref_entry *prevgre;
3469 u4 key; /* hashkey */
3470 u4 slot; /* slot in hashtable */
3473 STATISTICS(jniinvokation());
3475 o = (java_handle_t *) globalRef;
3477 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3479 LLNI_CRITICAL_START;
3481 /* normally addresses are aligned to 4, 8 or 16 bytes */
3483 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3484 slot = key & (hashtable_global_ref->size - 1);
3485 gre = hashtable_global_ref->ptr[slot];
3487 /* initialize prevgre */
3491 /* search external hash chain for the entry */
3494 if (gre->o == LLNI_DIRECT(o)) {
3495 /* global object found, decrement the reference count */
3499 /* if reference count is 0, remove the entry */
3501 if (gre->refs == 0) {
3502 /* special handling if it's the first in the chain */
3504 if (prevgre == NULL)
3505 hashtable_global_ref->ptr[slot] = gre->hashlink;
3507 prevgre->hashlink = gre->hashlink;
3509 #if defined(ENABLE_GC_CACAO)
3510 /* unregister global ref with the GC */
3512 gc_reference_unregister(&(gre->o));
3515 FREE(gre, hashtable_global_ref_entry);
3520 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3525 prevgre = gre; /* save current pointer for removal */
3526 gre = gre->hashlink; /* next element in external chain */
3529 log_println("JNI-DeleteGlobalRef: global reference not found");
3533 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3537 /* ExceptionCheck **************************************************************
3539 Returns JNI_TRUE when there is a pending exception; otherwise,
3542 *******************************************************************************/
3544 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3548 STATISTICS(jniinvokation());
3550 o = exceptions_get_exception();
3552 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3556 /* New JNI 1.4 functions ******************************************************/
3558 /* NewDirectByteBuffer *********************************************************
3560 Allocates and returns a direct java.nio.ByteBuffer referring to the
3561 block of memory starting at the memory address address and
3562 extending capacity bytes.
3564 *******************************************************************************/
3566 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3568 #if defined(ENABLE_JAVASE)
3569 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3570 java_handle_t *nbuf;
3572 # if SIZEOF_VOID_P == 8
3573 gnu_classpath_Pointer64 *paddress;
3575 gnu_classpath_Pointer32 *paddress;
3578 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3580 /* alocate a gnu.classpath.Pointer{32,64} object */
3582 # if SIZEOF_VOID_P == 8
3583 if (!(paddress = (gnu_classpath_Pointer64 *)
3584 builtin_new(class_gnu_classpath_Pointer64)))
3586 if (!(paddress = (gnu_classpath_Pointer32 *)
3587 builtin_new(class_gnu_classpath_Pointer32)))
3591 /* fill gnu.classpath.Pointer{32,64} with address */
3593 LLNI_field_set_val(paddress, data, (ptrint) address);
3595 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3597 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3598 (jmethodID) dbbirw_init, NULL, paddress,
3599 (jint) capacity, (jint) capacity, (jint) 0);
3601 /* add local reference and return the value */
3603 return jni_NewLocalRef(env, nbuf);
3605 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3611 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3613 /* Be paranoid about address sign-extension. */
3615 addr = (int64_t) ((uintptr_t) address);
3616 cap = (int32_t) capacity;
3618 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3619 (jmethodID) dbb_init, addr, cap);
3621 /* Add local reference and return the value. */
3623 return jni_NewLocalRef(env, o);
3626 # error unknown classpath configuration
3630 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3632 /* keep compiler happy */
3639 /* GetDirectBufferAddress ******************************************************
3641 Fetches and returns the starting address of the memory region
3642 referenced by the given direct java.nio.Buffer.
3644 *******************************************************************************/
3646 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3648 #if defined(ENABLE_JAVASE)
3651 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3653 java_nio_DirectByteBufferImpl *nbuf;
3654 gnu_classpath_Pointer *po;
3655 # if SIZEOF_VOID_P == 8
3656 gnu_classpath_Pointer64 *paddress;
3659 gnu_classpath_Pointer32 *paddress;
3664 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3666 /* Prevent compiler warning. */
3668 h = (java_handle_t *) buf;
3670 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3673 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3675 LLNI_field_get_ref(nbuf, address, po);
3677 # if SIZEOF_VOID_P == 8
3678 paddress = (gnu_classpath_Pointer64 *) po;
3680 paddress = (gnu_classpath_Pointer32 *) po;
3683 if (paddress == NULL)
3686 LLNI_field_get_val(paddress, data, address);
3688 p = (void *) (intptr_t) address;
3692 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3698 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3700 /* Prevent compiler warning. */
3702 h = (java_handle_t *) buf;
3704 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3707 o = (java_nio_Buffer *) buf;
3709 LLNI_field_get_val(o, address, address);
3711 p = (void *) (intptr_t) address;
3716 # error unknown classpath configuration
3721 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3723 /* keep compiler happy */
3731 /* GetDirectBufferCapacity *****************************************************
3733 Fetches and returns the capacity in bytes of the memory region
3734 referenced by the given direct java.nio.Buffer.
3736 *******************************************************************************/
3738 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3740 #if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3742 java_nio_Buffer *nbuf;
3745 STATISTICS(jniinvokation());
3747 o = (java_handle_t *) buf;
3749 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3752 nbuf = (java_nio_Buffer *) o;
3754 LLNI_field_get_val(nbuf, cap, capacity);
3758 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3760 /* keep compiler happy */
3767 /* GetObjectRefType ************************************************************
3769 Returns the type of the object referred to by the obj argument. The
3770 argument obj can either be a local, global or weak global
3773 *******************************************************************************/
3775 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3777 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3783 /* DestroyJavaVM ***************************************************************
3785 Unloads a Java VM and reclaims its resources. Only the main thread
3786 can unload the VM. The system waits until the main thread is only
3787 remaining user thread before it destroys the VM.
3789 *******************************************************************************/
3791 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3795 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3797 if (vm_created == false)
3800 status = vm_destroy(vm);
3806 /* AttachCurrentThread *********************************************************
3808 Attaches the current thread to a Java VM. Returns a JNI interface
3809 pointer in the JNIEnv argument.
3811 Trying to attach a thread that is already attached is a no-op.
3813 A native thread cannot be attached simultaneously to two Java VMs.
3815 When a thread is attached to the VM, the context class loader is
3816 the bootstrap loader.
3818 *******************************************************************************/
3820 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3822 #if defined(ENABLE_THREADS)
3823 JavaVMAttachArgs *vm_aargs;
3826 /* If the current thread has already been attached, this operation
3829 result = thread_current_is_attached();
3831 if (result == true) {
3837 vm_aargs = (JavaVMAttachArgs *) thr_args;
3839 if (vm_aargs != NULL) {
3840 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3841 (vm_aargs->version != JNI_VERSION_1_4))
3842 return JNI_EVERSION;
3845 if (!threads_attach_current_thread(vm_aargs, false))
3848 if (!localref_table_init())
3858 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3862 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3864 if (vm_created == false)
3867 result = jni_attach_current_thread(p_env, thr_args, false);
3873 /* DetachCurrentThread *********************************************************
3875 Detaches the current thread from a Java VM. All Java monitors held
3876 by this thread are released. All Java threads waiting for this
3877 thread to die are notified.
3879 In JDK 1.1, the main thread cannot be detached from the VM. It must
3880 call DestroyJavaVM to unload the entire VM.
3882 In the JDK, the main thread can be detached from the VM.
3884 The main thread, which is the thread that created the Java VM,
3885 cannot be detached from the VM. Instead, the main thread must call
3886 JNI_DestroyJavaVM() to unload the entire VM.
3888 *******************************************************************************/
3890 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3892 #if defined(ENABLE_THREADS)
3896 TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
3898 t = thread_get_current();
3904 /* If the given thread has already been detached, this operation
3907 result = thread_is_attached(t);
3909 if (result == false)
3912 /* We need to pop all frames before we can destroy the table. */
3914 localref_frame_pop_all();
3916 if (!localref_table_destroy())
3919 if (!threads_detach_thread(t))
3927 /* GetEnv **********************************************************************
3929 If the current thread is not attached to the VM, sets *env to NULL,
3930 and returns JNI_EDETACHED. If the specified version is not
3931 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3932 sets *env to the appropriate interface, and returns JNI_OK.
3934 *******************************************************************************/
3936 jint jni_GetEnv(JavaVM *vm, void **env, jint version)
3938 TRACEJNICALLS(("jni_GetEnv(vm=%p, env=%p, version=%d)", vm, env, version));
3940 if (vm_created == false) {
3942 return JNI_EDETACHED;
3945 #if defined(ENABLE_THREADS)
3946 if (thread_get_current() == NULL) {
3949 return JNI_EDETACHED;
3953 /* Check the JNI version. */
3955 if (jni_version_check(version) == true) {
3960 #if defined(ENABLE_JVMTI)
3961 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3962 == JVMTI_VERSION_INTERFACE_JVMTI) {
3964 *env = (void *) jvmti_new_environment();
3973 return JNI_EVERSION;
3977 /* AttachCurrentThreadAsDaemon *************************************************
3979 Same semantics as AttachCurrentThread, but the newly-created
3980 java.lang.Thread instance is a daemon.
3982 If the thread has already been attached via either
3983 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3984 simply sets the value pointed to by penv to the JNIEnv of the
3985 current thread. In this case neither AttachCurrentThread nor this
3986 routine have any effect on the daemon status of the thread.
3988 *******************************************************************************/
3990 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3994 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
3996 if (vm_created == false)
3999 result = jni_attach_current_thread(penv, args, true);
4005 /* JNI invocation table *******************************************************/
4007 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4012 _Jv_JNI_DestroyJavaVM,
4013 _Jv_JNI_AttachCurrentThread,
4014 _Jv_JNI_DetachCurrentThread,
4016 _Jv_JNI_AttachCurrentThreadAsDaemon
4020 /* JNI function table *********************************************************/
4022 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4029 _Jv_JNI_DefineClass,
4031 jni_FromReflectedMethod,
4032 jni_FromReflectedField,
4033 _Jv_JNI_ToReflectedMethod,
4034 _Jv_JNI_GetSuperclass,
4035 _Jv_JNI_IsAssignableFrom,
4036 _Jv_JNI_ToReflectedField,
4040 _Jv_JNI_ExceptionOccurred,
4041 jni_ExceptionDescribe,
4047 _Jv_JNI_NewGlobalRef,
4048 _Jv_JNI_DeleteGlobalRef,
4050 _Jv_JNI_IsSameObject,
4052 jni_EnsureLocalCapacity,
4054 _Jv_JNI_AllocObject,
4059 _Jv_JNI_GetObjectClass,
4060 _Jv_JNI_IsInstanceOf,
4062 _Jv_JNI_GetMethodID,
4064 _Jv_JNI_CallObjectMethod,
4065 _Jv_JNI_CallObjectMethodV,
4066 _Jv_JNI_CallObjectMethodA,
4067 _Jv_JNI_CallBooleanMethod,
4068 _Jv_JNI_CallBooleanMethodV,
4069 _Jv_JNI_CallBooleanMethodA,
4070 _Jv_JNI_CallByteMethod,
4071 _Jv_JNI_CallByteMethodV,
4072 _Jv_JNI_CallByteMethodA,
4073 _Jv_JNI_CallCharMethod,
4074 _Jv_JNI_CallCharMethodV,
4075 _Jv_JNI_CallCharMethodA,
4076 _Jv_JNI_CallShortMethod,
4077 _Jv_JNI_CallShortMethodV,
4078 _Jv_JNI_CallShortMethodA,
4079 _Jv_JNI_CallIntMethod,
4080 _Jv_JNI_CallIntMethodV,
4081 _Jv_JNI_CallIntMethodA,
4082 _Jv_JNI_CallLongMethod,
4083 _Jv_JNI_CallLongMethodV,
4084 _Jv_JNI_CallLongMethodA,
4085 _Jv_JNI_CallFloatMethod,
4086 _Jv_JNI_CallFloatMethodV,
4087 _Jv_JNI_CallFloatMethodA,
4088 _Jv_JNI_CallDoubleMethod,
4089 _Jv_JNI_CallDoubleMethodV,
4090 _Jv_JNI_CallDoubleMethodA,
4091 _Jv_JNI_CallVoidMethod,
4092 _Jv_JNI_CallVoidMethodV,
4093 _Jv_JNI_CallVoidMethodA,
4095 _Jv_JNI_CallNonvirtualObjectMethod,
4096 _Jv_JNI_CallNonvirtualObjectMethodV,
4097 _Jv_JNI_CallNonvirtualObjectMethodA,
4098 _Jv_JNI_CallNonvirtualBooleanMethod,
4099 _Jv_JNI_CallNonvirtualBooleanMethodV,
4100 _Jv_JNI_CallNonvirtualBooleanMethodA,
4101 _Jv_JNI_CallNonvirtualByteMethod,
4102 _Jv_JNI_CallNonvirtualByteMethodV,
4103 _Jv_JNI_CallNonvirtualByteMethodA,
4104 _Jv_JNI_CallNonvirtualCharMethod,
4105 _Jv_JNI_CallNonvirtualCharMethodV,
4106 _Jv_JNI_CallNonvirtualCharMethodA,
4107 _Jv_JNI_CallNonvirtualShortMethod,
4108 _Jv_JNI_CallNonvirtualShortMethodV,
4109 _Jv_JNI_CallNonvirtualShortMethodA,
4110 _Jv_JNI_CallNonvirtualIntMethod,
4111 _Jv_JNI_CallNonvirtualIntMethodV,
4112 _Jv_JNI_CallNonvirtualIntMethodA,
4113 _Jv_JNI_CallNonvirtualLongMethod,
4114 _Jv_JNI_CallNonvirtualLongMethodV,
4115 _Jv_JNI_CallNonvirtualLongMethodA,
4116 _Jv_JNI_CallNonvirtualFloatMethod,
4117 _Jv_JNI_CallNonvirtualFloatMethodV,
4118 _Jv_JNI_CallNonvirtualFloatMethodA,
4119 _Jv_JNI_CallNonvirtualDoubleMethod,
4120 _Jv_JNI_CallNonvirtualDoubleMethodV,
4121 _Jv_JNI_CallNonvirtualDoubleMethodA,
4122 _Jv_JNI_CallNonvirtualVoidMethod,
4123 _Jv_JNI_CallNonvirtualVoidMethodV,
4124 _Jv_JNI_CallNonvirtualVoidMethodA,
4128 _Jv_JNI_GetObjectField,
4129 _Jv_JNI_GetBooleanField,
4130 _Jv_JNI_GetByteField,
4131 _Jv_JNI_GetCharField,
4132 _Jv_JNI_GetShortField,
4133 _Jv_JNI_GetIntField,
4134 _Jv_JNI_GetLongField,
4135 _Jv_JNI_GetFloatField,
4136 _Jv_JNI_GetDoubleField,
4137 _Jv_JNI_SetObjectField,
4138 _Jv_JNI_SetBooleanField,
4139 _Jv_JNI_SetByteField,
4140 _Jv_JNI_SetCharField,
4141 _Jv_JNI_SetShortField,
4142 _Jv_JNI_SetIntField,
4143 _Jv_JNI_SetLongField,
4144 _Jv_JNI_SetFloatField,
4145 _Jv_JNI_SetDoubleField,
4147 _Jv_JNI_GetStaticMethodID,
4149 _Jv_JNI_CallStaticObjectMethod,
4150 _Jv_JNI_CallStaticObjectMethodV,
4151 _Jv_JNI_CallStaticObjectMethodA,
4152 _Jv_JNI_CallStaticBooleanMethod,
4153 _Jv_JNI_CallStaticBooleanMethodV,
4154 _Jv_JNI_CallStaticBooleanMethodA,
4155 _Jv_JNI_CallStaticByteMethod,
4156 _Jv_JNI_CallStaticByteMethodV,
4157 _Jv_JNI_CallStaticByteMethodA,
4158 _Jv_JNI_CallStaticCharMethod,
4159 _Jv_JNI_CallStaticCharMethodV,
4160 _Jv_JNI_CallStaticCharMethodA,
4161 _Jv_JNI_CallStaticShortMethod,
4162 _Jv_JNI_CallStaticShortMethodV,
4163 _Jv_JNI_CallStaticShortMethodA,
4164 _Jv_JNI_CallStaticIntMethod,
4165 _Jv_JNI_CallStaticIntMethodV,
4166 _Jv_JNI_CallStaticIntMethodA,
4167 _Jv_JNI_CallStaticLongMethod,
4168 _Jv_JNI_CallStaticLongMethodV,
4169 _Jv_JNI_CallStaticLongMethodA,
4170 _Jv_JNI_CallStaticFloatMethod,
4171 _Jv_JNI_CallStaticFloatMethodV,
4172 _Jv_JNI_CallStaticFloatMethodA,
4173 _Jv_JNI_CallStaticDoubleMethod,
4174 _Jv_JNI_CallStaticDoubleMethodV,
4175 _Jv_JNI_CallStaticDoubleMethodA,
4176 _Jv_JNI_CallStaticVoidMethod,
4177 _Jv_JNI_CallStaticVoidMethodV,
4178 _Jv_JNI_CallStaticVoidMethodA,
4180 _Jv_JNI_GetStaticFieldID,
4182 _Jv_JNI_GetStaticObjectField,
4183 _Jv_JNI_GetStaticBooleanField,
4184 _Jv_JNI_GetStaticByteField,
4185 _Jv_JNI_GetStaticCharField,
4186 _Jv_JNI_GetStaticShortField,
4187 _Jv_JNI_GetStaticIntField,
4188 _Jv_JNI_GetStaticLongField,
4189 _Jv_JNI_GetStaticFloatField,
4190 _Jv_JNI_GetStaticDoubleField,
4191 _Jv_JNI_SetStaticObjectField,
4192 _Jv_JNI_SetStaticBooleanField,
4193 _Jv_JNI_SetStaticByteField,
4194 _Jv_JNI_SetStaticCharField,
4195 _Jv_JNI_SetStaticShortField,
4196 _Jv_JNI_SetStaticIntField,
4197 _Jv_JNI_SetStaticLongField,
4198 _Jv_JNI_SetStaticFloatField,
4199 _Jv_JNI_SetStaticDoubleField,
4202 _Jv_JNI_GetStringLength,
4203 _Jv_JNI_GetStringChars,
4204 _Jv_JNI_ReleaseStringChars,
4206 _Jv_JNI_NewStringUTF,
4207 _Jv_JNI_GetStringUTFLength,
4208 _Jv_JNI_GetStringUTFChars,
4209 _Jv_JNI_ReleaseStringUTFChars,
4211 _Jv_JNI_GetArrayLength,
4213 _Jv_JNI_NewObjectArray,
4214 _Jv_JNI_GetObjectArrayElement,
4215 _Jv_JNI_SetObjectArrayElement,
4217 _Jv_JNI_NewBooleanArray,
4218 _Jv_JNI_NewByteArray,
4219 _Jv_JNI_NewCharArray,
4220 _Jv_JNI_NewShortArray,
4221 _Jv_JNI_NewIntArray,
4222 _Jv_JNI_NewLongArray,
4223 _Jv_JNI_NewFloatArray,
4224 _Jv_JNI_NewDoubleArray,
4226 _Jv_JNI_GetBooleanArrayElements,
4227 _Jv_JNI_GetByteArrayElements,
4228 _Jv_JNI_GetCharArrayElements,
4229 _Jv_JNI_GetShortArrayElements,
4230 _Jv_JNI_GetIntArrayElements,
4231 _Jv_JNI_GetLongArrayElements,
4232 _Jv_JNI_GetFloatArrayElements,
4233 _Jv_JNI_GetDoubleArrayElements,
4235 _Jv_JNI_ReleaseBooleanArrayElements,
4236 _Jv_JNI_ReleaseByteArrayElements,
4237 _Jv_JNI_ReleaseCharArrayElements,
4238 _Jv_JNI_ReleaseShortArrayElements,
4239 _Jv_JNI_ReleaseIntArrayElements,
4240 _Jv_JNI_ReleaseLongArrayElements,
4241 _Jv_JNI_ReleaseFloatArrayElements,
4242 _Jv_JNI_ReleaseDoubleArrayElements,
4244 _Jv_JNI_GetBooleanArrayRegion,
4245 _Jv_JNI_GetByteArrayRegion,
4246 _Jv_JNI_GetCharArrayRegion,
4247 _Jv_JNI_GetShortArrayRegion,
4248 _Jv_JNI_GetIntArrayRegion,
4249 _Jv_JNI_GetLongArrayRegion,
4250 _Jv_JNI_GetFloatArrayRegion,
4251 _Jv_JNI_GetDoubleArrayRegion,
4252 _Jv_JNI_SetBooleanArrayRegion,
4253 _Jv_JNI_SetByteArrayRegion,
4254 _Jv_JNI_SetCharArrayRegion,
4255 _Jv_JNI_SetShortArrayRegion,
4256 _Jv_JNI_SetIntArrayRegion,
4257 _Jv_JNI_SetLongArrayRegion,
4258 _Jv_JNI_SetFloatArrayRegion,
4259 _Jv_JNI_SetDoubleArrayRegion,
4261 _Jv_JNI_RegisterNatives,
4262 _Jv_JNI_UnregisterNatives,
4264 _Jv_JNI_MonitorEnter,
4265 _Jv_JNI_MonitorExit,
4269 /* New JNI 1.2 functions. */
4271 _Jv_JNI_GetStringRegion,
4272 _Jv_JNI_GetStringUTFRegion,
4274 jni_GetPrimitiveArrayCritical,
4275 jni_ReleasePrimitiveArrayCritical,
4277 _Jv_JNI_GetStringCritical,
4278 _Jv_JNI_ReleaseStringCritical,
4280 _Jv_JNI_NewWeakGlobalRef,
4281 _Jv_JNI_DeleteWeakGlobalRef,
4283 _Jv_JNI_ExceptionCheck,
4285 /* New JNI 1.4 functions. */
4287 _Jv_JNI_NewDirectByteBuffer,
4288 _Jv_JNI_GetDirectBufferAddress,
4289 _Jv_JNI_GetDirectBufferCapacity,
4291 /* New JNI 1.6 functions. */
4293 jni_GetObjectRefType
4297 /* Invocation API Functions ***************************************************/
4299 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4301 Returns a default configuration for the Java VM.
4303 *******************************************************************************/
4305 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4307 JavaVMInitArgs *_vm_args;
4309 _vm_args = (JavaVMInitArgs *) vm_args;
4311 /* GNU classpath currently supports JNI 1.2 */
4313 switch (_vm_args->version) {
4314 case JNI_VERSION_1_1:
4315 _vm_args->version = JNI_VERSION_1_1;
4318 case JNI_VERSION_1_2:
4319 case JNI_VERSION_1_4:
4320 _vm_args->ignoreUnrecognized = JNI_FALSE;
4321 _vm_args->options = NULL;
4322 _vm_args->nOptions = 0;
4333 /* JNI_GetCreatedJavaVMs *******************************************************
4335 Returns all Java VMs that have been created. Pointers to VMs are written in
4336 the buffer vmBuf in the order they are created. At most bufLen number of
4337 entries will be written. The total number of created VMs is returned in
4340 *******************************************************************************/
4342 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4344 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4349 /* We currently only support 1 VM running. */
4351 vmBuf[0] = (JavaVM *) _Jv_jvm;
4358 /* JNI_CreateJavaVM ************************************************************
4360 Loads and initializes a Java VM. The current thread becomes the main thread.
4361 Sets the env argument to the JNI interface pointer of the main thread.
4363 *******************************************************************************/
4365 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4367 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4369 /* actually create the JVM */
4371 if (!vm_createjvm(p_vm, p_env, vm_args))
4379 * These are local overrides for various environment variables in Emacs.
4380 * Please do not remove this and leave it at the end of the file, where
4381 * Emacs will automagically detect them.
4382 * ---------------------------------------------------------------------
4385 * indent-tabs-mode: t
4389 * vim:noexpandtab:sw=4:ts=4: