1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/gc-common.h"
37 #include "mm/memory.h"
39 #include "native/jni.h"
40 #include "native/llni.h"
41 #include "native/localref.h"
42 #include "native/native.h"
44 #if defined(ENABLE_JAVASE)
45 # if defined(WITH_CLASSPATH_GNU)
46 # include "native/include/gnu_classpath_Pointer.h"
48 # if SIZEOF_VOID_P == 8
49 # include "native/include/gnu_classpath_Pointer64.h"
51 # include "native/include/gnu_classpath_Pointer32.h"
56 #include "native/include/java_lang_Object.h"
57 #include "native/include/java_lang_String.h"
58 #include "native/include/java_lang_Throwable.h"
60 #if defined(ENABLE_JAVASE)
61 # if defined(WITH_CLASSPATH_SUN)
62 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
65 # include "native/include/java_lang_ClassLoader.h"
67 # include "native/include/java_lang_reflect_Constructor.h"
68 # include "native/include/java_lang_reflect_Field.h"
69 # include "native/include/java_lang_reflect_Method.h"
71 # include "native/include/java_nio_Buffer.h"
73 # if defined(WITH_CLASSPATH_GNU)
74 # include "native/include/java_nio_DirectByteBufferImpl.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
82 #include "native/vm/java_lang_Class.h"
84 #if defined(ENABLE_JAVASE)
85 # include "native/vm/java_lang_ClassLoader.h"
86 # include "native/vm/reflect.h"
89 #include "threads/lock-common.h"
90 #include "threads/threads-common.h"
92 #include "toolbox/logging.h"
94 #include "vm/builtin.h"
95 #include "vm/exceptions.h"
96 #include "vm/global.h"
97 #include "vm/initialize.h"
98 #include "vm/primitive.h"
99 #include "vm/resolve.h"
100 #include "vm/stringlocal.h"
103 #include "vm/jit/asmpart.h"
104 #include "vm/jit/jit.h"
105 #include "vm/jit/stacktrace.h"
107 #include "vmcore/loader.h"
108 #include "vmcore/options.h"
109 #include "vmcore/statistics.h"
112 /* debug **********************************************************************/
115 # define TRACEJNICALLS(format, ...) \
117 if (opt_TraceJNICalls) { \
118 log_println((format), __VA_ARGS__); \
122 # define TRACEJNICALLS(format, ...)
126 /* global variables ***********************************************************/
128 /* global reference table *****************************************************/
130 /* hashsize must be power of 2 */
132 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
134 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
137 /* direct buffer stuff ********************************************************/
139 #if defined(ENABLE_JAVASE)
140 static classinfo *class_java_nio_Buffer;
142 # if defined(WITH_CLASSPATH_GNU)
144 static classinfo *class_java_nio_DirectByteBufferImpl;
145 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
147 # if SIZEOF_VOID_P == 8
148 static classinfo *class_gnu_classpath_Pointer64;
150 static classinfo *class_gnu_classpath_Pointer32;
153 static methodinfo *dbbirw_init;
155 # elif defined(WITH_CLASSPATH_SUN)
157 static classinfo *class_sun_nio_ch_DirectBuffer;
158 static classinfo *class_java_nio_DirectByteBuffer;
160 static methodinfo *dbb_init;
166 /* accessing instance fields macros *******************************************/
168 #define SET_FIELD(o,type,f,value) \
169 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
171 #define GET_FIELD(o,type,f) \
172 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
175 /* some forward declarations **************************************************/
177 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
178 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
181 /* jni_init ********************************************************************
183 Initialize the JNI subsystem.
185 *******************************************************************************/
189 /* create global ref hashtable */
191 hashtable_global_ref = NEW(hashtable);
193 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
196 #if defined(ENABLE_JAVASE)
197 /* Direct buffer stuff. */
199 if (!(class_java_nio_Buffer =
200 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
201 !link_class(class_java_nio_Buffer))
204 # if defined(WITH_CLASSPATH_GNU)
206 if (!(class_java_nio_DirectByteBufferImpl =
207 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
208 !link_class(class_java_nio_DirectByteBufferImpl))
211 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
212 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
213 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
217 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
219 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
222 # if SIZEOF_VOID_P == 8
223 if (!(class_gnu_classpath_Pointer64 =
224 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
225 !link_class(class_gnu_classpath_Pointer64))
228 if (!(class_gnu_classpath_Pointer32 =
229 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
230 !link_class(class_gnu_classpath_Pointer32))
234 # elif defined(WITH_CLASSPATH_SUN)
236 if (!(class_sun_nio_ch_DirectBuffer =
237 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
238 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
240 if (!link_class(class_sun_nio_ch_DirectBuffer))
241 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
243 if (!(class_java_nio_DirectByteBuffer =
244 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
245 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
247 if (!link_class(class_java_nio_DirectByteBuffer))
248 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
251 class_resolvemethod(class_java_nio_DirectByteBuffer,
253 utf_new_char("(JI)V"))))
254 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
258 #endif /* defined(ENABLE_JAVASE) */
264 /* _Jv_jni_CallObjectMethod ****************************************************
266 Internal function to call Java Object methods.
268 *******************************************************************************/
270 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
272 methodinfo *m, va_list ap)
277 STATISTICS(jniinvokation());
280 exceptions_throw_nullpointerexception();
284 /* Class initialization is done by the JIT compiler. This is ok
285 since a static method always belongs to the declaring class. */
287 if (m->flags & ACC_STATIC) {
288 /* For static methods we reset the object. */
293 /* for convenience */
298 /* For instance methods we make a virtual function table lookup. */
300 resm = method_vftbl_lookup(vftbl, m);
303 STATISTICS(jnicallXmethodnvokation());
305 ro = vm_call_method_valist(resm, o, ap);
311 /* _Jv_jni_CallObjectMethodA ***************************************************
313 Internal function to call Java Object methods.
315 *******************************************************************************/
317 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
325 STATISTICS(jniinvokation());
328 exceptions_throw_nullpointerexception();
332 /* Class initialization is done by the JIT compiler. This is ok
333 since a static method always belongs to the declaring class. */
335 if (m->flags & ACC_STATIC) {
336 /* For static methods we reset the object. */
341 /* for convenience */
346 /* For instance methods we make a virtual function table lookup. */
348 resm = method_vftbl_lookup(vftbl, m);
351 STATISTICS(jnicallXmethodnvokation());
353 ro = vm_call_method_jvalue(resm, o, args);
359 /* _Jv_jni_CallIntMethod *******************************************************
361 Internal function to call Java integer class methods (boolean,
362 byte, char, short, int).
364 *******************************************************************************/
366 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
367 methodinfo *m, va_list ap)
372 STATISTICS(jniinvokation());
375 exceptions_throw_nullpointerexception();
379 /* Class initialization is done by the JIT compiler. This is ok
380 since a static method always belongs to the declaring class. */
382 if (m->flags & ACC_STATIC) {
383 /* For static methods we reset the object. */
388 /* for convenience */
393 /* For instance methods we make a virtual function table lookup. */
395 resm = method_vftbl_lookup(vftbl, m);
398 STATISTICS(jnicallXmethodnvokation());
400 i = vm_call_method_int_valist(resm, o, ap);
406 /* _Jv_jni_CallIntMethodA ******************************************************
408 Internal function to call Java integer class methods (boolean,
409 byte, char, short, int).
411 *******************************************************************************/
413 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
414 methodinfo *m, const jvalue *args)
419 STATISTICS(jniinvokation());
422 exceptions_throw_nullpointerexception();
426 /* Class initialization is done by the JIT compiler. This is ok
427 since a static method always belongs to the declaring class. */
429 if (m->flags & ACC_STATIC) {
430 /* For static methods we reset the object. */
435 /* for convenience */
440 /* For instance methods we make a virtual function table lookup. */
442 resm = method_vftbl_lookup(vftbl, m);
445 STATISTICS(jnicallXmethodnvokation());
447 i = vm_call_method_int_jvalue(resm, o, args);
453 /* _Jv_jni_CallLongMethod ******************************************************
455 Internal function to call Java long methods.
457 *******************************************************************************/
459 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
460 methodinfo *m, va_list ap)
465 STATISTICS(jniinvokation());
468 exceptions_throw_nullpointerexception();
472 /* Class initialization is done by the JIT compiler. This is ok
473 since a static method always belongs to the declaring class. */
475 if (m->flags & ACC_STATIC) {
476 /* For static methods we reset the object. */
481 /* for convenience */
486 /* For instance methods we make a virtual function table lookup. */
488 resm = method_vftbl_lookup(vftbl, m);
491 STATISTICS(jnicallXmethodnvokation());
493 l = vm_call_method_long_valist(resm, o, ap);
499 /* _Jv_jni_CallLongMethodA *****************************************************
501 Internal function to call Java long methods.
503 *******************************************************************************/
505 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
506 methodinfo *m, const jvalue *args)
511 STATISTICS(jniinvokation());
514 exceptions_throw_nullpointerexception();
518 /* Class initialization is done by the JIT compiler. This is ok
519 since a static method always belongs to the declaring class. */
521 if (m->flags & ACC_STATIC) {
522 /* For static methods we reset the object. */
527 /* for convenience */
532 /* For instance methods we make a virtual function table lookup. */
534 resm = method_vftbl_lookup(vftbl, m);
537 STATISTICS(jnicallXmethodnvokation());
539 l = vm_call_method_long_jvalue(resm, o, args);
545 /* _Jv_jni_CallFloatMethod *****************************************************
547 Internal function to call Java float methods.
549 *******************************************************************************/
551 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
552 methodinfo *m, va_list ap)
557 /* Class initialization is done by the JIT compiler. This is ok
558 since a static method always belongs to the declaring class. */
560 if (m->flags & ACC_STATIC) {
561 /* For static methods we reset the object. */
566 /* for convenience */
571 /* For instance methods we make a virtual function table lookup. */
573 resm = method_vftbl_lookup(vftbl, m);
576 STATISTICS(jnicallXmethodnvokation());
578 f = vm_call_method_float_valist(resm, o, ap);
584 /* _Jv_jni_CallFloatMethodA ****************************************************
586 Internal function to call Java float methods.
588 *******************************************************************************/
590 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
591 methodinfo *m, const jvalue *args)
596 /* Class initialization is done by the JIT compiler. This is ok
597 since a static method always belongs to the declaring class. */
599 if (m->flags & ACC_STATIC) {
600 /* For static methods we reset the object. */
605 /* for convenience */
610 /* For instance methods we make a virtual function table lookup. */
612 resm = method_vftbl_lookup(vftbl, m);
615 STATISTICS(jnicallXmethodnvokation());
617 f = vm_call_method_float_jvalue(resm, o, args);
623 /* _Jv_jni_CallDoubleMethod ****************************************************
625 Internal function to call Java double methods.
627 *******************************************************************************/
629 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
630 methodinfo *m, va_list ap)
635 /* Class initialization is done by the JIT compiler. This is ok
636 since a static method always belongs to the declaring class. */
638 if (m->flags & ACC_STATIC) {
639 /* For static methods we reset the object. */
644 /* for convenience */
649 /* For instance methods we make a virtual function table lookup. */
651 resm = method_vftbl_lookup(vftbl, m);
654 d = vm_call_method_double_valist(resm, o, ap);
660 /* _Jv_jni_CallDoubleMethodA ***************************************************
662 Internal function to call Java double methods.
664 *******************************************************************************/
666 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
667 methodinfo *m, const jvalue *args)
672 /* Class initialization is done by the JIT compiler. This is ok
673 since a static method always belongs to the declaring class. */
675 if (m->flags & ACC_STATIC) {
676 /* For static methods we reset the object. */
681 /* for convenience */
686 /* For instance methods we make a virtual function table lookup. */
688 resm = method_vftbl_lookup(vftbl, m);
691 d = vm_call_method_double_jvalue(resm, o, args);
697 /* _Jv_jni_CallVoidMethod ******************************************************
699 Internal function to call Java void methods.
701 *******************************************************************************/
703 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
704 methodinfo *m, va_list ap)
709 exceptions_throw_nullpointerexception();
713 /* Class initialization is done by the JIT compiler. This is ok
714 since a static method always belongs to the declaring class. */
716 if (m->flags & ACC_STATIC) {
717 /* For static methods we reset the object. */
722 /* for convenience */
727 /* For instance methods we make a virtual function table lookup. */
729 resm = method_vftbl_lookup(vftbl, m);
732 STATISTICS(jnicallXmethodnvokation());
734 (void) vm_call_method_valist(resm, o, ap);
738 /* _Jv_jni_CallVoidMethodA *****************************************************
740 Internal function to call Java void methods.
742 *******************************************************************************/
744 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
745 methodinfo *m, const jvalue *args)
750 exceptions_throw_nullpointerexception();
754 /* Class initialization is done by the JIT compiler. This is ok
755 since a static method always belongs to the declaring class. */
757 if (m->flags & ACC_STATIC) {
758 /* For static methods we reset the object. */
763 /* for convenience */
768 /* For instance methods we make a virtual function table lookup. */
770 resm = method_vftbl_lookup(vftbl, m);
773 STATISTICS(jnicallXmethodnvokation());
775 (void) vm_call_method_jvalue(resm, o, args);
779 /* _Jv_jni_invokeNative ********************************************************
781 Invoke a method on the given object with the given arguments.
783 For instance methods OBJ must be != NULL and the method is looked up
784 in the vftbl of the object.
786 For static methods, OBJ is ignored.
788 *******************************************************************************/
790 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
791 java_handle_objectarray_t *params)
803 exceptions_throw_nullpointerexception();
807 argcount = m->parseddesc->paramcount;
808 paramcount = argcount;
810 /* if method is non-static, remove the `this' pointer */
812 if (!(m->flags & ACC_STATIC))
815 /* For instance methods the object has to be an instance of the
816 class the method belongs to. For static methods the obj
817 parameter is ignored. */
819 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
820 exceptions_throw_illegalargumentexception();
824 /* check if we got the right number of arguments */
826 if (((params == NULL) && (paramcount != 0)) ||
827 (params && (LLNI_array_size(params) != paramcount)))
829 exceptions_throw_illegalargumentexception();
833 /* for instance methods we need an object */
835 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
836 /* XXX not sure if that is the correct exception */
837 exceptions_throw_nullpointerexception();
841 /* for static methods, zero object to make subsequent code simpler */
842 if (m->flags & ACC_STATIC)
846 /* for instance methods we must do a vftbl lookup */
847 resm = method_vftbl_lookup(o->vftbl, m);
850 /* for static methods, just for convenience */
854 /* mark start of dump memory area */
856 dumpsize = dump_size();
858 /* Fill the argument array from a object-array. */
860 array = vm_array_from_objectarray(resm, o, params);
862 /* The array can be NULL if we don't have any arguments to pass
863 and the architecture does not have any argument registers
864 (e.g. i386). In that case we additionally check for an
867 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
868 /* release dump area */
870 dump_release(dumpsize);
875 switch (resm->parseddesc->returntype.decltype) {
877 (void) vm_call_array(resm, array);
881 case PRIMITIVETYPE_BOOLEAN:
882 case PRIMITIVETYPE_BYTE:
883 case PRIMITIVETYPE_CHAR:
884 case PRIMITIVETYPE_SHORT:
885 case PRIMITIVETYPE_INT:
886 value.i = vm_call_int_array(resm, array);
887 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
890 case PRIMITIVETYPE_LONG:
891 value.l = vm_call_long_array(resm, array);
892 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
895 case PRIMITIVETYPE_FLOAT:
896 value.f = vm_call_float_array(resm, array);
897 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
900 case PRIMITIVETYPE_DOUBLE:
901 value.d = vm_call_double_array(resm, array);
902 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
906 ro = vm_call_array(resm, array);
910 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
913 xptr = exceptions_get_exception();
916 /* clear exception pointer, we are calling JIT code again */
918 exceptions_clear_exception();
920 exceptions_throw_invocationtargetexception(xptr);
923 /* release dump area */
925 dump_release(dumpsize);
931 /* GetVersion ******************************************************************
933 Returns the major version number in the higher 16 bits and the
934 minor version number in the lower 16 bits.
936 *******************************************************************************/
938 jint _Jv_JNI_GetVersion(JNIEnv *env)
940 TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
942 /* We support JNI 1.6. */
944 return JNI_VERSION_1_6;
948 /* Class Operations ***********************************************************/
950 /* DefineClass *****************************************************************
952 Loads a class from a buffer of raw class data. The buffer
953 containing the raw class data is not referenced by the VM after the
954 DefineClass call returns, and it may be discarded if desired.
956 *******************************************************************************/
958 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
959 const jbyte *buf, jsize bufLen)
961 #if defined(ENABLE_JAVASE)
966 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
968 u = utf_new_char(name);
969 cl = (classloader *) loader;
971 c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
973 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
975 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
977 /* keep compiler happy */
984 /* FindClass *******************************************************************
986 This function loads a locally-defined class. It searches the
987 directories and zip files specified by the CLASSPATH environment
988 variable for the class with the specified name.
990 *******************************************************************************/
992 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
994 #if defined(ENABLE_JAVASE)
999 STATISTICS(jniinvokation());
1001 u = utf_new_char_classname((char *) name);
1003 /* Check stacktrace for classloader, if one found use it,
1004 otherwise use the system classloader. */
1006 /* Quote from the JNI documentation:
1008 In the Java 2 Platform, FindClass locates the class loader
1009 associated with the current native method. If the native code
1010 belongs to a system class, no class loader will be
1011 involved. Otherwise, the proper class loader will be invoked to
1012 load and link the named class. When FindClass is called through
1013 the Invocation Interface, there is no current native method or
1014 its associated class loader. In that case, the result of
1015 ClassLoader.getBaseClassLoader is used." */
1017 cc = stacktrace_getCurrentClass();
1020 c = load_class_from_sysloader(u);
1022 c = load_class_from_classloader(u, cc->classloader);
1030 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1032 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1034 /* keep compiler happy */
1041 /* GetSuperclass ***************************************************************
1043 If clazz represents any class other than the class Object, then
1044 this function returns the object that represents the superclass of
1045 the class specified by clazz.
1047 *******************************************************************************/
1049 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1054 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1056 c = LLNI_classinfo_unwrap(sub);
1061 super = class_get_superclass(c);
1063 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
1067 /* IsAssignableFrom ************************************************************
1069 Determines whether an object of sub can be safely cast to sup.
1071 *******************************************************************************/
1073 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1075 java_lang_Class *csup;
1076 java_lang_Class *csub;
1078 csup = (java_lang_Class *) sup;
1079 csub = (java_lang_Class *) sub;
1081 STATISTICS(jniinvokation());
1083 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1087 /* Throw ***********************************************************************
1089 Causes a java.lang.Throwable object to be thrown.
1091 *******************************************************************************/
1093 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1097 STATISTICS(jniinvokation());
1099 o = (java_handle_t *) obj;
1101 exceptions_set_exception(o);
1107 /* ThrowNew ********************************************************************
1109 Constructs an exception object from the specified class with the
1110 message specified by message and causes that exception to be
1113 *******************************************************************************/
1115 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1121 STATISTICS(jniinvokation());
1123 c = LLNI_classinfo_unwrap(clazz);
1126 s = javastring_new_from_utf_string(msg);
1128 /* instantiate exception object */
1130 o = native_new_and_init_string(c, s);
1135 exceptions_set_exception(o);
1141 /* ExceptionOccurred ***********************************************************
1143 Determines if an exception is being thrown. The exception stays
1144 being thrown until either the native code calls ExceptionClear(),
1145 or the Java code handles the exception.
1147 *******************************************************************************/
1149 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1153 TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1155 o = exceptions_get_exception();
1157 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1161 /* ExceptionDescribe ***********************************************************
1163 Prints an exception and a backtrace of the stack to a system
1164 error-reporting channel, such as stderr. This is a convenience
1165 routine provided for debugging.
1167 *******************************************************************************/
1169 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1174 TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1176 /* Clear exception, because we are probably calling Java code
1179 o = exceptions_get_and_clear_exception();
1182 /* Get printStackTrace method from exception class. */
1184 m = class_resolveclassmethod(o->vftbl->class,
1185 utf_printStackTrace,
1191 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1193 /* Print the stacktrace. */
1195 (void) vm_call_method(m, o);
1200 /* ExceptionClear **************************************************************
1202 Clears any exception that is currently being thrown. If no
1203 exception is currently being thrown, this routine has no effect.
1205 *******************************************************************************/
1207 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1209 STATISTICS(jniinvokation());
1211 exceptions_clear_exception();
1215 /* FatalError ******************************************************************
1217 Raises a fatal error and does not expect the VM to recover. This
1218 function does not return.
1220 *******************************************************************************/
1222 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1224 STATISTICS(jniinvokation());
1226 /* this seems to be the best way */
1228 vm_abort("JNI Fatal error: %s", msg);
1232 /* PushLocalFrame **************************************************************
1234 Creates a new local reference frame, in which at least a given
1235 number of local references can be created.
1237 *******************************************************************************/
1239 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1241 STATISTICS(jniinvokation());
1246 /* add new local reference frame to current table */
1248 if (!localref_frame_push(capacity))
1255 /* PopLocalFrame ***************************************************************
1257 Pops off the current local reference frame, frees all the local
1258 references, and returns a local reference in the previous local
1259 reference frame for the given result object.
1261 *******************************************************************************/
1263 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1265 STATISTICS(jniinvokation());
1267 /* release all current local frames */
1269 localref_frame_pop_all();
1271 /* add local reference and return the value */
1273 return _Jv_JNI_NewLocalRef(env, result);
1277 /* DeleteLocalRef **************************************************************
1279 Deletes the local reference pointed to by localRef.
1281 *******************************************************************************/
1283 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1286 localref_table *lrt;
1289 STATISTICS(jniinvokation());
1291 o = (java_handle_t *) localRef;
1293 /* get local reference table (thread specific) */
1295 lrt = LOCALREFTABLE;
1297 /* go through all local frames */
1299 for (; lrt != NULL; lrt = lrt->prev) {
1301 /* and try to remove the reference */
1303 for (i = 0; i < lrt->capacity; i++) {
1304 if (lrt->refs[i] == o) {
1305 lrt->refs[i] = NULL;
1313 /* this should not happen */
1315 /* if (opt_checkjni) */
1316 /* FatalError(env, "Bad global or local ref passed to JNI"); */
1317 log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1321 /* IsSameObject ****************************************************************
1323 Tests whether two references refer to the same Java object.
1325 *******************************************************************************/
1327 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1329 STATISTICS(jniinvokation());
1338 /* NewLocalRef *****************************************************************
1340 Creates a new local reference that refers to the same object as ref.
1342 *******************************************************************************/
1344 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1346 localref_table *lrt;
1349 STATISTICS(jniinvokation());
1354 /* get local reference table (thread specific) */
1356 lrt = LOCALREFTABLE;
1358 /* Check if we have space for the requested reference? No,
1359 allocate a new frame. This is actually not what the spec says,
1360 but for compatibility reasons... */
1362 if (lrt->used == lrt->capacity) {
1363 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1366 /* get the new local reference table */
1368 lrt = LOCALREFTABLE;
1371 /* insert the reference */
1373 for (i = 0; i < lrt->capacity; i++) {
1374 if (lrt->refs[i] == NULL) {
1375 lrt->refs[i] = (java_handle_t *) ref;
1382 /* should not happen, just to be sure */
1386 /* keep compiler happy */
1392 /* EnsureLocalCapacity *********************************************************
1394 Ensures that at least a given number of local references can be
1395 created in the current thread
1397 *******************************************************************************/
1399 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1401 localref_table *lrt;
1403 STATISTICS(jniinvokation());
1405 /* get local reference table (thread specific) */
1407 lrt = LOCALREFTABLE;
1409 /* check if capacity elements are available in the local references table */
1411 if ((lrt->used + capacity) > lrt->capacity)
1412 return _Jv_JNI_PushLocalFrame(env, capacity);
1418 /* AllocObject *****************************************************************
1420 Allocates a new Java object without invoking any of the
1421 constructors for the object. Returns a reference to the object.
1423 *******************************************************************************/
1425 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1430 STATISTICS(jniinvokation());
1432 c = LLNI_classinfo_unwrap(clazz);
1434 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1435 exceptions_throw_instantiationexception(c);
1441 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1445 /* NewObject *******************************************************************
1447 Programmers place all arguments that are to be passed to the
1448 constructor immediately following the methodID
1449 argument. NewObject() accepts these arguments and passes them to
1450 the Java method that the programmer wishes to invoke.
1452 *******************************************************************************/
1454 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1461 STATISTICS(jniinvokation());
1463 c = LLNI_classinfo_unwrap(clazz);
1464 m = (methodinfo *) methodID;
1473 /* call constructor */
1475 va_start(ap, methodID);
1476 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1479 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1483 /* NewObjectV ******************************************************************
1485 Programmers place all arguments that are to be passed to the
1486 constructor in an args argument of type va_list that immediately
1487 follows the methodID argument. NewObjectV() accepts these
1488 arguments, and, in turn, passes them to the Java method that the
1489 programmer wishes to invoke.
1491 *******************************************************************************/
1493 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1500 STATISTICS(jniinvokation());
1502 c = LLNI_classinfo_unwrap(clazz);
1503 m = (methodinfo *) methodID;
1512 /* call constructor */
1514 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1516 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1520 /* NewObjectA *****************************************************************
1522 Programmers place all arguments that are to be passed to the
1523 constructor in an args array of jvalues that immediately follows
1524 the methodID argument. NewObjectA() accepts the arguments in this
1525 array, and, in turn, passes them to the Java method that the
1526 programmer wishes to invoke.
1528 *******************************************************************************/
1530 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1537 STATISTICS(jniinvokation());
1539 c = LLNI_classinfo_unwrap(clazz);
1540 m = (methodinfo *) methodID;
1549 /* call constructor */
1551 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1553 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1557 /* GetObjectClass **************************************************************
1559 Returns the class of an object.
1561 *******************************************************************************/
1563 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1568 STATISTICS(jniinvokation());
1570 o = (java_handle_t *) obj;
1572 if ((o == NULL) || (o->vftbl == NULL))
1575 c = o->vftbl->class;
1577 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1581 /* IsInstanceOf ****************************************************************
1583 Tests whether an object is an instance of a class.
1585 *******************************************************************************/
1587 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1590 java_lang_Object *o;
1592 STATISTICS(jniinvokation());
1594 c = (java_lang_Class *) clazz;
1595 o = (java_lang_Object *) obj;
1597 return _Jv_java_lang_Class_isInstance(c, o);
1601 /* Reflection Support *********************************************************/
1603 /* FromReflectedMethod *********************************************************
1605 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1606 object to a method ID.
1608 *******************************************************************************/
1610 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1612 #if defined(ENABLE_JAVASE)
1618 STATISTICS(jniinvokation());
1620 o = (java_handle_t *) method;
1625 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1626 java_lang_reflect_Method *rm;
1628 rm = (java_lang_reflect_Method *) method;
1629 LLNI_field_get_cls(rm, clazz, c);
1630 LLNI_field_get_val(rm, slot , slot);
1632 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1633 java_lang_reflect_Constructor *rc;
1635 rc = (java_lang_reflect_Constructor *) method;
1636 LLNI_field_get_cls(rc, clazz, c);
1637 LLNI_field_get_val(rc, slot , slot);
1642 m = &(c->methods[slot]);
1644 return (jmethodID) m;
1646 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1648 /* keep compiler happy */
1655 /* FromReflectedField **********************************************************
1657 Converts a java.lang.reflect.Field to a field ID.
1659 *******************************************************************************/
1661 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1663 #if defined(ENABLE_JAVASE)
1664 java_lang_reflect_Field *rf;
1669 STATISTICS(jniinvokation());
1671 rf = (java_lang_reflect_Field *) field;
1676 LLNI_field_get_cls(rf, clazz, c);
1677 LLNI_field_get_val(rf, slot , slot);
1678 f = &(c->fields[slot]);
1680 return (jfieldID) f;
1682 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1684 /* keep compiler happy */
1691 /* ToReflectedMethod ***********************************************************
1693 Converts a method ID derived from cls to an instance of the
1694 java.lang.reflect.Method class or to an instance of the
1695 java.lang.reflect.Constructor class.
1697 *******************************************************************************/
1699 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1702 #if defined(ENABLE_JAVASE)
1704 java_lang_reflect_Constructor *rc;
1705 java_lang_reflect_Method *rm;
1707 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1709 m = (methodinfo *) methodID;
1711 /* HotSpot does the same assert. */
1713 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1715 if (m->name == utf_init) {
1716 rc = reflect_constructor_new(m);
1718 return (jobject) rc;
1721 rm = reflect_method_new(m);
1723 return (jobject) rm;
1726 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1728 /* keep compiler happy */
1735 /* ToReflectedField ************************************************************
1737 Converts a field ID derived from cls to an instance of the
1738 java.lang.reflect.Field class.
1740 *******************************************************************************/
1742 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1745 STATISTICS(jniinvokation());
1747 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1753 /* Calling Instance Methods ***************************************************/
1755 /* GetMethodID *****************************************************************
1757 Returns the method ID for an instance (nonstatic) method of a class
1758 or interface. The method may be defined in one of the clazz's
1759 superclasses and inherited by clazz. The method is determined by
1760 its name and signature.
1762 GetMethodID() causes an uninitialized class to be initialized.
1764 *******************************************************************************/
1766 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1774 STATISTICS(jniinvokation());
1776 c = LLNI_classinfo_unwrap(clazz);
1781 if (!(c->state & CLASS_INITIALIZED))
1782 if (!initialize_class(c))
1785 /* try to get the method of the class or one of it's superclasses */
1787 uname = utf_new_char((char *) name);
1788 udesc = utf_new_char((char *) sig);
1790 m = class_resolvemethod(c, uname, udesc);
1792 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1793 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1798 return (jmethodID) m;
1802 /* JNI-functions for calling instance methods *********************************/
1804 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1805 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1806 jmethodID methodID, ...) \
1813 o = (java_handle_t *) obj; \
1814 m = (methodinfo *) methodID; \
1816 va_start(ap, methodID); \
1817 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
1823 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1824 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1825 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1826 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1827 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1828 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1829 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1830 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1833 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1834 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1835 jmethodID methodID, va_list args) \
1841 o = (java_handle_t *) obj; \
1842 m = (methodinfo *) methodID; \
1844 ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args); \
1849 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1850 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1851 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1852 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1853 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1854 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1855 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1856 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1859 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1860 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1861 jmethodID methodID, \
1862 const jvalue *args) \
1868 o = (java_handle_t *) obj; \
1869 m = (methodinfo *) methodID; \
1871 ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
1876 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1877 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1878 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1879 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1880 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1881 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1882 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1883 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1886 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1894 o = (java_handle_t *) obj;
1895 m = (methodinfo *) methodID;
1897 va_start(ap, methodID);
1898 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1901 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1905 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1912 o = (java_handle_t *) obj;
1913 m = (methodinfo *) methodID;
1915 ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1917 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1921 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1928 o = (java_handle_t *) obj;
1929 m = (methodinfo *) methodID;
1931 ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1933 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1938 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1944 o = (java_handle_t *) obj;
1945 m = (methodinfo *) methodID;
1947 va_start(ap, methodID);
1948 _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1953 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1959 o = (java_handle_t *) obj;
1960 m = (methodinfo *) methodID;
1962 _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1966 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1972 o = (java_handle_t *) obj;
1973 m = (methodinfo *) methodID;
1975 _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1980 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1981 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1982 jclass clazz, jmethodID methodID, \
1991 o = (java_handle_t *) obj; \
1992 c = LLNI_classinfo_unwrap(clazz); \
1993 m = (methodinfo *) methodID; \
1995 va_start(ap, methodID); \
1996 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
2002 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
2003 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
2004 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
2005 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
2006 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
2008 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
2009 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
2012 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
2013 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
2014 jclass clazz, jmethodID methodID, \
2022 o = (java_handle_t *) obj; \
2023 c = LLNI_classinfo_unwrap(clazz); \
2024 m = (methodinfo *) methodID; \
2026 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2031 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2032 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2033 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2034 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2035 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2036 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2037 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2038 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2041 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2042 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2043 jclass clazz, jmethodID methodID, \
2044 const jvalue *args) \
2046 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2051 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2052 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2053 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2054 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2055 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2056 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2057 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2058 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2060 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2061 jclass clazz, jmethodID methodID,
2070 o = (java_handle_t *) obj;
2071 c = LLNI_classinfo_unwrap(clazz);
2072 m = (methodinfo *) methodID;
2074 va_start(ap, methodID);
2075 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2078 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2082 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2083 jclass clazz, jmethodID methodID,
2091 o = (java_handle_t *) obj;
2092 c = LLNI_classinfo_unwrap(clazz);
2093 m = (methodinfo *) methodID;
2095 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2097 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2101 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2102 jclass clazz, jmethodID methodID,
2105 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2107 return _Jv_JNI_NewLocalRef(env, NULL);
2111 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2112 jmethodID methodID, ...)
2119 o = (java_handle_t *) obj;
2120 c = LLNI_classinfo_unwrap(clazz);
2121 m = (methodinfo *) methodID;
2123 va_start(ap, methodID);
2124 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2129 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2130 jmethodID methodID, va_list args)
2136 o = (java_handle_t *) obj;
2137 c = LLNI_classinfo_unwrap(clazz);
2138 m = (methodinfo *) methodID;
2140 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2144 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2145 jmethodID methodID, const jvalue * args)
2151 o = (java_handle_t *) obj;
2152 c = LLNI_classinfo_unwrap(clazz);
2153 m = (methodinfo *) methodID;
2155 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2159 /* Accessing Fields of Objects ************************************************/
2161 /* GetFieldID ******************************************************************
2163 Returns the field ID for an instance (nonstatic) field of a
2164 class. The field is specified by its name and signature. The
2165 Get<type>Field and Set<type>Field families of accessor functions
2166 use field IDs to retrieve object fields.
2168 *******************************************************************************/
2170 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2178 STATISTICS(jniinvokation());
2180 c = LLNI_classinfo_unwrap(clazz);
2182 /* XXX NPE check? */
2184 uname = utf_new_char((char *) name);
2185 udesc = utf_new_char((char *) sig);
2187 f = class_findfield(c, uname, udesc);
2190 exceptions_throw_nosuchfielderror(c, uname);
2192 return (jfieldID) f;
2196 /* Get<type>Field Routines *****************************************************
2198 This family of accessor routines returns the value of an instance
2199 (nonstatic) field of an object. The field to access is specified by
2200 a field ID obtained by calling GetFieldID().
2202 *******************************************************************************/
2204 #define JNI_GET_FIELD(name, type, intern) \
2205 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2209 STATISTICS(jniinvokation()); \
2211 ret = GET_FIELD(obj, intern, fieldID); \
2213 return (type) ret; \
2216 JNI_GET_FIELD(Boolean, jboolean, s4)
2217 JNI_GET_FIELD(Byte, jbyte, s4)
2218 JNI_GET_FIELD(Char, jchar, s4)
2219 JNI_GET_FIELD(Short, jshort, s4)
2220 JNI_GET_FIELD(Int, jint, s4)
2221 JNI_GET_FIELD(Long, jlong, s8)
2222 JNI_GET_FIELD(Float, jfloat, float)
2223 JNI_GET_FIELD(Double, jdouble, double)
2226 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2230 STATISTICS(jniinvokation());
2232 #warning this needs to be fixed
2233 o = GET_FIELD(obj, java_handle_t*, fieldID);
2235 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2239 /* Set<type>Field Routines *****************************************************
2241 This family of accessor routines sets the value of an instance
2242 (nonstatic) field of an object. The field to access is specified by
2243 a field ID obtained by calling GetFieldID().
2245 *******************************************************************************/
2247 #define JNI_SET_FIELD(name, type, intern) \
2248 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2251 STATISTICS(jniinvokation()); \
2253 SET_FIELD(obj, intern, fieldID, value); \
2256 JNI_SET_FIELD(Boolean, jboolean, s4)
2257 JNI_SET_FIELD(Byte, jbyte, s4)
2258 JNI_SET_FIELD(Char, jchar, s4)
2259 JNI_SET_FIELD(Short, jshort, s4)
2260 JNI_SET_FIELD(Int, jint, s4)
2261 JNI_SET_FIELD(Long, jlong, s8)
2262 JNI_SET_FIELD(Float, jfloat, float)
2263 JNI_SET_FIELD(Double, jdouble, double)
2266 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2269 STATISTICS(jniinvokation());
2271 #warning this needs to be fixed
2272 SET_FIELD(obj, java_handle_t*, fieldID, value);
2276 /* Calling Static Methods *****************************************************/
2278 /* GetStaticMethodID ***********************************************************
2280 Returns the method ID for a static method of a class. The method is
2281 specified by its name and signature.
2283 GetStaticMethodID() causes an uninitialized class to be
2286 *******************************************************************************/
2288 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2296 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2298 c = LLNI_classinfo_unwrap(clazz);
2303 if (!(c->state & CLASS_INITIALIZED))
2304 if (!initialize_class(c))
2307 /* try to get the static method of the class */
2309 uname = utf_new_char((char *) name);
2310 udesc = utf_new_char((char *) sig);
2312 m = class_resolvemethod(c, uname, udesc);
2314 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2315 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2320 return (jmethodID) m;
2324 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2325 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2326 jmethodID methodID, ...) \
2332 m = (methodinfo *) methodID; \
2334 va_start(ap, methodID); \
2335 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2341 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2342 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2343 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2344 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2345 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2346 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2347 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2348 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2351 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2352 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2353 jmethodID methodID, va_list args) \
2358 m = (methodinfo *) methodID; \
2360 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2365 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2366 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2367 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2368 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2369 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2370 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2371 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2372 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2375 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2376 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2377 jmethodID methodID, const jvalue *args) \
2382 m = (methodinfo *) methodID; \
2384 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2389 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2390 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2391 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2392 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2393 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2394 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2395 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2396 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2399 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2400 jmethodID methodID, ...)
2406 m = (methodinfo *) methodID;
2408 va_start(ap, methodID);
2409 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2412 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2416 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2417 jmethodID methodID, va_list args)
2422 m = (methodinfo *) methodID;
2424 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2426 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2430 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2431 jmethodID methodID, const jvalue *args)
2436 m = (methodinfo *) methodID;
2438 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2440 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2444 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2445 jmethodID methodID, ...)
2450 m = (methodinfo *) methodID;
2452 va_start(ap, methodID);
2453 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2458 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2459 jmethodID methodID, va_list args)
2463 m = (methodinfo *) methodID;
2465 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2469 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2470 jmethodID methodID, const jvalue * args)
2474 m = (methodinfo *) methodID;
2476 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2480 /* Accessing Static Fields ****************************************************/
2482 /* GetStaticFieldID ************************************************************
2484 Returns the field ID for a static field of a class. The field is
2485 specified by its name and signature. The GetStatic<type>Field and
2486 SetStatic<type>Field families of accessor functions use field IDs
2487 to retrieve static fields.
2489 *******************************************************************************/
2491 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2499 STATISTICS(jniinvokation());
2501 c = LLNI_classinfo_unwrap(clazz);
2503 uname = utf_new_char((char *) name);
2504 usig = utf_new_char((char *) sig);
2506 f = class_findfield(c, uname, usig);
2509 exceptions_throw_nosuchfielderror(c, uname);
2511 return (jfieldID) f;
2515 /* GetStatic<type>Field ********************************************************
2517 This family of accessor routines returns the value of a static
2520 *******************************************************************************/
2522 #define JNI_GET_STATIC_FIELD(name, type, field) \
2523 type _Jv_JNI_GetStatic##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 return f->value->field; \
2541 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2542 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2543 JNI_GET_STATIC_FIELD(Char, jchar, i)
2544 JNI_GET_STATIC_FIELD(Short, jshort, i)
2545 JNI_GET_STATIC_FIELD(Int, jint, i)
2546 JNI_GET_STATIC_FIELD(Long, jlong, l)
2547 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2548 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2551 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
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 return _Jv_JNI_NewLocalRef(env, f->value->a);
2570 /* SetStatic<type>Field *******************************************************
2572 This family of accessor routines sets the value of a static field
2575 *******************************************************************************/
2577 #define JNI_SET_STATIC_FIELD(name, type, field) \
2578 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2585 STATISTICS(jniinvokation()); \
2587 c = LLNI_classinfo_unwrap(clazz); \
2588 f = (fieldinfo *) fieldID; \
2590 if (!(c->state & CLASS_INITIALIZED)) \
2591 if (!initialize_class(c)) \
2594 f->value->field = value; \
2597 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2598 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2599 JNI_SET_STATIC_FIELD(Char, jchar, i)
2600 JNI_SET_STATIC_FIELD(Short, jshort, i)
2601 JNI_SET_STATIC_FIELD(Int, jint, i)
2602 JNI_SET_STATIC_FIELD(Long, jlong, l)
2603 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2604 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2607 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2613 STATISTICS(jniinvokation());
2615 c = LLNI_classinfo_unwrap(clazz);
2616 f = (fieldinfo *) fieldID;
2618 if (!(c->state & CLASS_INITIALIZED))
2619 if (!initialize_class(c))
2622 f->value->a = value;
2626 /* String Operations **********************************************************/
2628 /* NewString *******************************************************************
2630 Create new java.lang.String object from an array of Unicode
2633 *******************************************************************************/
2635 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2637 java_lang_String *s;
2638 java_handle_chararray_t *a;
2641 STATISTICS(jniinvokation());
2643 s = (java_lang_String *) builtin_new(class_java_lang_String);
2644 a = builtin_newarray_char(len);
2646 /* javastring or characterarray could not be created */
2647 if ((a == NULL) || (s == NULL))
2651 for (i = 0; i < len; i++)
2652 LLNI_array_direct(a, i) = buf[i];
2654 LLNI_field_set_ref(s, value , a);
2655 LLNI_field_set_val(s, offset, 0);
2656 LLNI_field_set_val(s, count , len);
2658 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2662 static jchar emptyStringJ[]={0,0};
2664 /* GetStringLength *************************************************************
2666 Returns the length (the count of Unicode characters) of a Java
2669 *******************************************************************************/
2671 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2673 java_lang_String *s;
2676 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2678 s = (java_lang_String *) str;
2680 LLNI_field_get_val(s, count, len);
2686 /******************** convertes javastring to u2-array ****************************/
2688 u2 *javastring_tou2(jstring so)
2690 java_lang_String *s;
2691 java_handle_chararray_t *a;
2697 STATISTICS(jniinvokation());
2699 s = (java_lang_String *) so;
2704 LLNI_field_get_ref(s, value, a);
2709 LLNI_field_get_val(s, count, count);
2710 LLNI_field_get_val(s, offset, offset);
2712 /* allocate memory */
2714 stringbuffer = MNEW(u2, count + 1);
2718 for (i = 0; i < count; i++)
2719 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2721 /* terminate string */
2723 stringbuffer[i] = '\0';
2725 return stringbuffer;
2729 /* GetStringChars **************************************************************
2731 Returns a pointer to the array of Unicode characters of the
2732 string. This pointer is valid until ReleaseStringChars() is called.
2734 *******************************************************************************/
2736 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2740 STATISTICS(jniinvokation());
2742 jc = javastring_tou2(str);
2754 return emptyStringJ;
2758 /* ReleaseStringChars **********************************************************
2760 Informs the VM that the native code no longer needs access to
2761 chars. The chars argument is a pointer obtained from string using
2764 *******************************************************************************/
2766 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2768 java_lang_String *s;
2770 STATISTICS(jniinvokation());
2772 if (chars == emptyStringJ)
2775 s = (java_lang_String *) str;
2777 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2781 /* NewStringUTF ****************************************************************
2783 Constructs a new java.lang.String object from an array of UTF-8
2786 *******************************************************************************/
2788 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2790 java_lang_String *s;
2792 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2794 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2796 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2800 /****************** returns the utf8 length in bytes of a string *******************/
2802 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2804 java_lang_String *s;
2807 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2809 s = (java_lang_String *) string;
2811 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2817 /* GetStringUTFChars ***********************************************************
2819 Returns a pointer to an array of UTF-8 characters of the
2820 string. This array is valid until it is released by
2821 ReleaseStringUTFChars().
2823 *******************************************************************************/
2825 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2830 STATISTICS(jniinvokation());
2838 u = javastring_toutf((java_handle_t *) string, false);
2847 /* ReleaseStringUTFChars *******************************************************
2849 Informs the VM that the native code no longer needs access to
2850 utf. The utf argument is a pointer derived from string using
2851 GetStringUTFChars().
2853 *******************************************************************************/
2855 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2857 STATISTICS(jniinvokation());
2859 /* XXX we don't release utf chars right now, perhaps that should be done
2860 later. Since there is always one reference the garbage collector will
2865 /* Array Operations ***********************************************************/
2867 /* GetArrayLength **************************************************************
2869 Returns the number of elements in the array.
2871 *******************************************************************************/
2873 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2878 STATISTICS(jniinvokation());
2880 a = (java_handle_t *) array;
2882 size = LLNI_array_size(a);
2888 /* NewObjectArray **************************************************************
2890 Constructs a new array holding objects in class elementClass. All
2891 elements are initially set to initialElement.
2893 *******************************************************************************/
2895 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2896 jclass elementClass, jobject initialElement)
2900 java_handle_objectarray_t *oa;
2903 STATISTICS(jniinvokation());
2905 c = LLNI_classinfo_unwrap(elementClass);
2906 o = (java_handle_t *) initialElement;
2909 exceptions_throw_negativearraysizeexception();
2913 oa = builtin_anewarray(length, c);
2918 /* set all elements to initialElement */
2920 for (i = 0; i < length; i++)
2921 LLNI_objectarray_element_set(oa, i, o);
2923 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2927 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2930 java_handle_objectarray_t *oa;
2933 STATISTICS(jniinvokation());
2935 oa = (java_handle_objectarray_t *) array;
2937 if (index >= LLNI_array_size(oa)) {
2938 exceptions_throw_arrayindexoutofboundsexception();
2942 LLNI_objectarray_element_get(oa, index, o);
2944 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2948 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2949 jsize index, jobject val)
2951 java_handle_objectarray_t *oa;
2954 STATISTICS(jniinvokation());
2956 oa = (java_handle_objectarray_t *) array;
2957 o = (java_handle_t *) val;
2959 if (index >= LLNI_array_size(oa)) {
2960 exceptions_throw_arrayindexoutofboundsexception();
2964 /* check if the class of value is a subclass of the element class
2967 if (!builtin_canstore(oa, o))
2970 LLNI_objectarray_element_set(oa, index, o);
2974 #define JNI_NEW_ARRAY(name, type, intern) \
2975 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2977 java_handle_##intern##array_t *a; \
2979 STATISTICS(jniinvokation()); \
2982 exceptions_throw_negativearraysizeexception(); \
2986 a = builtin_newarray_##intern(len); \
2988 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2991 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2992 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2993 JNI_NEW_ARRAY(Char, jcharArray, char)
2994 JNI_NEW_ARRAY(Short, jshortArray, byte)
2995 JNI_NEW_ARRAY(Int, jintArray, int)
2996 JNI_NEW_ARRAY(Long, jlongArray, long)
2997 JNI_NEW_ARRAY(Float, jfloatArray, float)
2998 JNI_NEW_ARRAY(Double, jdoubleArray, double)
3001 /* Get<PrimitiveType>ArrayElements *********************************************
3003 A family of functions that returns the body of the primitive array.
3005 *******************************************************************************/
3007 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
3008 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
3011 java_handle_##intern##array_t *a; \
3013 STATISTICS(jniinvokation()); \
3015 a = (java_handle_##intern##array_t *) array; \
3018 *isCopy = JNI_FALSE; \
3020 return LLNI_array_data(a); \
3023 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3024 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3025 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3026 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3027 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3028 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3029 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3030 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3033 /* Release<PrimitiveType>ArrayElements *****************************************
3035 A family of functions that informs the VM that the native code no
3036 longer needs access to elems. The elems argument is a pointer
3037 derived from array using the corresponding
3038 Get<PrimitiveType>ArrayElements() function. If necessary, this
3039 function copies back all changes made to elems to the original
3042 *******************************************************************************/
3044 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3045 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3046 type *elems, jint mode) \
3048 java_handle_##intern##array_t *a; \
3050 STATISTICS(jniinvokation()); \
3052 a = (java_handle_##intern##array_t *) array; \
3054 if (elems != LLNI_array_data(a)) { \
3057 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3060 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3061 /* XXX TWISTI how should it be freed? */ \
3064 /* XXX TWISTI how should it be freed? */ \
3070 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3071 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3072 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3073 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3074 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3075 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3076 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3077 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3080 /* Get<PrimitiveType>ArrayRegion **********************************************
3082 A family of functions that copies a region of a primitive array
3085 *******************************************************************************/
3087 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3088 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3089 jsize start, jsize len, type *buf) \
3091 java_handle_##intern##array_t *a; \
3093 STATISTICS(jniinvokation()); \
3095 a = (java_handle_##intern##array_t *) array; \
3097 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3098 exceptions_throw_arrayindexoutofboundsexception(); \
3100 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3103 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3104 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3105 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3106 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3107 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3108 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3109 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3110 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3113 /* Set<PrimitiveType>ArrayRegion **********************************************
3115 A family of functions that copies back a region of a primitive
3116 array from a buffer.
3118 *******************************************************************************/
3120 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3121 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3122 jsize start, jsize len, const type *buf) \
3124 java_handle_##intern##array_t *a; \
3126 STATISTICS(jniinvokation()); \
3128 a = (java_handle_##intern##array_t *) array; \
3130 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3131 exceptions_throw_arrayindexoutofboundsexception(); \
3133 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3136 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3137 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3138 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3139 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3140 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3141 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3142 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3143 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3146 /* Registering Native Methods *************************************************/
3148 /* RegisterNatives *************************************************************
3150 Registers native methods with the class specified by the clazz
3151 argument. The methods parameter specifies an array of
3152 JNINativeMethod structures that contain the names, signatures, and
3153 function pointers of the native methods. The nMethods parameter
3154 specifies the number of native methods in the array.
3156 *******************************************************************************/
3158 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3159 const JNINativeMethod *methods, jint nMethods)
3163 STATISTICS(jniinvokation());
3165 c = LLNI_classinfo_unwrap(clazz);
3167 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3168 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3171 native_method_register(c->name, methods, nMethods);
3177 /* UnregisterNatives ***********************************************************
3179 Unregisters native methods of a class. The class goes back to the
3180 state before it was linked or registered with its native method
3183 This function should not be used in normal native code. Instead, it
3184 provides special programs a way to reload and relink native
3187 *******************************************************************************/
3189 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3191 STATISTICS(jniinvokation());
3193 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3195 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3201 /* Monitor Operations *********************************************************/
3203 /* MonitorEnter ****************************************************************
3205 Enters the monitor associated with the underlying Java object
3208 *******************************************************************************/
3210 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3212 STATISTICS(jniinvokation());
3215 exceptions_throw_nullpointerexception();
3219 LOCK_MONITOR_ENTER(obj);
3225 /* MonitorExit *****************************************************************
3227 The current thread must be the owner of the monitor associated with
3228 the underlying Java object referred to by obj. The thread
3229 decrements the counter indicating the number of times it has
3230 entered this monitor. If the value of the counter becomes zero, the
3231 current thread releases the monitor.
3233 *******************************************************************************/
3235 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3237 STATISTICS(jniinvokation());
3240 exceptions_throw_nullpointerexception();
3244 LOCK_MONITOR_EXIT(obj);
3250 /* JavaVM Interface ***********************************************************/
3252 /* GetJavaVM *******************************************************************
3254 Returns the Java VM interface (used in the Invocation API)
3255 associated with the current thread. The result is placed at the
3256 location pointed to by the second argument, vm.
3258 *******************************************************************************/
3260 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3262 STATISTICS(jniinvokation());
3264 *vm = (JavaVM *) _Jv_jvm;
3270 /* GetStringRegion *************************************************************
3272 Copies len number of Unicode characters beginning at offset start
3273 to the given buffer buf.
3275 Throws StringIndexOutOfBoundsException on index overflow.
3277 *******************************************************************************/
3279 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3282 java_lang_String *s;
3283 java_handle_chararray_t *ca;
3285 STATISTICS(jniinvokation());
3287 s = (java_lang_String *) str;
3288 LLNI_field_get_ref(s, value, ca);
3290 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3291 (start + len > LLNI_field_direct(s, count))) {
3292 exceptions_throw_stringindexoutofboundsexception();
3296 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3300 /* GetStringUTFRegion **********************************************************
3302 Translates len number of Unicode characters beginning at offset
3303 start into UTF-8 format and place the result in the given buffer
3306 Throws StringIndexOutOfBoundsException on index overflow.
3308 *******************************************************************************/
3310 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3311 jsize len, char *buf)
3313 java_lang_String *s;
3314 java_handle_chararray_t *ca;
3319 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3321 s = (java_lang_String *) str;
3322 LLNI_field_get_ref(s, value, ca);
3323 LLNI_field_get_val(s, count, count);
3324 LLNI_field_get_val(s, offset, offset);
3326 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3327 exceptions_throw_stringindexoutofboundsexception();
3331 for (i = 0; i < len; i++)
3332 buf[i] = LLNI_array_direct(ca, offset + start + i);
3338 /* GetPrimitiveArrayCritical ***************************************************
3340 Obtain a direct pointer to array elements.
3342 *******************************************************************************/
3344 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3347 java_handle_bytearray_t *ba;
3350 ba = (java_handle_bytearray_t *) array;
3352 /* do the same as Kaffe does */
3354 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3360 /* ReleasePrimitiveArrayCritical ***********************************************
3362 No specific documentation.
3364 *******************************************************************************/
3366 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3367 void *carray, jint mode)
3369 STATISTICS(jniinvokation());
3371 /* do the same as Kaffe does */
3373 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3378 /* GetStringCritical ***********************************************************
3380 The semantics of these two functions are similar to the existing
3381 Get/ReleaseStringChars functions.
3383 *******************************************************************************/
3385 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3388 STATISTICS(jniinvokation());
3390 return _Jv_JNI_GetStringChars(env, string, isCopy);
3394 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3395 const jchar *cstring)
3397 STATISTICS(jniinvokation());
3399 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3403 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3405 STATISTICS(jniinvokation());
3407 log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3413 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3415 STATISTICS(jniinvokation());
3417 log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3421 /* NewGlobalRef ****************************************************************
3423 Creates a new global reference to the object referred to by the obj
3426 *******************************************************************************/
3428 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3430 hashtable_global_ref_entry *gre;
3431 u4 key; /* hashkey */
3432 u4 slot; /* slot in hashtable */
3435 STATISTICS(jniinvokation());
3437 o = (java_handle_t *) obj;
3439 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3441 /* normally addresses are aligned to 4, 8 or 16 bytes */
3443 key = ((u4) (ptrint) obj) >> 4; /* align to 16-byte boundaries */
3444 slot = key & (hashtable_global_ref->size - 1);
3445 gre = hashtable_global_ref->ptr[slot];
3447 /* search external hash chain for the entry */
3451 /* global object found, increment the reference */
3455 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3460 gre = gre->hashlink; /* next element in external chain */
3463 /* global ref not found, create a new one */
3465 gre = NEW(hashtable_global_ref_entry);
3470 /* insert entry into hashtable */
3472 gre->hashlink = hashtable_global_ref->ptr[slot];
3474 hashtable_global_ref->ptr[slot] = gre;
3476 /* update number of hashtable-entries */
3478 hashtable_global_ref->entries++;
3480 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3486 /* DeleteGlobalRef *************************************************************
3488 Deletes the global reference pointed to by globalRef.
3490 *******************************************************************************/
3492 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3494 hashtable_global_ref_entry *gre;
3495 hashtable_global_ref_entry *prevgre;
3496 u4 key; /* hashkey */
3497 u4 slot; /* slot in hashtable */
3500 STATISTICS(jniinvokation());
3502 o = (java_handle_t *) globalRef;
3504 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3506 /* normally addresses are aligned to 4, 8 or 16 bytes */
3508 key = ((u4) (ptrint) globalRef) >> 4; /* align to 16-byte boundaries */
3509 slot = key & (hashtable_global_ref->size - 1);
3510 gre = hashtable_global_ref->ptr[slot];
3512 /* initialize prevgre */
3516 /* search external hash chain for the entry */
3520 /* global object found, decrement the reference count */
3524 /* if reference count is 0, remove the entry */
3526 if (gre->refs == 0) {
3527 /* special handling if it's the first in the chain */
3529 if (prevgre == NULL)
3530 hashtable_global_ref->ptr[slot] = gre->hashlink;
3532 prevgre->hashlink = gre->hashlink;
3534 FREE(gre, hashtable_global_ref_entry);
3537 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3542 prevgre = gre; /* save current pointer for removal */
3543 gre = gre->hashlink; /* next element in external chain */
3546 log_println("JNI-DeleteGlobalRef: global reference not found");
3548 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3552 /* ExceptionCheck **************************************************************
3554 Returns JNI_TRUE when there is a pending exception; otherwise,
3557 *******************************************************************************/
3559 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3563 STATISTICS(jniinvokation());
3565 o = exceptions_get_exception();
3567 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3571 /* New JNI 1.4 functions ******************************************************/
3573 /* NewDirectByteBuffer *********************************************************
3575 Allocates and returns a direct java.nio.ByteBuffer referring to the
3576 block of memory starting at the memory address address and
3577 extending capacity bytes.
3579 *******************************************************************************/
3581 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3583 #if defined(ENABLE_JAVASE)
3584 # if defined(WITH_CLASSPATH_GNU)
3585 java_handle_t *nbuf;
3587 # if SIZEOF_VOID_P == 8
3588 gnu_classpath_Pointer64 *paddress;
3590 gnu_classpath_Pointer32 *paddress;
3593 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3595 /* alocate a gnu.classpath.Pointer{32,64} object */
3597 # if SIZEOF_VOID_P == 8
3598 if (!(paddress = (gnu_classpath_Pointer64 *)
3599 builtin_new(class_gnu_classpath_Pointer64)))
3601 if (!(paddress = (gnu_classpath_Pointer32 *)
3602 builtin_new(class_gnu_classpath_Pointer32)))
3606 /* fill gnu.classpath.Pointer{32,64} with address */
3608 LLNI_field_set_val(paddress, data, (ptrint) address);
3610 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3612 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3613 (jmethodID) dbbirw_init, NULL, paddress,
3614 (jint) capacity, (jint) capacity, (jint) 0);
3616 /* add local reference and return the value */
3618 return _Jv_JNI_NewLocalRef(env, nbuf);
3620 # elif defined(WITH_CLASSPATH_SUN)
3626 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3628 /* Be paranoid about address sign-extension. */
3630 addr = (int64_t) ((uintptr_t) address);
3631 cap = (int32_t) capacity;
3633 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3634 (jmethodID) dbb_init, addr, cap);
3636 /* Add local reference and return the value. */
3638 return _Jv_JNI_NewLocalRef(env, o);
3641 # error unknown classpath configuration
3645 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3647 /* keep compiler happy */
3654 /* GetDirectBufferAddress ******************************************************
3656 Fetches and returns the starting address of the memory region
3657 referenced by the given direct java.nio.Buffer.
3659 *******************************************************************************/
3661 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3663 #if defined(ENABLE_JAVASE)
3664 # if defined(WITH_CLASSPATH_GNU)
3666 java_nio_DirectByteBufferImpl *nbuf;
3667 # if SIZEOF_VOID_P == 8
3668 gnu_classpath_Pointer64 *paddress;
3670 gnu_classpath_Pointer32 *paddress;
3674 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3676 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3679 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3681 # if SIZEOF_VOID_P == 8
3682 LLNI_field_get_ref(nbuf, address, paddress);
3683 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3685 LLNI_field_get_ref(nbuf, address, paddress);
3686 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3689 if (paddress == NULL)
3692 LLNI_field_get_val(paddress, data, address);
3693 /* this was the cast to avaoid warning: (void *) paddress->data */
3697 # elif defined(WITH_CLASSPATH_SUN)
3703 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3705 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3708 o = (java_nio_Buffer *) buf;
3710 LLNI_field_get_val(o, address, address);
3712 p = (void *) (intptr_t) address;
3717 # error unknown classpath configuration
3722 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3724 /* keep compiler happy */
3732 /* GetDirectBufferCapacity *****************************************************
3734 Fetches and returns the capacity in bytes of the memory region
3735 referenced by the given direct java.nio.Buffer.
3737 *******************************************************************************/
3739 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3741 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3743 java_nio_Buffer *nbuf;
3746 STATISTICS(jniinvokation());
3748 o = (java_handle_t *) buf;
3750 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3753 nbuf = (java_nio_Buffer *) o;
3755 LLNI_field_get_val(nbuf, cap, capacity);
3759 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3761 /* keep compiler happy */
3768 /* GetObjectRefType ************************************************************
3770 Returns the type of the object referred to by the obj argument. The
3771 argument obj can either be a local, global or weak global
3774 *******************************************************************************/
3776 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3778 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3784 /* DestroyJavaVM ***************************************************************
3786 Unloads a Java VM and reclaims its resources. Only the main thread
3787 can unload the VM. The system waits until the main thread is only
3788 remaining user thread before it destroys the VM.
3790 *******************************************************************************/
3792 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3796 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3798 status = vm_destroy(vm);
3804 /* AttachCurrentThread *********************************************************
3806 Attaches the current thread to a Java VM. Returns a JNI interface
3807 pointer in the JNIEnv argument.
3809 Trying to attach a thread that is already attached is a no-op.
3811 A native thread cannot be attached simultaneously to two Java VMs.
3813 When a thread is attached to the VM, the context class loader is
3814 the bootstrap loader.
3816 *******************************************************************************/
3818 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3820 JavaVMAttachArgs *vm_aargs;
3822 #if defined(ENABLE_THREADS)
3823 if (threads_get_current_threadobject() == NULL) {
3824 vm_aargs = (JavaVMAttachArgs *) thr_args;
3826 if (vm_aargs != NULL) {
3827 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3828 (vm_aargs->version != JNI_VERSION_1_4))
3829 return JNI_EVERSION;
3832 if (!threads_attach_current_thread(vm_aargs, false))
3835 if (!localref_table_init())
3846 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3848 STATISTICS(jniinvokation());
3850 return jni_attach_current_thread(p_env, thr_args, false);
3854 /* DetachCurrentThread *********************************************************
3856 Detaches the current thread from a Java VM. All Java monitors held
3857 by this thread are released. All Java threads waiting for this
3858 thread to die are notified.
3860 In JDK 1.1, the main thread cannot be detached from the VM. It must
3861 call DestroyJavaVM to unload the entire VM.
3863 In the JDK, the main thread can be detached from the VM.
3865 The main thread, which is the thread that created the Java VM,
3866 cannot be detached from the VM. Instead, the main thread must call
3867 JNI_DestroyJavaVM() to unload the entire VM.
3869 *******************************************************************************/
3871 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3873 #if defined(ENABLE_THREADS)
3874 threadobject *thread;
3876 STATISTICS(jniinvokation());
3878 thread = threads_get_current_threadobject();
3883 if (!threads_detach_thread(thread))
3891 /* GetEnv **********************************************************************
3893 If the current thread is not attached to the VM, sets *env to NULL,
3894 and returns JNI_EDETACHED. If the specified version is not
3895 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3896 sets *env to the appropriate interface, and returns JNI_OK.
3898 *******************************************************************************/
3900 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3902 STATISTICS(jniinvokation());
3904 #if defined(ENABLE_THREADS)
3905 if (threads_get_current_threadobject() == NULL) {
3908 return JNI_EDETACHED;
3912 /* check the JNI version */
3915 case JNI_VERSION_1_1:
3916 case JNI_VERSION_1_2:
3917 case JNI_VERSION_1_4:
3925 #if defined(ENABLE_JVMTI)
3926 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3927 == JVMTI_VERSION_INTERFACE_JVMTI) {
3929 *env = (void *) jvmti_new_environment();
3938 return JNI_EVERSION;
3942 /* AttachCurrentThreadAsDaemon *************************************************
3944 Same semantics as AttachCurrentThread, but the newly-created
3945 java.lang.Thread instance is a daemon.
3947 If the thread has already been attached via either
3948 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3949 simply sets the value pointed to by penv to the JNIEnv of the
3950 current thread. In this case neither AttachCurrentThread nor this
3951 routine have any effect on the daemon status of the thread.
3953 *******************************************************************************/
3955 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3957 STATISTICS(jniinvokation());
3959 return jni_attach_current_thread(penv, args, true);
3963 /* JNI invocation table *******************************************************/
3965 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3970 _Jv_JNI_DestroyJavaVM,
3971 _Jv_JNI_AttachCurrentThread,
3972 _Jv_JNI_DetachCurrentThread,
3974 _Jv_JNI_AttachCurrentThreadAsDaemon
3978 /* JNI function table *********************************************************/
3980 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3987 _Jv_JNI_DefineClass,
3989 _Jv_JNI_FromReflectedMethod,
3990 _Jv_JNI_FromReflectedField,
3991 _Jv_JNI_ToReflectedMethod,
3992 _Jv_JNI_GetSuperclass,
3993 _Jv_JNI_IsAssignableFrom,
3994 _Jv_JNI_ToReflectedField,
3998 _Jv_JNI_ExceptionOccurred,
3999 _Jv_JNI_ExceptionDescribe,
4000 _Jv_JNI_ExceptionClear,
4002 _Jv_JNI_PushLocalFrame,
4003 _Jv_JNI_PopLocalFrame,
4005 _Jv_JNI_NewGlobalRef,
4006 _Jv_JNI_DeleteGlobalRef,
4007 _Jv_JNI_DeleteLocalRef,
4008 _Jv_JNI_IsSameObject,
4009 _Jv_JNI_NewLocalRef,
4010 _Jv_JNI_EnsureLocalCapacity,
4012 _Jv_JNI_AllocObject,
4017 _Jv_JNI_GetObjectClass,
4018 _Jv_JNI_IsInstanceOf,
4020 _Jv_JNI_GetMethodID,
4022 _Jv_JNI_CallObjectMethod,
4023 _Jv_JNI_CallObjectMethodV,
4024 _Jv_JNI_CallObjectMethodA,
4025 _Jv_JNI_CallBooleanMethod,
4026 _Jv_JNI_CallBooleanMethodV,
4027 _Jv_JNI_CallBooleanMethodA,
4028 _Jv_JNI_CallByteMethod,
4029 _Jv_JNI_CallByteMethodV,
4030 _Jv_JNI_CallByteMethodA,
4031 _Jv_JNI_CallCharMethod,
4032 _Jv_JNI_CallCharMethodV,
4033 _Jv_JNI_CallCharMethodA,
4034 _Jv_JNI_CallShortMethod,
4035 _Jv_JNI_CallShortMethodV,
4036 _Jv_JNI_CallShortMethodA,
4037 _Jv_JNI_CallIntMethod,
4038 _Jv_JNI_CallIntMethodV,
4039 _Jv_JNI_CallIntMethodA,
4040 _Jv_JNI_CallLongMethod,
4041 _Jv_JNI_CallLongMethodV,
4042 _Jv_JNI_CallLongMethodA,
4043 _Jv_JNI_CallFloatMethod,
4044 _Jv_JNI_CallFloatMethodV,
4045 _Jv_JNI_CallFloatMethodA,
4046 _Jv_JNI_CallDoubleMethod,
4047 _Jv_JNI_CallDoubleMethodV,
4048 _Jv_JNI_CallDoubleMethodA,
4049 _Jv_JNI_CallVoidMethod,
4050 _Jv_JNI_CallVoidMethodV,
4051 _Jv_JNI_CallVoidMethodA,
4053 _Jv_JNI_CallNonvirtualObjectMethod,
4054 _Jv_JNI_CallNonvirtualObjectMethodV,
4055 _Jv_JNI_CallNonvirtualObjectMethodA,
4056 _Jv_JNI_CallNonvirtualBooleanMethod,
4057 _Jv_JNI_CallNonvirtualBooleanMethodV,
4058 _Jv_JNI_CallNonvirtualBooleanMethodA,
4059 _Jv_JNI_CallNonvirtualByteMethod,
4060 _Jv_JNI_CallNonvirtualByteMethodV,
4061 _Jv_JNI_CallNonvirtualByteMethodA,
4062 _Jv_JNI_CallNonvirtualCharMethod,
4063 _Jv_JNI_CallNonvirtualCharMethodV,
4064 _Jv_JNI_CallNonvirtualCharMethodA,
4065 _Jv_JNI_CallNonvirtualShortMethod,
4066 _Jv_JNI_CallNonvirtualShortMethodV,
4067 _Jv_JNI_CallNonvirtualShortMethodA,
4068 _Jv_JNI_CallNonvirtualIntMethod,
4069 _Jv_JNI_CallNonvirtualIntMethodV,
4070 _Jv_JNI_CallNonvirtualIntMethodA,
4071 _Jv_JNI_CallNonvirtualLongMethod,
4072 _Jv_JNI_CallNonvirtualLongMethodV,
4073 _Jv_JNI_CallNonvirtualLongMethodA,
4074 _Jv_JNI_CallNonvirtualFloatMethod,
4075 _Jv_JNI_CallNonvirtualFloatMethodV,
4076 _Jv_JNI_CallNonvirtualFloatMethodA,
4077 _Jv_JNI_CallNonvirtualDoubleMethod,
4078 _Jv_JNI_CallNonvirtualDoubleMethodV,
4079 _Jv_JNI_CallNonvirtualDoubleMethodA,
4080 _Jv_JNI_CallNonvirtualVoidMethod,
4081 _Jv_JNI_CallNonvirtualVoidMethodV,
4082 _Jv_JNI_CallNonvirtualVoidMethodA,
4086 _Jv_JNI_GetObjectField,
4087 _Jv_JNI_GetBooleanField,
4088 _Jv_JNI_GetByteField,
4089 _Jv_JNI_GetCharField,
4090 _Jv_JNI_GetShortField,
4091 _Jv_JNI_GetIntField,
4092 _Jv_JNI_GetLongField,
4093 _Jv_JNI_GetFloatField,
4094 _Jv_JNI_GetDoubleField,
4095 _Jv_JNI_SetObjectField,
4096 _Jv_JNI_SetBooleanField,
4097 _Jv_JNI_SetByteField,
4098 _Jv_JNI_SetCharField,
4099 _Jv_JNI_SetShortField,
4100 _Jv_JNI_SetIntField,
4101 _Jv_JNI_SetLongField,
4102 _Jv_JNI_SetFloatField,
4103 _Jv_JNI_SetDoubleField,
4105 _Jv_JNI_GetStaticMethodID,
4107 _Jv_JNI_CallStaticObjectMethod,
4108 _Jv_JNI_CallStaticObjectMethodV,
4109 _Jv_JNI_CallStaticObjectMethodA,
4110 _Jv_JNI_CallStaticBooleanMethod,
4111 _Jv_JNI_CallStaticBooleanMethodV,
4112 _Jv_JNI_CallStaticBooleanMethodA,
4113 _Jv_JNI_CallStaticByteMethod,
4114 _Jv_JNI_CallStaticByteMethodV,
4115 _Jv_JNI_CallStaticByteMethodA,
4116 _Jv_JNI_CallStaticCharMethod,
4117 _Jv_JNI_CallStaticCharMethodV,
4118 _Jv_JNI_CallStaticCharMethodA,
4119 _Jv_JNI_CallStaticShortMethod,
4120 _Jv_JNI_CallStaticShortMethodV,
4121 _Jv_JNI_CallStaticShortMethodA,
4122 _Jv_JNI_CallStaticIntMethod,
4123 _Jv_JNI_CallStaticIntMethodV,
4124 _Jv_JNI_CallStaticIntMethodA,
4125 _Jv_JNI_CallStaticLongMethod,
4126 _Jv_JNI_CallStaticLongMethodV,
4127 _Jv_JNI_CallStaticLongMethodA,
4128 _Jv_JNI_CallStaticFloatMethod,
4129 _Jv_JNI_CallStaticFloatMethodV,
4130 _Jv_JNI_CallStaticFloatMethodA,
4131 _Jv_JNI_CallStaticDoubleMethod,
4132 _Jv_JNI_CallStaticDoubleMethodV,
4133 _Jv_JNI_CallStaticDoubleMethodA,
4134 _Jv_JNI_CallStaticVoidMethod,
4135 _Jv_JNI_CallStaticVoidMethodV,
4136 _Jv_JNI_CallStaticVoidMethodA,
4138 _Jv_JNI_GetStaticFieldID,
4140 _Jv_JNI_GetStaticObjectField,
4141 _Jv_JNI_GetStaticBooleanField,
4142 _Jv_JNI_GetStaticByteField,
4143 _Jv_JNI_GetStaticCharField,
4144 _Jv_JNI_GetStaticShortField,
4145 _Jv_JNI_GetStaticIntField,
4146 _Jv_JNI_GetStaticLongField,
4147 _Jv_JNI_GetStaticFloatField,
4148 _Jv_JNI_GetStaticDoubleField,
4149 _Jv_JNI_SetStaticObjectField,
4150 _Jv_JNI_SetStaticBooleanField,
4151 _Jv_JNI_SetStaticByteField,
4152 _Jv_JNI_SetStaticCharField,
4153 _Jv_JNI_SetStaticShortField,
4154 _Jv_JNI_SetStaticIntField,
4155 _Jv_JNI_SetStaticLongField,
4156 _Jv_JNI_SetStaticFloatField,
4157 _Jv_JNI_SetStaticDoubleField,
4160 _Jv_JNI_GetStringLength,
4161 _Jv_JNI_GetStringChars,
4162 _Jv_JNI_ReleaseStringChars,
4164 _Jv_JNI_NewStringUTF,
4165 _Jv_JNI_GetStringUTFLength,
4166 _Jv_JNI_GetStringUTFChars,
4167 _Jv_JNI_ReleaseStringUTFChars,
4169 _Jv_JNI_GetArrayLength,
4171 _Jv_JNI_NewObjectArray,
4172 _Jv_JNI_GetObjectArrayElement,
4173 _Jv_JNI_SetObjectArrayElement,
4175 _Jv_JNI_NewBooleanArray,
4176 _Jv_JNI_NewByteArray,
4177 _Jv_JNI_NewCharArray,
4178 _Jv_JNI_NewShortArray,
4179 _Jv_JNI_NewIntArray,
4180 _Jv_JNI_NewLongArray,
4181 _Jv_JNI_NewFloatArray,
4182 _Jv_JNI_NewDoubleArray,
4184 _Jv_JNI_GetBooleanArrayElements,
4185 _Jv_JNI_GetByteArrayElements,
4186 _Jv_JNI_GetCharArrayElements,
4187 _Jv_JNI_GetShortArrayElements,
4188 _Jv_JNI_GetIntArrayElements,
4189 _Jv_JNI_GetLongArrayElements,
4190 _Jv_JNI_GetFloatArrayElements,
4191 _Jv_JNI_GetDoubleArrayElements,
4193 _Jv_JNI_ReleaseBooleanArrayElements,
4194 _Jv_JNI_ReleaseByteArrayElements,
4195 _Jv_JNI_ReleaseCharArrayElements,
4196 _Jv_JNI_ReleaseShortArrayElements,
4197 _Jv_JNI_ReleaseIntArrayElements,
4198 _Jv_JNI_ReleaseLongArrayElements,
4199 _Jv_JNI_ReleaseFloatArrayElements,
4200 _Jv_JNI_ReleaseDoubleArrayElements,
4202 _Jv_JNI_GetBooleanArrayRegion,
4203 _Jv_JNI_GetByteArrayRegion,
4204 _Jv_JNI_GetCharArrayRegion,
4205 _Jv_JNI_GetShortArrayRegion,
4206 _Jv_JNI_GetIntArrayRegion,
4207 _Jv_JNI_GetLongArrayRegion,
4208 _Jv_JNI_GetFloatArrayRegion,
4209 _Jv_JNI_GetDoubleArrayRegion,
4210 _Jv_JNI_SetBooleanArrayRegion,
4211 _Jv_JNI_SetByteArrayRegion,
4212 _Jv_JNI_SetCharArrayRegion,
4213 _Jv_JNI_SetShortArrayRegion,
4214 _Jv_JNI_SetIntArrayRegion,
4215 _Jv_JNI_SetLongArrayRegion,
4216 _Jv_JNI_SetFloatArrayRegion,
4217 _Jv_JNI_SetDoubleArrayRegion,
4219 _Jv_JNI_RegisterNatives,
4220 _Jv_JNI_UnregisterNatives,
4222 _Jv_JNI_MonitorEnter,
4223 _Jv_JNI_MonitorExit,
4227 /* New JNI 1.2 functions. */
4229 _Jv_JNI_GetStringRegion,
4230 _Jv_JNI_GetStringUTFRegion,
4232 _Jv_JNI_GetPrimitiveArrayCritical,
4233 _Jv_JNI_ReleasePrimitiveArrayCritical,
4235 _Jv_JNI_GetStringCritical,
4236 _Jv_JNI_ReleaseStringCritical,
4238 _Jv_JNI_NewWeakGlobalRef,
4239 _Jv_JNI_DeleteWeakGlobalRef,
4241 _Jv_JNI_ExceptionCheck,
4243 /* New JNI 1.4 functions. */
4245 _Jv_JNI_NewDirectByteBuffer,
4246 _Jv_JNI_GetDirectBufferAddress,
4247 _Jv_JNI_GetDirectBufferCapacity,
4249 /* New JNI 1.6 functions. */
4251 jni_GetObjectRefType
4255 /* Invocation API Functions ***************************************************/
4257 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4259 Returns a default configuration for the Java VM.
4261 *******************************************************************************/
4263 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4265 JavaVMInitArgs *_vm_args;
4267 _vm_args = (JavaVMInitArgs *) vm_args;
4269 /* GNU classpath currently supports JNI 1.2 */
4271 switch (_vm_args->version) {
4272 case JNI_VERSION_1_1:
4273 _vm_args->version = JNI_VERSION_1_1;
4276 case JNI_VERSION_1_2:
4277 case JNI_VERSION_1_4:
4278 _vm_args->ignoreUnrecognized = JNI_FALSE;
4279 _vm_args->options = NULL;
4280 _vm_args->nOptions = 0;
4291 /* JNI_GetCreatedJavaVMs *******************************************************
4293 Returns all Java VMs that have been created. Pointers to VMs are written in
4294 the buffer vmBuf in the order they are created. At most bufLen number of
4295 entries will be written. The total number of created VMs is returned in
4298 *******************************************************************************/
4300 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4302 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4307 /* We currently only support 1 VM running. */
4309 vmBuf[0] = (JavaVM *) _Jv_jvm;
4316 /* JNI_CreateJavaVM ************************************************************
4318 Loads and initializes a Java VM. The current thread becomes the main thread.
4319 Sets the env argument to the JNI interface pointer of the main thread.
4321 *******************************************************************************/
4323 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4325 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4327 /* actually create the JVM */
4329 if (!vm_createjvm(p_vm, p_env, vm_args))
4337 * These are local overrides for various environment variables in Emacs.
4338 * Please do not remove this and leave it at the end of the file, where
4339 * Emacs will automagically detect them.
4340 * ---------------------------------------------------------------------
4343 * indent-tabs-mode: t
4347 * vim:noexpandtab:sw=4:ts=4: