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);
180 /* jni_init ********************************************************************
182 Initialize the JNI subsystem.
184 *******************************************************************************/
188 /* create global ref hashtable */
190 hashtable_global_ref = NEW(hashtable);
192 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
195 #if defined(ENABLE_JAVASE)
196 /* Direct buffer stuff. */
198 if (!(class_java_nio_Buffer =
199 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
200 !link_class(class_java_nio_Buffer))
203 # if defined(WITH_CLASSPATH_GNU)
205 if (!(class_java_nio_DirectByteBufferImpl =
206 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
207 !link_class(class_java_nio_DirectByteBufferImpl))
210 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
212 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
216 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
218 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
221 # if SIZEOF_VOID_P == 8
222 if (!(class_gnu_classpath_Pointer64 =
223 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
224 !link_class(class_gnu_classpath_Pointer64))
227 if (!(class_gnu_classpath_Pointer32 =
228 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
229 !link_class(class_gnu_classpath_Pointer32))
233 # elif defined(WITH_CLASSPATH_SUN)
235 if (!(class_sun_nio_ch_DirectBuffer =
236 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
237 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
239 if (!link_class(class_sun_nio_ch_DirectBuffer))
240 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
242 if (!(class_java_nio_DirectByteBuffer =
243 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
244 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
246 if (!link_class(class_java_nio_DirectByteBuffer))
247 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
250 class_resolvemethod(class_java_nio_DirectByteBuffer,
252 utf_new_char("(JI)V"))))
253 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
257 #endif /* defined(ENABLE_JAVASE) */
263 /* jni_version_check ************************************************************
265 Check if the given JNI version is supported.
268 version....JNI version to check
272 false......not supported
274 ********************************************************************************/
276 bool jni_version_check(int version)
279 case JNI_VERSION_1_1:
280 case JNI_VERSION_1_2:
281 case JNI_VERSION_1_4:
282 case JNI_VERSION_1_6:
290 /* _Jv_jni_CallObjectMethod ****************************************************
292 Internal function to call Java Object methods.
294 *******************************************************************************/
296 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
298 methodinfo *m, va_list ap)
303 STATISTICS(jniinvokation());
306 exceptions_throw_nullpointerexception();
310 /* Class initialization is done by the JIT compiler. This is ok
311 since a static method always belongs to the declaring class. */
313 if (m->flags & ACC_STATIC) {
314 /* For static methods we reset the object. */
319 /* for convenience */
324 /* For instance methods we make a virtual function table lookup. */
326 resm = method_vftbl_lookup(vftbl, m);
329 STATISTICS(jnicallXmethodnvokation());
331 ro = vm_call_method_valist(resm, o, ap);
337 /* _Jv_jni_CallObjectMethodA ***************************************************
339 Internal function to call Java Object methods.
341 *******************************************************************************/
343 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
351 STATISTICS(jniinvokation());
354 exceptions_throw_nullpointerexception();
358 /* Class initialization is done by the JIT compiler. This is ok
359 since a static method always belongs to the declaring class. */
361 if (m->flags & ACC_STATIC) {
362 /* For static methods we reset the object. */
367 /* for convenience */
372 /* For instance methods we make a virtual function table lookup. */
374 resm = method_vftbl_lookup(vftbl, m);
377 STATISTICS(jnicallXmethodnvokation());
379 ro = vm_call_method_jvalue(resm, o, args);
385 /* _Jv_jni_CallIntMethod *******************************************************
387 Internal function to call Java integer class methods (boolean,
388 byte, char, short, int).
390 *******************************************************************************/
392 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
393 methodinfo *m, va_list ap)
398 STATISTICS(jniinvokation());
401 exceptions_throw_nullpointerexception();
405 /* Class initialization is done by the JIT compiler. This is ok
406 since a static method always belongs to the declaring class. */
408 if (m->flags & ACC_STATIC) {
409 /* For static methods we reset the object. */
414 /* for convenience */
419 /* For instance methods we make a virtual function table lookup. */
421 resm = method_vftbl_lookup(vftbl, m);
424 STATISTICS(jnicallXmethodnvokation());
426 i = vm_call_method_int_valist(resm, o, ap);
432 /* _Jv_jni_CallIntMethodA ******************************************************
434 Internal function to call Java integer class methods (boolean,
435 byte, char, short, int).
437 *******************************************************************************/
439 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
440 methodinfo *m, const jvalue *args)
445 STATISTICS(jniinvokation());
448 exceptions_throw_nullpointerexception();
452 /* Class initialization is done by the JIT compiler. This is ok
453 since a static method always belongs to the declaring class. */
455 if (m->flags & ACC_STATIC) {
456 /* For static methods we reset the object. */
461 /* for convenience */
466 /* For instance methods we make a virtual function table lookup. */
468 resm = method_vftbl_lookup(vftbl, m);
471 STATISTICS(jnicallXmethodnvokation());
473 i = vm_call_method_int_jvalue(resm, o, args);
479 /* _Jv_jni_CallLongMethod ******************************************************
481 Internal function to call Java long methods.
483 *******************************************************************************/
485 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
486 methodinfo *m, va_list ap)
491 STATISTICS(jniinvokation());
494 exceptions_throw_nullpointerexception();
498 /* Class initialization is done by the JIT compiler. This is ok
499 since a static method always belongs to the declaring class. */
501 if (m->flags & ACC_STATIC) {
502 /* For static methods we reset the object. */
507 /* for convenience */
512 /* For instance methods we make a virtual function table lookup. */
514 resm = method_vftbl_lookup(vftbl, m);
517 STATISTICS(jnicallXmethodnvokation());
519 l = vm_call_method_long_valist(resm, o, ap);
525 /* _Jv_jni_CallLongMethodA *****************************************************
527 Internal function to call Java long methods.
529 *******************************************************************************/
531 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
532 methodinfo *m, const jvalue *args)
537 STATISTICS(jniinvokation());
540 exceptions_throw_nullpointerexception();
544 /* Class initialization is done by the JIT compiler. This is ok
545 since a static method always belongs to the declaring class. */
547 if (m->flags & ACC_STATIC) {
548 /* For static methods we reset the object. */
553 /* for convenience */
558 /* For instance methods we make a virtual function table lookup. */
560 resm = method_vftbl_lookup(vftbl, m);
563 STATISTICS(jnicallXmethodnvokation());
565 l = vm_call_method_long_jvalue(resm, o, args);
571 /* _Jv_jni_CallFloatMethod *****************************************************
573 Internal function to call Java float methods.
575 *******************************************************************************/
577 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
578 methodinfo *m, va_list ap)
583 /* Class initialization is done by the JIT compiler. This is ok
584 since a static method always belongs to the declaring class. */
586 if (m->flags & ACC_STATIC) {
587 /* For static methods we reset the object. */
592 /* for convenience */
597 /* For instance methods we make a virtual function table lookup. */
599 resm = method_vftbl_lookup(vftbl, m);
602 STATISTICS(jnicallXmethodnvokation());
604 f = vm_call_method_float_valist(resm, o, ap);
610 /* _Jv_jni_CallFloatMethodA ****************************************************
612 Internal function to call Java float methods.
614 *******************************************************************************/
616 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
617 methodinfo *m, const jvalue *args)
622 /* Class initialization is done by the JIT compiler. This is ok
623 since a static method always belongs to the declaring class. */
625 if (m->flags & ACC_STATIC) {
626 /* For static methods we reset the object. */
631 /* for convenience */
636 /* For instance methods we make a virtual function table lookup. */
638 resm = method_vftbl_lookup(vftbl, m);
641 STATISTICS(jnicallXmethodnvokation());
643 f = vm_call_method_float_jvalue(resm, o, args);
649 /* _Jv_jni_CallDoubleMethod ****************************************************
651 Internal function to call Java double methods.
653 *******************************************************************************/
655 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
656 methodinfo *m, va_list ap)
661 /* Class initialization is done by the JIT compiler. This is ok
662 since a static method always belongs to the declaring class. */
664 if (m->flags & ACC_STATIC) {
665 /* For static methods we reset the object. */
670 /* for convenience */
675 /* For instance methods we make a virtual function table lookup. */
677 resm = method_vftbl_lookup(vftbl, m);
680 d = vm_call_method_double_valist(resm, o, ap);
686 /* _Jv_jni_CallDoubleMethodA ***************************************************
688 Internal function to call Java double methods.
690 *******************************************************************************/
692 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
693 methodinfo *m, const jvalue *args)
698 /* Class initialization is done by the JIT compiler. This is ok
699 since a static method always belongs to the declaring class. */
701 if (m->flags & ACC_STATIC) {
702 /* For static methods we reset the object. */
707 /* for convenience */
712 /* For instance methods we make a virtual function table lookup. */
714 resm = method_vftbl_lookup(vftbl, m);
717 d = vm_call_method_double_jvalue(resm, o, args);
723 /* _Jv_jni_CallVoidMethod ******************************************************
725 Internal function to call Java void methods.
727 *******************************************************************************/
729 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
730 methodinfo *m, va_list ap)
735 exceptions_throw_nullpointerexception();
739 /* Class initialization is done by the JIT compiler. This is ok
740 since a static method always belongs to the declaring class. */
742 if (m->flags & ACC_STATIC) {
743 /* For static methods we reset the object. */
748 /* for convenience */
753 /* For instance methods we make a virtual function table lookup. */
755 resm = method_vftbl_lookup(vftbl, m);
758 STATISTICS(jnicallXmethodnvokation());
760 (void) vm_call_method_valist(resm, o, ap);
764 /* _Jv_jni_CallVoidMethodA *****************************************************
766 Internal function to call Java void methods.
768 *******************************************************************************/
770 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
771 methodinfo *m, const jvalue *args)
776 exceptions_throw_nullpointerexception();
780 /* Class initialization is done by the JIT compiler. This is ok
781 since a static method always belongs to the declaring class. */
783 if (m->flags & ACC_STATIC) {
784 /* For static methods we reset the object. */
789 /* for convenience */
794 /* For instance methods we make a virtual function table lookup. */
796 resm = method_vftbl_lookup(vftbl, m);
799 STATISTICS(jnicallXmethodnvokation());
801 (void) vm_call_method_jvalue(resm, o, args);
805 /* _Jv_jni_invokeNative ********************************************************
807 Invoke a method on the given object with the given arguments.
809 For instance methods OBJ must be != NULL and the method is looked up
810 in the vftbl of the object.
812 For static methods, OBJ is ignored.
814 *******************************************************************************/
816 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
817 java_handle_objectarray_t *params)
829 exceptions_throw_nullpointerexception();
833 argcount = m->parseddesc->paramcount;
834 paramcount = argcount;
836 /* if method is non-static, remove the `this' pointer */
838 if (!(m->flags & ACC_STATIC))
841 /* For instance methods the object has to be an instance of the
842 class the method belongs to. For static methods the obj
843 parameter is ignored. */
845 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
846 exceptions_throw_illegalargumentexception();
850 /* check if we got the right number of arguments */
852 if (((params == NULL) && (paramcount != 0)) ||
853 (params && (LLNI_array_size(params) != paramcount)))
855 exceptions_throw_illegalargumentexception();
859 /* for instance methods we need an object */
861 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
862 /* XXX not sure if that is the correct exception */
863 exceptions_throw_nullpointerexception();
867 /* for static methods, zero object to make subsequent code simpler */
868 if (m->flags & ACC_STATIC)
872 /* for instance methods we must do a vftbl lookup */
873 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
876 /* for static methods, just for convenience */
880 /* mark start of dump memory area */
882 dumpsize = dump_size();
884 /* Fill the argument array from a object-array. */
886 array = vm_array_from_objectarray(resm, o, params);
888 /* The array can be NULL if we don't have any arguments to pass
889 and the architecture does not have any argument registers
890 (e.g. i386). In that case we additionally check for an
893 if ((array == NULL) && (exceptions_get_exception() != NULL)) {
894 /* release dump area */
896 dump_release(dumpsize);
901 switch (resm->parseddesc->returntype.decltype) {
903 (void) vm_call_array(resm, array);
907 case PRIMITIVETYPE_BOOLEAN:
908 case PRIMITIVETYPE_BYTE:
909 case PRIMITIVETYPE_CHAR:
910 case PRIMITIVETYPE_SHORT:
911 case PRIMITIVETYPE_INT:
912 value.i = vm_call_int_array(resm, array);
913 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
916 case PRIMITIVETYPE_LONG:
917 value.l = vm_call_long_array(resm, array);
918 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
921 case PRIMITIVETYPE_FLOAT:
922 value.f = vm_call_float_array(resm, array);
923 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
926 case PRIMITIVETYPE_DOUBLE:
927 value.d = vm_call_double_array(resm, array);
928 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
932 ro = vm_call_array(resm, array);
936 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
939 xptr = exceptions_get_exception();
942 /* clear exception pointer, we are calling JIT code again */
944 exceptions_clear_exception();
946 exceptions_throw_invocationtargetexception(xptr);
949 /* release dump area */
951 dump_release(dumpsize);
957 /* GetVersion ******************************************************************
959 Returns the major version number in the higher 16 bits and the
960 minor version number in the lower 16 bits.
962 *******************************************************************************/
964 jint _Jv_JNI_GetVersion(JNIEnv *env)
966 TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
968 /* We support JNI 1.6. */
970 return JNI_VERSION_1_6;
974 /* Class Operations ***********************************************************/
976 /* DefineClass *****************************************************************
978 Loads a class from a buffer of raw class data. The buffer
979 containing the raw class data is not referenced by the VM after the
980 DefineClass call returns, and it may be discarded if desired.
982 *******************************************************************************/
984 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
985 const jbyte *buf, jsize bufLen)
987 #if defined(ENABLE_JAVASE)
993 TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
995 u = utf_new_char(name);
996 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
998 c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
1000 co = LLNI_classinfo_wrap(c);
1002 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1004 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
1006 /* keep compiler happy */
1013 /* FindClass *******************************************************************
1015 This function loads a locally-defined class. It searches the
1016 directories and zip files specified by the CLASSPATH environment
1017 variable for the class with the specified name.
1019 *******************************************************************************/
1021 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
1023 #if defined(ENABLE_JAVASE)
1028 java_lang_Class *co;
1030 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
1032 u = utf_new_char_classname((char *) name);
1034 /* Check stacktrace for classloader, if one found use it,
1035 otherwise use the system classloader. */
1037 /* Quote from the JNI documentation:
1039 In the Java 2 Platform, FindClass locates the class loader
1040 associated with the current native method. If the native code
1041 belongs to a system class, no class loader will be
1042 involved. Otherwise, the proper class loader will be invoked to
1043 load and link the named class. When FindClass is called through
1044 the Invocation Interface, there is no current native method or
1045 its associated class loader. In that case, the result of
1046 ClassLoader.getBaseClassLoader is used." */
1048 cc = stacktrace_getCurrentClass();
1051 c = load_class_from_sysloader(u);
1053 c = load_class_from_classloader(u, cc->classloader);
1061 co = LLNI_classinfo_wrap(c);
1063 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1065 #elif defined(ENABLE_JAVAME_CLDC1_1)
1070 TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
1072 u = utf_new_char_classname((char *) name);
1073 c = load_class_bootstrap(u);
1081 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1084 vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1086 /* keep compiler happy */
1093 /* GetSuperclass ***************************************************************
1095 If clazz represents any class other than the class Object, then
1096 this function returns the object that represents the superclass of
1097 the class specified by clazz.
1099 *******************************************************************************/
1101 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1105 java_lang_Class *co;
1107 TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1109 c = LLNI_classinfo_unwrap(sub);
1114 super = class_get_superclass(c);
1116 co = LLNI_classinfo_wrap(super);
1118 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1122 /* IsAssignableFrom ************************************************************
1124 Determines whether an object of sub can be safely cast to sup.
1126 *******************************************************************************/
1128 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1130 java_lang_Class *csup;
1131 java_lang_Class *csub;
1133 csup = (java_lang_Class *) sup;
1134 csub = (java_lang_Class *) sub;
1136 STATISTICS(jniinvokation());
1138 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1142 /* Throw ***********************************************************************
1144 Causes a java.lang.Throwable object to be thrown.
1146 *******************************************************************************/
1148 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1152 STATISTICS(jniinvokation());
1154 o = (java_handle_t *) obj;
1156 exceptions_set_exception(o);
1162 /* ThrowNew ********************************************************************
1164 Constructs an exception object from the specified class with the
1165 message specified by message and causes that exception to be
1168 *******************************************************************************/
1170 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1176 STATISTICS(jniinvokation());
1178 c = LLNI_classinfo_unwrap(clazz);
1181 s = javastring_new_from_utf_string(msg);
1183 /* instantiate exception object */
1185 o = native_new_and_init_string(c, s);
1190 exceptions_set_exception(o);
1196 /* ExceptionOccurred ***********************************************************
1198 Determines if an exception is being thrown. The exception stays
1199 being thrown until either the native code calls ExceptionClear(),
1200 or the Java code handles the exception.
1202 *******************************************************************************/
1204 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1208 TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1210 o = exceptions_get_exception();
1212 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1216 /* ExceptionDescribe ***********************************************************
1218 Prints an exception and a backtrace of the stack to a system
1219 error-reporting channel, such as stderr. This is a convenience
1220 routine provided for debugging.
1222 *******************************************************************************/
1224 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1230 TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1232 /* Clear exception, because we are probably calling Java code
1235 o = exceptions_get_and_clear_exception();
1238 /* get printStackTrace method from exception class */
1240 LLNI_class_get(o, c);
1242 m = class_resolveclassmethod(c,
1243 utf_printStackTrace,
1249 vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1251 /* Print the stacktrace. */
1253 (void) vm_call_method(m, o);
1258 /* ExceptionClear **************************************************************
1260 Clears any exception that is currently being thrown. If no
1261 exception is currently being thrown, this routine has no effect.
1263 *******************************************************************************/
1265 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1267 STATISTICS(jniinvokation());
1269 exceptions_clear_exception();
1273 /* FatalError ******************************************************************
1275 Raises a fatal error and does not expect the VM to recover. This
1276 function does not return.
1278 *******************************************************************************/
1280 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1282 STATISTICS(jniinvokation());
1284 /* this seems to be the best way */
1286 vm_abort("JNI Fatal error: %s", msg);
1290 /* PushLocalFrame **************************************************************
1292 Creates a new local reference frame, in which at least a given
1293 number of local references can be created.
1295 *******************************************************************************/
1297 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1299 STATISTICS(jniinvokation());
1304 /* add new local reference frame to current table */
1306 if (!localref_frame_push(capacity))
1313 /* PopLocalFrame ***************************************************************
1315 Pops off the current local reference frame, frees all the local
1316 references, and returns a local reference in the previous local
1317 reference frame for the given result object.
1319 *******************************************************************************/
1321 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1323 STATISTICS(jniinvokation());
1325 /* release all current local frames */
1327 localref_frame_pop_all();
1329 /* add local reference and return the value */
1331 return _Jv_JNI_NewLocalRef(env, result);
1335 /* DeleteLocalRef **************************************************************
1337 Deletes the local reference pointed to by localRef.
1339 *******************************************************************************/
1341 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1345 STATISTICS(jniinvokation());
1347 o = (java_handle_t *) localRef;
1349 /* delete the reference */
1355 /* IsSameObject ****************************************************************
1357 Tests whether two references refer to the same Java object.
1359 *******************************************************************************/
1361 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1367 STATISTICS(jniinvokation());
1369 o1 = (java_handle_t *) ref1;
1370 o2 = (java_handle_t *) ref2;
1372 LLNI_CRITICAL_START;
1374 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1385 /* NewLocalRef *****************************************************************
1387 Creates a new local reference that refers to the same object as ref.
1389 *******************************************************************************/
1391 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1394 java_handle_t *localref;
1396 STATISTICS(jniinvokation());
1401 o = (java_handle_t *) ref;
1403 /* insert the reference */
1405 localref = localref_add(LLNI_DIRECT(o));
1411 /* EnsureLocalCapacity *********************************************************
1413 Ensures that at least a given number of local references can be
1414 created in the current thread
1416 *******************************************************************************/
1418 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1420 localref_table *lrt;
1422 STATISTICS(jniinvokation());
1424 /* get local reference table (thread specific) */
1426 lrt = LOCALREFTABLE;
1428 /* check if capacity elements are available in the local references table */
1430 if ((lrt->used + capacity) > lrt->capacity)
1431 return _Jv_JNI_PushLocalFrame(env, capacity);
1437 /* AllocObject *****************************************************************
1439 Allocates a new Java object without invoking any of the
1440 constructors for the object. Returns a reference to the object.
1442 *******************************************************************************/
1444 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1449 STATISTICS(jniinvokation());
1451 c = LLNI_classinfo_unwrap(clazz);
1453 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1454 exceptions_throw_instantiationexception(c);
1460 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1464 /* NewObject *******************************************************************
1466 Programmers place all arguments that are to be passed to the
1467 constructor immediately following the methodID
1468 argument. NewObject() accepts these arguments and passes them to
1469 the Java method that the programmer wishes to invoke.
1471 *******************************************************************************/
1473 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1480 STATISTICS(jniinvokation());
1482 c = LLNI_classinfo_unwrap(clazz);
1483 m = (methodinfo *) methodID;
1492 /* call constructor */
1494 va_start(ap, methodID);
1495 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1498 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1502 /* NewObjectV ******************************************************************
1504 Programmers place all arguments that are to be passed to the
1505 constructor in an args argument of type va_list that immediately
1506 follows the methodID argument. NewObjectV() accepts these
1507 arguments, and, in turn, passes them to the Java method that the
1508 programmer wishes to invoke.
1510 *******************************************************************************/
1512 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1519 STATISTICS(jniinvokation());
1521 c = LLNI_classinfo_unwrap(clazz);
1522 m = (methodinfo *) methodID;
1531 /* call constructor */
1533 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1535 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1539 /* NewObjectA *****************************************************************
1541 Programmers place all arguments that are to be passed to the
1542 constructor in an args array of jvalues that immediately follows
1543 the methodID argument. NewObjectA() accepts the arguments in this
1544 array, and, in turn, passes them to the Java method that the
1545 programmer wishes to invoke.
1547 *******************************************************************************/
1549 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1556 STATISTICS(jniinvokation());
1558 c = LLNI_classinfo_unwrap(clazz);
1559 m = (methodinfo *) methodID;
1568 /* call constructor */
1570 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1572 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1576 /* GetObjectClass **************************************************************
1578 Returns the class of an object.
1580 *******************************************************************************/
1582 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1586 java_lang_Class *co;
1588 STATISTICS(jniinvokation());
1590 o = (java_handle_t *) obj;
1592 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1595 LLNI_class_get(o, c);
1597 co = LLNI_classinfo_wrap(c);
1599 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1603 /* IsInstanceOf ****************************************************************
1605 Tests whether an object is an instance of a class.
1607 *******************************************************************************/
1609 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1612 java_lang_Object *o;
1614 STATISTICS(jniinvokation());
1616 c = (java_lang_Class *) clazz;
1617 o = (java_lang_Object *) obj;
1619 return _Jv_java_lang_Class_isInstance(c, o);
1623 /* Reflection Support *********************************************************/
1625 /* FromReflectedMethod *********************************************************
1627 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1628 object to a method ID.
1630 *******************************************************************************/
1632 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1634 #if defined(ENABLE_JAVASE)
1640 STATISTICS(jniinvokation());
1642 o = (java_handle_t *) method;
1647 if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1648 java_lang_reflect_Method *rm;
1650 rm = (java_lang_reflect_Method *) method;
1651 LLNI_field_get_cls(rm, clazz, c);
1652 LLNI_field_get_val(rm, slot , slot);
1654 else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1655 java_lang_reflect_Constructor *rc;
1657 rc = (java_lang_reflect_Constructor *) method;
1658 LLNI_field_get_cls(rc, clazz, c);
1659 LLNI_field_get_val(rc, slot , slot);
1664 m = &(c->methods[slot]);
1666 return (jmethodID) m;
1668 vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1670 /* keep compiler happy */
1677 /* FromReflectedField **********************************************************
1679 Converts a java.lang.reflect.Field to a field ID.
1681 *******************************************************************************/
1683 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1685 #if defined(ENABLE_JAVASE)
1686 java_lang_reflect_Field *rf;
1691 STATISTICS(jniinvokation());
1693 rf = (java_lang_reflect_Field *) field;
1698 LLNI_field_get_cls(rf, clazz, c);
1699 LLNI_field_get_val(rf, slot , slot);
1700 f = &(c->fields[slot]);
1702 return (jfieldID) f;
1704 vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1706 /* keep compiler happy */
1713 /* ToReflectedMethod ***********************************************************
1715 Converts a method ID derived from cls to an instance of the
1716 java.lang.reflect.Method class or to an instance of the
1717 java.lang.reflect.Constructor class.
1719 *******************************************************************************/
1721 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1724 #if defined(ENABLE_JAVASE)
1726 java_lang_reflect_Constructor *rc;
1727 java_lang_reflect_Method *rm;
1729 TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1731 m = (methodinfo *) methodID;
1733 /* HotSpot does the same assert. */
1735 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1737 if (m->name == utf_init) {
1738 rc = reflect_constructor_new(m);
1740 return (jobject) rc;
1743 rm = reflect_method_new(m);
1745 return (jobject) rm;
1748 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1750 /* keep compiler happy */
1757 /* ToReflectedField ************************************************************
1759 Converts a field ID derived from cls to an instance of the
1760 java.lang.reflect.Field class.
1762 *******************************************************************************/
1764 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1767 STATISTICS(jniinvokation());
1769 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1775 /* Calling Instance Methods ***************************************************/
1777 /* GetMethodID *****************************************************************
1779 Returns the method ID for an instance (nonstatic) method of a class
1780 or interface. The method may be defined in one of the clazz's
1781 superclasses and inherited by clazz. The method is determined by
1782 its name and signature.
1784 GetMethodID() causes an uninitialized class to be initialized.
1786 *******************************************************************************/
1788 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1796 STATISTICS(jniinvokation());
1798 c = LLNI_classinfo_unwrap(clazz);
1803 if (!(c->state & CLASS_INITIALIZED))
1804 if (!initialize_class(c))
1807 /* try to get the method of the class or one of it's superclasses */
1809 uname = utf_new_char((char *) name);
1810 udesc = utf_new_char((char *) sig);
1812 m = class_resolvemethod(c, uname, udesc);
1814 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1815 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1820 return (jmethodID) m;
1824 /* JNI-functions for calling instance methods *********************************/
1826 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1827 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1828 jmethodID methodID, ...) \
1835 o = (java_handle_t *) obj; \
1836 m = (methodinfo *) methodID; \
1838 va_start(ap, methodID); \
1839 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1845 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1846 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1847 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1848 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1849 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1850 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1851 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1852 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1855 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1856 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1857 jmethodID methodID, va_list args) \
1863 o = (java_handle_t *) obj; \
1864 m = (methodinfo *) methodID; \
1866 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1871 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1872 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1873 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1874 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1875 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1876 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1877 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1878 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1881 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1882 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1883 jmethodID methodID, \
1884 const jvalue *args) \
1890 o = (java_handle_t *) obj; \
1891 m = (methodinfo *) methodID; \
1893 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1898 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1899 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1900 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1901 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1902 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1903 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1904 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1905 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1908 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1916 o = (java_handle_t *) obj;
1917 m = (methodinfo *) methodID;
1919 va_start(ap, methodID);
1920 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1923 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1927 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1934 o = (java_handle_t *) obj;
1935 m = (methodinfo *) methodID;
1937 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1939 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1943 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1950 o = (java_handle_t *) obj;
1951 m = (methodinfo *) methodID;
1953 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1955 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1960 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1966 o = (java_handle_t *) obj;
1967 m = (methodinfo *) methodID;
1969 va_start(ap, methodID);
1970 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1975 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1981 o = (java_handle_t *) obj;
1982 m = (methodinfo *) methodID;
1984 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1988 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1994 o = (java_handle_t *) obj;
1995 m = (methodinfo *) methodID;
1997 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
2002 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
2003 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
2004 jclass clazz, jmethodID methodID, \
2013 o = (java_handle_t *) obj; \
2014 c = LLNI_classinfo_unwrap(clazz); \
2015 m = (methodinfo *) methodID; \
2017 va_start(ap, methodID); \
2018 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
2024 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
2025 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
2026 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
2027 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
2028 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
2029 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
2030 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
2031 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
2034 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
2035 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
2036 jclass clazz, jmethodID methodID, \
2044 o = (java_handle_t *) obj; \
2045 c = LLNI_classinfo_unwrap(clazz); \
2046 m = (methodinfo *) methodID; \
2048 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
2053 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2054 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
2055 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
2056 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
2057 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
2058 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
2059 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
2060 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
2063 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
2064 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
2065 jclass clazz, jmethodID methodID, \
2066 const jvalue *args) \
2068 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
2073 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2074 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
2075 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
2076 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
2077 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
2078 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
2079 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
2080 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
2082 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2083 jclass clazz, jmethodID methodID,
2092 o = (java_handle_t *) obj;
2093 c = LLNI_classinfo_unwrap(clazz);
2094 m = (methodinfo *) methodID;
2096 va_start(ap, methodID);
2097 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2100 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2104 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2105 jclass clazz, jmethodID methodID,
2113 o = (java_handle_t *) obj;
2114 c = LLNI_classinfo_unwrap(clazz);
2115 m = (methodinfo *) methodID;
2117 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2119 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2123 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2124 jclass clazz, jmethodID methodID,
2127 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2129 return _Jv_JNI_NewLocalRef(env, NULL);
2133 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2134 jmethodID methodID, ...)
2141 o = (java_handle_t *) obj;
2142 c = LLNI_classinfo_unwrap(clazz);
2143 m = (methodinfo *) methodID;
2145 va_start(ap, methodID);
2146 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2151 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2152 jmethodID methodID, va_list args)
2158 o = (java_handle_t *) obj;
2159 c = LLNI_classinfo_unwrap(clazz);
2160 m = (methodinfo *) methodID;
2162 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2166 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2167 jmethodID methodID, const jvalue * args)
2173 o = (java_handle_t *) obj;
2174 c = LLNI_classinfo_unwrap(clazz);
2175 m = (methodinfo *) methodID;
2177 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2181 /* Accessing Fields of Objects ************************************************/
2183 /* GetFieldID ******************************************************************
2185 Returns the field ID for an instance (nonstatic) field of a
2186 class. The field is specified by its name and signature. The
2187 Get<type>Field and Set<type>Field families of accessor functions
2188 use field IDs to retrieve object fields.
2190 *******************************************************************************/
2192 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2200 STATISTICS(jniinvokation());
2202 c = LLNI_classinfo_unwrap(clazz);
2204 /* XXX NPE check? */
2206 uname = utf_new_char((char *) name);
2207 udesc = utf_new_char((char *) sig);
2209 f = class_findfield(c, uname, udesc);
2212 exceptions_throw_nosuchfielderror(c, uname);
2214 return (jfieldID) f;
2218 /* Get<type>Field Routines *****************************************************
2220 This family of accessor routines returns the value of an instance
2221 (nonstatic) field of an object. The field to access is specified by
2222 a field ID obtained by calling GetFieldID().
2224 *******************************************************************************/
2226 #define JNI_GET_FIELD(name, type, intern) \
2227 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2231 STATISTICS(jniinvokation()); \
2233 ret = GET_FIELD(obj, intern, fieldID); \
2235 return (type) ret; \
2238 JNI_GET_FIELD(Boolean, jboolean, s4)
2239 JNI_GET_FIELD(Byte, jbyte, s4)
2240 JNI_GET_FIELD(Char, jchar, s4)
2241 JNI_GET_FIELD(Short, jshort, s4)
2242 JNI_GET_FIELD(Int, jint, s4)
2243 JNI_GET_FIELD(Long, jlong, s8)
2244 JNI_GET_FIELD(Float, jfloat, float)
2245 JNI_GET_FIELD(Double, jdouble, double)
2248 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2252 TRACEJNICALLS("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID);
2254 LLNI_CRITICAL_START;
2256 o = LLNI_WRAP(GET_FIELD(obj, java_handle_t*, fieldID));
2260 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2264 /* Set<type>Field Routines *****************************************************
2266 This family of accessor routines sets the value of an instance
2267 (nonstatic) field of an object. The field to access is specified by
2268 a field ID obtained by calling GetFieldID().
2270 *******************************************************************************/
2272 #define JNI_SET_FIELD(name, type, intern) \
2273 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2276 STATISTICS(jniinvokation()); \
2278 SET_FIELD(obj, intern, fieldID, value); \
2281 JNI_SET_FIELD(Boolean, jboolean, s4)
2282 JNI_SET_FIELD(Byte, jbyte, s4)
2283 JNI_SET_FIELD(Char, jchar, s4)
2284 JNI_SET_FIELD(Short, jshort, s4)
2285 JNI_SET_FIELD(Int, jint, s4)
2286 JNI_SET_FIELD(Long, jlong, s8)
2287 JNI_SET_FIELD(Float, jfloat, float)
2288 JNI_SET_FIELD(Double, jdouble, double)
2291 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2294 TRACEJNICALLS("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value);
2296 LLNI_CRITICAL_START;
2298 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP(value));
2304 /* Calling Static Methods *****************************************************/
2306 /* GetStaticMethodID ***********************************************************
2308 Returns the method ID for a static method of a class. The method is
2309 specified by its name and signature.
2311 GetStaticMethodID() causes an uninitialized class to be
2314 *******************************************************************************/
2316 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2324 TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2326 c = LLNI_classinfo_unwrap(clazz);
2331 if (!(c->state & CLASS_INITIALIZED))
2332 if (!initialize_class(c))
2335 /* try to get the static method of the class */
2337 uname = utf_new_char((char *) name);
2338 udesc = utf_new_char((char *) sig);
2340 m = class_resolvemethod(c, uname, udesc);
2342 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2343 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2348 return (jmethodID) m;
2352 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2353 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2354 jmethodID methodID, ...) \
2360 m = (methodinfo *) methodID; \
2362 va_start(ap, methodID); \
2363 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2369 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2370 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2371 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2372 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2373 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2374 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2375 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2376 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2379 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2380 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2381 jmethodID methodID, va_list args) \
2386 m = (methodinfo *) methodID; \
2388 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2393 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2394 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2395 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2396 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2397 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2398 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2399 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2400 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2403 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2404 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2405 jmethodID methodID, const jvalue *args) \
2410 m = (methodinfo *) methodID; \
2412 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2417 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2418 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2419 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2420 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2421 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2422 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2423 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2424 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2427 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2428 jmethodID methodID, ...)
2434 m = (methodinfo *) methodID;
2436 va_start(ap, methodID);
2437 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2440 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2444 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2445 jmethodID methodID, va_list args)
2450 m = (methodinfo *) methodID;
2452 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2454 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2458 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2459 jmethodID methodID, const jvalue *args)
2464 m = (methodinfo *) methodID;
2466 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2468 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2472 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2473 jmethodID methodID, ...)
2478 m = (methodinfo *) methodID;
2480 va_start(ap, methodID);
2481 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2486 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2487 jmethodID methodID, va_list args)
2491 m = (methodinfo *) methodID;
2493 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2497 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2498 jmethodID methodID, const jvalue * args)
2502 m = (methodinfo *) methodID;
2504 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2508 /* Accessing Static Fields ****************************************************/
2510 /* GetStaticFieldID ************************************************************
2512 Returns the field ID for a static field of a class. The field is
2513 specified by its name and signature. The GetStatic<type>Field and
2514 SetStatic<type>Field families of accessor functions use field IDs
2515 to retrieve static fields.
2517 *******************************************************************************/
2519 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2527 STATISTICS(jniinvokation());
2529 c = LLNI_classinfo_unwrap(clazz);
2531 uname = utf_new_char((char *) name);
2532 usig = utf_new_char((char *) sig);
2534 f = class_findfield(c, uname, usig);
2537 exceptions_throw_nosuchfielderror(c, uname);
2539 return (jfieldID) f;
2543 /* GetStatic<type>Field ********************************************************
2545 This family of accessor routines returns the value of a static
2548 *******************************************************************************/
2550 #define JNI_GET_STATIC_FIELD(name, type, field) \
2551 type _Jv_JNI_GetStatic##name##Field(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 f->value->field; \
2569 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2570 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2571 JNI_GET_STATIC_FIELD(Char, jchar, i)
2572 JNI_GET_STATIC_FIELD(Short, jshort, i)
2573 JNI_GET_STATIC_FIELD(Int, jint, i)
2574 JNI_GET_STATIC_FIELD(Long, jlong, l)
2575 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2576 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2579 jobject _Jv_JNI_GetStaticObjectField(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 return _Jv_JNI_NewLocalRef(env, f->value->a);
2598 /* SetStatic<type>Field *******************************************************
2600 This family of accessor routines sets the value of a static field
2603 *******************************************************************************/
2605 #define JNI_SET_STATIC_FIELD(name, type, field) \
2606 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
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->field = value; \
2625 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2626 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2627 JNI_SET_STATIC_FIELD(Char, jchar, i)
2628 JNI_SET_STATIC_FIELD(Short, jshort, i)
2629 JNI_SET_STATIC_FIELD(Int, jint, i)
2630 JNI_SET_STATIC_FIELD(Long, jlong, l)
2631 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2632 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2635 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2641 STATISTICS(jniinvokation());
2643 c = LLNI_classinfo_unwrap(clazz);
2644 f = (fieldinfo *) fieldID;
2646 if (!(c->state & CLASS_INITIALIZED))
2647 if (!initialize_class(c))
2650 f->value->a = value;
2654 /* String Operations **********************************************************/
2656 /* NewString *******************************************************************
2658 Create new java.lang.String object from an array of Unicode
2661 *******************************************************************************/
2663 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2665 java_lang_String *s;
2666 java_handle_chararray_t *a;
2669 STATISTICS(jniinvokation());
2671 s = (java_lang_String *) builtin_new(class_java_lang_String);
2672 a = builtin_newarray_char(len);
2674 /* javastring or characterarray could not be created */
2675 if ((a == NULL) || (s == NULL))
2679 for (i = 0; i < len; i++)
2680 LLNI_array_direct(a, i) = buf[i];
2682 LLNI_field_set_ref(s, value , a);
2683 LLNI_field_set_val(s, offset, 0);
2684 LLNI_field_set_val(s, count , len);
2686 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2690 static jchar emptyStringJ[]={0,0};
2692 /* GetStringLength *************************************************************
2694 Returns the length (the count of Unicode characters) of a Java
2697 *******************************************************************************/
2699 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2701 java_lang_String *s;
2704 TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2706 s = (java_lang_String *) str;
2708 LLNI_field_get_val(s, count, len);
2714 /******************** convertes javastring to u2-array ****************************/
2716 u2 *javastring_tou2(jstring so)
2718 java_lang_String *s;
2719 java_handle_chararray_t *a;
2725 STATISTICS(jniinvokation());
2727 s = (java_lang_String *) so;
2732 LLNI_field_get_ref(s, value, a);
2737 LLNI_field_get_val(s, count, count);
2738 LLNI_field_get_val(s, offset, offset);
2740 /* allocate memory */
2742 stringbuffer = MNEW(u2, count + 1);
2746 for (i = 0; i < count; i++)
2747 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2749 /* terminate string */
2751 stringbuffer[i] = '\0';
2753 return stringbuffer;
2757 /* GetStringChars **************************************************************
2759 Returns a pointer to the array of Unicode characters of the
2760 string. This pointer is valid until ReleaseStringChars() is called.
2762 *******************************************************************************/
2764 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2768 STATISTICS(jniinvokation());
2770 jc = javastring_tou2(str);
2782 return emptyStringJ;
2786 /* ReleaseStringChars **********************************************************
2788 Informs the VM that the native code no longer needs access to
2789 chars. The chars argument is a pointer obtained from string using
2792 *******************************************************************************/
2794 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2796 java_lang_String *s;
2798 STATISTICS(jniinvokation());
2800 if (chars == emptyStringJ)
2803 s = (java_lang_String *) str;
2805 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2809 /* NewStringUTF ****************************************************************
2811 Constructs a new java.lang.String object from an array of UTF-8
2814 *******************************************************************************/
2816 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2818 java_lang_String *s;
2820 TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2822 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2824 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2828 /****************** returns the utf8 length in bytes of a string *******************/
2830 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2832 java_lang_String *s;
2835 TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2837 s = (java_lang_String *) string;
2839 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2845 /* GetStringUTFChars ***********************************************************
2847 Returns a pointer to an array of UTF-8 characters of the
2848 string. This array is valid until it is released by
2849 ReleaseStringUTFChars().
2851 *******************************************************************************/
2853 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2858 STATISTICS(jniinvokation());
2866 u = javastring_toutf((java_handle_t *) string, false);
2875 /* ReleaseStringUTFChars *******************************************************
2877 Informs the VM that the native code no longer needs access to
2878 utf. The utf argument is a pointer derived from string using
2879 GetStringUTFChars().
2881 *******************************************************************************/
2883 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2885 STATISTICS(jniinvokation());
2887 /* XXX we don't release utf chars right now, perhaps that should be done
2888 later. Since there is always one reference the garbage collector will
2893 /* Array Operations ***********************************************************/
2895 /* GetArrayLength **************************************************************
2897 Returns the number of elements in the array.
2899 *******************************************************************************/
2901 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2906 STATISTICS(jniinvokation());
2908 a = (java_handle_t *) array;
2910 size = LLNI_array_size(a);
2916 /* NewObjectArray **************************************************************
2918 Constructs a new array holding objects in class elementClass. All
2919 elements are initially set to initialElement.
2921 *******************************************************************************/
2923 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2924 jclass elementClass, jobject initialElement)
2928 java_handle_objectarray_t *oa;
2931 STATISTICS(jniinvokation());
2933 c = LLNI_classinfo_unwrap(elementClass);
2934 o = (java_handle_t *) initialElement;
2937 exceptions_throw_negativearraysizeexception();
2941 oa = builtin_anewarray(length, c);
2946 /* set all elements to initialElement */
2948 for (i = 0; i < length; i++)
2949 LLNI_objectarray_element_set(oa, i, o);
2951 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2955 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2958 java_handle_objectarray_t *oa;
2961 STATISTICS(jniinvokation());
2963 oa = (java_handle_objectarray_t *) array;
2965 if (index >= LLNI_array_size(oa)) {
2966 exceptions_throw_arrayindexoutofboundsexception();
2970 LLNI_objectarray_element_get(oa, index, o);
2972 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2976 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2977 jsize index, jobject val)
2979 java_handle_objectarray_t *oa;
2982 STATISTICS(jniinvokation());
2984 oa = (java_handle_objectarray_t *) array;
2985 o = (java_handle_t *) val;
2987 if (index >= LLNI_array_size(oa)) {
2988 exceptions_throw_arrayindexoutofboundsexception();
2992 /* check if the class of value is a subclass of the element class
2995 if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2998 LLNI_objectarray_element_set(oa, index, o);
3002 #define JNI_NEW_ARRAY(name, type, intern) \
3003 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
3005 java_handle_##intern##array_t *a; \
3007 STATISTICS(jniinvokation()); \
3010 exceptions_throw_negativearraysizeexception(); \
3014 a = builtin_newarray_##intern(len); \
3016 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
3019 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
3020 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
3021 JNI_NEW_ARRAY(Char, jcharArray, char)
3022 JNI_NEW_ARRAY(Short, jshortArray, byte)
3023 JNI_NEW_ARRAY(Int, jintArray, int)
3024 JNI_NEW_ARRAY(Long, jlongArray, long)
3025 JNI_NEW_ARRAY(Float, jfloatArray, float)
3026 JNI_NEW_ARRAY(Double, jdoubleArray, double)
3029 /* Get<PrimitiveType>ArrayElements *********************************************
3031 A family of functions that returns the body of the primitive array.
3033 *******************************************************************************/
3035 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
3036 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
3039 java_handle_##intern##array_t *a; \
3041 STATISTICS(jniinvokation()); \
3043 a = (java_handle_##intern##array_t *) array; \
3046 *isCopy = JNI_FALSE; \
3048 return LLNI_array_data(a); \
3051 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3052 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
3053 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
3054 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
3055 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
3056 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
3057 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
3058 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
3061 /* Release<PrimitiveType>ArrayElements *****************************************
3063 A family of functions that informs the VM that the native code no
3064 longer needs access to elems. The elems argument is a pointer
3065 derived from array using the corresponding
3066 Get<PrimitiveType>ArrayElements() function. If necessary, this
3067 function copies back all changes made to elems to the original
3070 *******************************************************************************/
3072 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
3073 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
3074 type *elems, jint mode) \
3076 java_handle_##intern##array_t *a; \
3078 STATISTICS(jniinvokation()); \
3080 a = (java_handle_##intern##array_t *) array; \
3082 if (elems != LLNI_array_data(a)) { \
3085 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3088 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3089 /* XXX TWISTI how should it be freed? */ \
3092 /* XXX TWISTI how should it be freed? */ \
3098 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3099 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3100 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3101 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3102 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3103 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3104 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3105 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3108 /* Get<PrimitiveType>ArrayRegion **********************************************
3110 A family of functions that copies a region of a primitive array
3113 *******************************************************************************/
3115 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3116 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3117 jsize start, jsize len, type *buf) \
3119 java_handle_##intern##array_t *a; \
3121 STATISTICS(jniinvokation()); \
3123 a = (java_handle_##intern##array_t *) array; \
3125 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3126 exceptions_throw_arrayindexoutofboundsexception(); \
3128 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3131 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3132 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3133 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3134 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3135 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3136 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3137 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3138 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3141 /* Set<PrimitiveType>ArrayRegion **********************************************
3143 A family of functions that copies back a region of a primitive
3144 array from a buffer.
3146 *******************************************************************************/
3148 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3149 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3150 jsize start, jsize len, const type *buf) \
3152 java_handle_##intern##array_t *a; \
3154 STATISTICS(jniinvokation()); \
3156 a = (java_handle_##intern##array_t *) array; \
3158 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3159 exceptions_throw_arrayindexoutofboundsexception(); \
3161 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3164 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3165 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3166 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3167 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3168 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3169 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3170 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3171 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3174 /* Registering Native Methods *************************************************/
3176 /* RegisterNatives *************************************************************
3178 Registers native methods with the class specified by the clazz
3179 argument. The methods parameter specifies an array of
3180 JNINativeMethod structures that contain the names, signatures, and
3181 function pointers of the native methods. The nMethods parameter
3182 specifies the number of native methods in the array.
3184 *******************************************************************************/
3186 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3187 const JNINativeMethod *methods, jint nMethods)
3191 STATISTICS(jniinvokation());
3193 c = LLNI_classinfo_unwrap(clazz);
3195 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3196 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3199 native_method_register(c->name, methods, nMethods);
3205 /* UnregisterNatives ***********************************************************
3207 Unregisters native methods of a class. The class goes back to the
3208 state before it was linked or registered with its native method
3211 This function should not be used in normal native code. Instead, it
3212 provides special programs a way to reload and relink native
3215 *******************************************************************************/
3217 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3219 STATISTICS(jniinvokation());
3221 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3223 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3229 /* Monitor Operations *********************************************************/
3231 /* MonitorEnter ****************************************************************
3233 Enters the monitor associated with the underlying Java object
3236 *******************************************************************************/
3238 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3240 STATISTICS(jniinvokation());
3243 exceptions_throw_nullpointerexception();
3247 LOCK_MONITOR_ENTER(obj);
3253 /* MonitorExit *****************************************************************
3255 The current thread must be the owner of the monitor associated with
3256 the underlying Java object referred to by obj. The thread
3257 decrements the counter indicating the number of times it has
3258 entered this monitor. If the value of the counter becomes zero, the
3259 current thread releases the monitor.
3261 *******************************************************************************/
3263 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3265 STATISTICS(jniinvokation());
3268 exceptions_throw_nullpointerexception();
3272 LOCK_MONITOR_EXIT(obj);
3278 /* JavaVM Interface ***********************************************************/
3280 /* GetJavaVM *******************************************************************
3282 Returns the Java VM interface (used in the Invocation API)
3283 associated with the current thread. The result is placed at the
3284 location pointed to by the second argument, vm.
3286 *******************************************************************************/
3288 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3290 STATISTICS(jniinvokation());
3292 *vm = (JavaVM *) _Jv_jvm;
3298 /* GetStringRegion *************************************************************
3300 Copies len number of Unicode characters beginning at offset start
3301 to the given buffer buf.
3303 Throws StringIndexOutOfBoundsException on index overflow.
3305 *******************************************************************************/
3307 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3310 java_lang_String *s;
3311 java_handle_chararray_t *ca;
3313 STATISTICS(jniinvokation());
3315 s = (java_lang_String *) str;
3316 LLNI_field_get_ref(s, value, ca);
3318 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3319 (start + len > LLNI_field_direct(s, count))) {
3320 exceptions_throw_stringindexoutofboundsexception();
3324 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3328 /* GetStringUTFRegion **********************************************************
3330 Translates len number of Unicode characters beginning at offset
3331 start into UTF-8 format and place the result in the given buffer
3334 Throws StringIndexOutOfBoundsException on index overflow.
3336 *******************************************************************************/
3338 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3339 jsize len, char *buf)
3341 java_lang_String *s;
3342 java_handle_chararray_t *ca;
3347 TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3349 s = (java_lang_String *) str;
3350 LLNI_field_get_ref(s, value, ca);
3351 LLNI_field_get_val(s, count, count);
3352 LLNI_field_get_val(s, offset, offset);
3354 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3355 exceptions_throw_stringindexoutofboundsexception();
3359 for (i = 0; i < len; i++)
3360 buf[i] = LLNI_array_direct(ca, offset + start + i);
3366 /* GetPrimitiveArrayCritical ***************************************************
3368 Obtain a direct pointer to array elements.
3370 *******************************************************************************/
3372 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3375 java_handle_bytearray_t *ba;
3378 ba = (java_handle_bytearray_t *) array;
3380 /* do the same as Kaffe does */
3382 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3388 /* ReleasePrimitiveArrayCritical ***********************************************
3390 No specific documentation.
3392 *******************************************************************************/
3394 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3395 void *carray, jint mode)
3397 STATISTICS(jniinvokation());
3399 /* do the same as Kaffe does */
3401 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3406 /* GetStringCritical ***********************************************************
3408 The semantics of these two functions are similar to the existing
3409 Get/ReleaseStringChars functions.
3411 *******************************************************************************/
3413 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3416 STATISTICS(jniinvokation());
3418 return _Jv_JNI_GetStringChars(env, string, isCopy);
3422 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3423 const jchar *cstring)
3425 STATISTICS(jniinvokation());
3427 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3431 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3433 TRACEJNICALLS("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj);
3439 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3441 TRACEJNICALLS("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref);
3445 /* NewGlobalRef ****************************************************************
3447 Creates a new global reference to the object referred to by the obj
3450 *******************************************************************************/
3452 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3454 hashtable_global_ref_entry *gre;
3455 u4 key; /* hashkey */
3456 u4 slot; /* slot in hashtable */
3459 STATISTICS(jniinvokation());
3461 o = (java_handle_t *) obj;
3463 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3465 LLNI_CRITICAL_START;
3467 /* normally addresses are aligned to 4, 8 or 16 bytes */
3469 #if defined(ENABLE_GC_CACAO)
3470 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3472 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3474 slot = key & (hashtable_global_ref->size - 1);
3475 gre = hashtable_global_ref->ptr[slot];
3477 /* search external hash chain for the entry */
3480 if (gre->o == LLNI_DIRECT(o)) {
3481 /* global object found, increment the reference */
3488 gre = gre->hashlink; /* next element in external chain */
3491 /* global ref not found, create a new one */
3494 gre = NEW(hashtable_global_ref_entry);
3496 #if defined(ENABLE_GC_CACAO)
3497 /* register global ref with the GC */
3499 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3502 gre->o = LLNI_DIRECT(o);
3505 /* insert entry into hashtable */
3507 gre->hashlink = hashtable_global_ref->ptr[slot];
3509 hashtable_global_ref->ptr[slot] = gre;
3511 /* update number of hashtable-entries */
3513 hashtable_global_ref->entries++;
3518 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3520 #if defined(ENABLE_HANDLES)
3528 /* DeleteGlobalRef *************************************************************
3530 Deletes the global reference pointed to by globalRef.
3532 *******************************************************************************/
3534 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3536 hashtable_global_ref_entry *gre;
3537 hashtable_global_ref_entry *prevgre;
3538 u4 key; /* hashkey */
3539 u4 slot; /* slot in hashtable */
3542 STATISTICS(jniinvokation());
3544 o = (java_handle_t *) globalRef;
3546 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3548 LLNI_CRITICAL_START;
3550 /* normally addresses are aligned to 4, 8 or 16 bytes */
3552 #if defined(ENABLE_GC_CACAO)
3553 key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3555 key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
3557 slot = key & (hashtable_global_ref->size - 1);
3558 gre = hashtable_global_ref->ptr[slot];
3560 /* initialize prevgre */
3564 /* search external hash chain for the entry */
3567 if (gre->o == LLNI_DIRECT(o)) {
3568 /* global object found, decrement the reference count */
3572 /* if reference count is 0, remove the entry */
3574 if (gre->refs == 0) {
3575 /* special handling if it's the first in the chain */
3577 if (prevgre == NULL)
3578 hashtable_global_ref->ptr[slot] = gre->hashlink;
3580 prevgre->hashlink = gre->hashlink;
3582 #if defined(ENABLE_GC_CACAO)
3583 /* unregister global ref with the GC */
3585 gc_reference_unregister(&(gre->o));
3588 FREE(gre, hashtable_global_ref_entry);
3593 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3598 prevgre = gre; /* save current pointer for removal */
3599 gre = gre->hashlink; /* next element in external chain */
3602 log_println("JNI-DeleteGlobalRef: global reference not found");
3606 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3610 /* ExceptionCheck **************************************************************
3612 Returns JNI_TRUE when there is a pending exception; otherwise,
3615 *******************************************************************************/
3617 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3621 STATISTICS(jniinvokation());
3623 o = exceptions_get_exception();
3625 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3629 /* New JNI 1.4 functions ******************************************************/
3631 /* NewDirectByteBuffer *********************************************************
3633 Allocates and returns a direct java.nio.ByteBuffer referring to the
3634 block of memory starting at the memory address address and
3635 extending capacity bytes.
3637 *******************************************************************************/
3639 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3641 #if defined(ENABLE_JAVASE)
3642 # if defined(WITH_CLASSPATH_GNU)
3643 java_handle_t *nbuf;
3645 # if SIZEOF_VOID_P == 8
3646 gnu_classpath_Pointer64 *paddress;
3648 gnu_classpath_Pointer32 *paddress;
3651 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3653 /* alocate a gnu.classpath.Pointer{32,64} object */
3655 # if SIZEOF_VOID_P == 8
3656 if (!(paddress = (gnu_classpath_Pointer64 *)
3657 builtin_new(class_gnu_classpath_Pointer64)))
3659 if (!(paddress = (gnu_classpath_Pointer32 *)
3660 builtin_new(class_gnu_classpath_Pointer32)))
3664 /* fill gnu.classpath.Pointer{32,64} with address */
3666 LLNI_field_set_val(paddress, data, (ptrint) address);
3668 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3670 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3671 (jmethodID) dbbirw_init, NULL, paddress,
3672 (jint) capacity, (jint) capacity, (jint) 0);
3674 /* add local reference and return the value */
3676 return _Jv_JNI_NewLocalRef(env, nbuf);
3678 # elif defined(WITH_CLASSPATH_SUN)
3684 TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3686 /* Be paranoid about address sign-extension. */
3688 addr = (int64_t) ((uintptr_t) address);
3689 cap = (int32_t) capacity;
3691 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3692 (jmethodID) dbb_init, addr, cap);
3694 /* Add local reference and return the value. */
3696 return _Jv_JNI_NewLocalRef(env, o);
3699 # error unknown classpath configuration
3703 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3705 /* keep compiler happy */
3712 /* GetDirectBufferAddress ******************************************************
3714 Fetches and returns the starting address of the memory region
3715 referenced by the given direct java.nio.Buffer.
3717 *******************************************************************************/
3719 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3721 #if defined(ENABLE_JAVASE)
3722 # if defined(WITH_CLASSPATH_GNU)
3724 java_nio_DirectByteBufferImpl *nbuf;
3725 # if SIZEOF_VOID_P == 8
3726 gnu_classpath_Pointer64 *paddress;
3728 gnu_classpath_Pointer32 *paddress;
3732 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3734 if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3737 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3739 # if SIZEOF_VOID_P == 8
3740 LLNI_field_get_ref(nbuf, address, paddress);
3741 /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3743 LLNI_field_get_ref(nbuf, address, paddress);
3744 /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3747 if (paddress == NULL)
3750 LLNI_field_get_val(paddress, data, address);
3751 /* this was the cast to avaoid warning: (void *) paddress->data */
3755 # elif defined(WITH_CLASSPATH_SUN)
3761 TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3763 if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3766 o = (java_nio_Buffer *) buf;
3768 LLNI_field_get_val(o, address, address);
3770 p = (void *) (intptr_t) address;
3775 # error unknown classpath configuration
3780 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3782 /* keep compiler happy */
3790 /* GetDirectBufferCapacity *****************************************************
3792 Fetches and returns the capacity in bytes of the memory region
3793 referenced by the given direct java.nio.Buffer.
3795 *******************************************************************************/
3797 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3799 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3801 java_nio_Buffer *nbuf;
3804 STATISTICS(jniinvokation());
3806 o = (java_handle_t *) buf;
3808 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3811 nbuf = (java_nio_Buffer *) o;
3813 LLNI_field_get_val(nbuf, cap, capacity);
3817 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3819 /* keep compiler happy */
3826 /* GetObjectRefType ************************************************************
3828 Returns the type of the object referred to by the obj argument. The
3829 argument obj can either be a local, global or weak global
3832 *******************************************************************************/
3834 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3836 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3842 /* DestroyJavaVM ***************************************************************
3844 Unloads a Java VM and reclaims its resources. Only the main thread
3845 can unload the VM. The system waits until the main thread is only
3846 remaining user thread before it destroys the VM.
3848 *******************************************************************************/
3850 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3854 TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3856 status = vm_destroy(vm);
3862 /* AttachCurrentThread *********************************************************
3864 Attaches the current thread to a Java VM. Returns a JNI interface
3865 pointer in the JNIEnv argument.
3867 Trying to attach a thread that is already attached is a no-op.
3869 A native thread cannot be attached simultaneously to two Java VMs.
3871 When a thread is attached to the VM, the context class loader is
3872 the bootstrap loader.
3874 *******************************************************************************/
3876 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3878 JavaVMAttachArgs *vm_aargs;
3880 #if defined(ENABLE_THREADS)
3881 if (threads_get_current_threadobject() == NULL) {
3882 vm_aargs = (JavaVMAttachArgs *) thr_args;
3884 if (vm_aargs != NULL) {
3885 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3886 (vm_aargs->version != JNI_VERSION_1_4))
3887 return JNI_EVERSION;
3890 if (!threads_attach_current_thread(vm_aargs, false))
3893 if (!localref_table_init())
3904 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3906 STATISTICS(jniinvokation());
3908 return jni_attach_current_thread(p_env, thr_args, false);
3912 /* DetachCurrentThread *********************************************************
3914 Detaches the current thread from a Java VM. All Java monitors held
3915 by this thread are released. All Java threads waiting for this
3916 thread to die are notified.
3918 In JDK 1.1, the main thread cannot be detached from the VM. It must
3919 call DestroyJavaVM to unload the entire VM.
3921 In the JDK, the main thread can be detached from the VM.
3923 The main thread, which is the thread that created the Java VM,
3924 cannot be detached from the VM. Instead, the main thread must call
3925 JNI_DestroyJavaVM() to unload the entire VM.
3927 *******************************************************************************/
3929 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3931 #if defined(ENABLE_THREADS)
3932 threadobject *thread;
3934 STATISTICS(jniinvokation());
3936 thread = threads_get_current_threadobject();
3941 /* We need to pop all frames before we can destroy the table. */
3943 localref_frame_pop_all();
3945 if (!localref_table_destroy())
3948 if (!threads_detach_thread(thread))
3956 /* GetEnv **********************************************************************
3958 If the current thread is not attached to the VM, sets *env to NULL,
3959 and returns JNI_EDETACHED. If the specified version is not
3960 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3961 sets *env to the appropriate interface, and returns JNI_OK.
3963 *******************************************************************************/
3965 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3967 STATISTICS(jniinvokation());
3969 #if defined(ENABLE_THREADS)
3970 if (threads_get_current_threadobject() == NULL) {
3973 return JNI_EDETACHED;
3977 /* check the JNI version */
3980 case JNI_VERSION_1_1:
3981 case JNI_VERSION_1_2:
3982 case JNI_VERSION_1_4:
3990 #if defined(ENABLE_JVMTI)
3991 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3992 == JVMTI_VERSION_INTERFACE_JVMTI) {
3994 *env = (void *) jvmti_new_environment();
4003 return JNI_EVERSION;
4007 /* AttachCurrentThreadAsDaemon *************************************************
4009 Same semantics as AttachCurrentThread, but the newly-created
4010 java.lang.Thread instance is a daemon.
4012 If the thread has already been attached via either
4013 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
4014 simply sets the value pointed to by penv to the JNIEnv of the
4015 current thread. In this case neither AttachCurrentThread nor this
4016 routine have any effect on the daemon status of the thread.
4018 *******************************************************************************/
4020 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
4022 STATISTICS(jniinvokation());
4024 return jni_attach_current_thread(penv, args, true);
4028 /* JNI invocation table *******************************************************/
4030 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4035 _Jv_JNI_DestroyJavaVM,
4036 _Jv_JNI_AttachCurrentThread,
4037 _Jv_JNI_DetachCurrentThread,
4039 _Jv_JNI_AttachCurrentThreadAsDaemon
4043 /* JNI function table *********************************************************/
4045 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4052 _Jv_JNI_DefineClass,
4054 _Jv_JNI_FromReflectedMethod,
4055 _Jv_JNI_FromReflectedField,
4056 _Jv_JNI_ToReflectedMethod,
4057 _Jv_JNI_GetSuperclass,
4058 _Jv_JNI_IsAssignableFrom,
4059 _Jv_JNI_ToReflectedField,
4063 _Jv_JNI_ExceptionOccurred,
4064 _Jv_JNI_ExceptionDescribe,
4065 _Jv_JNI_ExceptionClear,
4067 _Jv_JNI_PushLocalFrame,
4068 _Jv_JNI_PopLocalFrame,
4070 _Jv_JNI_NewGlobalRef,
4071 _Jv_JNI_DeleteGlobalRef,
4072 _Jv_JNI_DeleteLocalRef,
4073 _Jv_JNI_IsSameObject,
4074 _Jv_JNI_NewLocalRef,
4075 _Jv_JNI_EnsureLocalCapacity,
4077 _Jv_JNI_AllocObject,
4082 _Jv_JNI_GetObjectClass,
4083 _Jv_JNI_IsInstanceOf,
4085 _Jv_JNI_GetMethodID,
4087 _Jv_JNI_CallObjectMethod,
4088 _Jv_JNI_CallObjectMethodV,
4089 _Jv_JNI_CallObjectMethodA,
4090 _Jv_JNI_CallBooleanMethod,
4091 _Jv_JNI_CallBooleanMethodV,
4092 _Jv_JNI_CallBooleanMethodA,
4093 _Jv_JNI_CallByteMethod,
4094 _Jv_JNI_CallByteMethodV,
4095 _Jv_JNI_CallByteMethodA,
4096 _Jv_JNI_CallCharMethod,
4097 _Jv_JNI_CallCharMethodV,
4098 _Jv_JNI_CallCharMethodA,
4099 _Jv_JNI_CallShortMethod,
4100 _Jv_JNI_CallShortMethodV,
4101 _Jv_JNI_CallShortMethodA,
4102 _Jv_JNI_CallIntMethod,
4103 _Jv_JNI_CallIntMethodV,
4104 _Jv_JNI_CallIntMethodA,
4105 _Jv_JNI_CallLongMethod,
4106 _Jv_JNI_CallLongMethodV,
4107 _Jv_JNI_CallLongMethodA,
4108 _Jv_JNI_CallFloatMethod,
4109 _Jv_JNI_CallFloatMethodV,
4110 _Jv_JNI_CallFloatMethodA,
4111 _Jv_JNI_CallDoubleMethod,
4112 _Jv_JNI_CallDoubleMethodV,
4113 _Jv_JNI_CallDoubleMethodA,
4114 _Jv_JNI_CallVoidMethod,
4115 _Jv_JNI_CallVoidMethodV,
4116 _Jv_JNI_CallVoidMethodA,
4118 _Jv_JNI_CallNonvirtualObjectMethod,
4119 _Jv_JNI_CallNonvirtualObjectMethodV,
4120 _Jv_JNI_CallNonvirtualObjectMethodA,
4121 _Jv_JNI_CallNonvirtualBooleanMethod,
4122 _Jv_JNI_CallNonvirtualBooleanMethodV,
4123 _Jv_JNI_CallNonvirtualBooleanMethodA,
4124 _Jv_JNI_CallNonvirtualByteMethod,
4125 _Jv_JNI_CallNonvirtualByteMethodV,
4126 _Jv_JNI_CallNonvirtualByteMethodA,
4127 _Jv_JNI_CallNonvirtualCharMethod,
4128 _Jv_JNI_CallNonvirtualCharMethodV,
4129 _Jv_JNI_CallNonvirtualCharMethodA,
4130 _Jv_JNI_CallNonvirtualShortMethod,
4131 _Jv_JNI_CallNonvirtualShortMethodV,
4132 _Jv_JNI_CallNonvirtualShortMethodA,
4133 _Jv_JNI_CallNonvirtualIntMethod,
4134 _Jv_JNI_CallNonvirtualIntMethodV,
4135 _Jv_JNI_CallNonvirtualIntMethodA,
4136 _Jv_JNI_CallNonvirtualLongMethod,
4137 _Jv_JNI_CallNonvirtualLongMethodV,
4138 _Jv_JNI_CallNonvirtualLongMethodA,
4139 _Jv_JNI_CallNonvirtualFloatMethod,
4140 _Jv_JNI_CallNonvirtualFloatMethodV,
4141 _Jv_JNI_CallNonvirtualFloatMethodA,
4142 _Jv_JNI_CallNonvirtualDoubleMethod,
4143 _Jv_JNI_CallNonvirtualDoubleMethodV,
4144 _Jv_JNI_CallNonvirtualDoubleMethodA,
4145 _Jv_JNI_CallNonvirtualVoidMethod,
4146 _Jv_JNI_CallNonvirtualVoidMethodV,
4147 _Jv_JNI_CallNonvirtualVoidMethodA,
4151 _Jv_JNI_GetObjectField,
4152 _Jv_JNI_GetBooleanField,
4153 _Jv_JNI_GetByteField,
4154 _Jv_JNI_GetCharField,
4155 _Jv_JNI_GetShortField,
4156 _Jv_JNI_GetIntField,
4157 _Jv_JNI_GetLongField,
4158 _Jv_JNI_GetFloatField,
4159 _Jv_JNI_GetDoubleField,
4160 _Jv_JNI_SetObjectField,
4161 _Jv_JNI_SetBooleanField,
4162 _Jv_JNI_SetByteField,
4163 _Jv_JNI_SetCharField,
4164 _Jv_JNI_SetShortField,
4165 _Jv_JNI_SetIntField,
4166 _Jv_JNI_SetLongField,
4167 _Jv_JNI_SetFloatField,
4168 _Jv_JNI_SetDoubleField,
4170 _Jv_JNI_GetStaticMethodID,
4172 _Jv_JNI_CallStaticObjectMethod,
4173 _Jv_JNI_CallStaticObjectMethodV,
4174 _Jv_JNI_CallStaticObjectMethodA,
4175 _Jv_JNI_CallStaticBooleanMethod,
4176 _Jv_JNI_CallStaticBooleanMethodV,
4177 _Jv_JNI_CallStaticBooleanMethodA,
4178 _Jv_JNI_CallStaticByteMethod,
4179 _Jv_JNI_CallStaticByteMethodV,
4180 _Jv_JNI_CallStaticByteMethodA,
4181 _Jv_JNI_CallStaticCharMethod,
4182 _Jv_JNI_CallStaticCharMethodV,
4183 _Jv_JNI_CallStaticCharMethodA,
4184 _Jv_JNI_CallStaticShortMethod,
4185 _Jv_JNI_CallStaticShortMethodV,
4186 _Jv_JNI_CallStaticShortMethodA,
4187 _Jv_JNI_CallStaticIntMethod,
4188 _Jv_JNI_CallStaticIntMethodV,
4189 _Jv_JNI_CallStaticIntMethodA,
4190 _Jv_JNI_CallStaticLongMethod,
4191 _Jv_JNI_CallStaticLongMethodV,
4192 _Jv_JNI_CallStaticLongMethodA,
4193 _Jv_JNI_CallStaticFloatMethod,
4194 _Jv_JNI_CallStaticFloatMethodV,
4195 _Jv_JNI_CallStaticFloatMethodA,
4196 _Jv_JNI_CallStaticDoubleMethod,
4197 _Jv_JNI_CallStaticDoubleMethodV,
4198 _Jv_JNI_CallStaticDoubleMethodA,
4199 _Jv_JNI_CallStaticVoidMethod,
4200 _Jv_JNI_CallStaticVoidMethodV,
4201 _Jv_JNI_CallStaticVoidMethodA,
4203 _Jv_JNI_GetStaticFieldID,
4205 _Jv_JNI_GetStaticObjectField,
4206 _Jv_JNI_GetStaticBooleanField,
4207 _Jv_JNI_GetStaticByteField,
4208 _Jv_JNI_GetStaticCharField,
4209 _Jv_JNI_GetStaticShortField,
4210 _Jv_JNI_GetStaticIntField,
4211 _Jv_JNI_GetStaticLongField,
4212 _Jv_JNI_GetStaticFloatField,
4213 _Jv_JNI_GetStaticDoubleField,
4214 _Jv_JNI_SetStaticObjectField,
4215 _Jv_JNI_SetStaticBooleanField,
4216 _Jv_JNI_SetStaticByteField,
4217 _Jv_JNI_SetStaticCharField,
4218 _Jv_JNI_SetStaticShortField,
4219 _Jv_JNI_SetStaticIntField,
4220 _Jv_JNI_SetStaticLongField,
4221 _Jv_JNI_SetStaticFloatField,
4222 _Jv_JNI_SetStaticDoubleField,
4225 _Jv_JNI_GetStringLength,
4226 _Jv_JNI_GetStringChars,
4227 _Jv_JNI_ReleaseStringChars,
4229 _Jv_JNI_NewStringUTF,
4230 _Jv_JNI_GetStringUTFLength,
4231 _Jv_JNI_GetStringUTFChars,
4232 _Jv_JNI_ReleaseStringUTFChars,
4234 _Jv_JNI_GetArrayLength,
4236 _Jv_JNI_NewObjectArray,
4237 _Jv_JNI_GetObjectArrayElement,
4238 _Jv_JNI_SetObjectArrayElement,
4240 _Jv_JNI_NewBooleanArray,
4241 _Jv_JNI_NewByteArray,
4242 _Jv_JNI_NewCharArray,
4243 _Jv_JNI_NewShortArray,
4244 _Jv_JNI_NewIntArray,
4245 _Jv_JNI_NewLongArray,
4246 _Jv_JNI_NewFloatArray,
4247 _Jv_JNI_NewDoubleArray,
4249 _Jv_JNI_GetBooleanArrayElements,
4250 _Jv_JNI_GetByteArrayElements,
4251 _Jv_JNI_GetCharArrayElements,
4252 _Jv_JNI_GetShortArrayElements,
4253 _Jv_JNI_GetIntArrayElements,
4254 _Jv_JNI_GetLongArrayElements,
4255 _Jv_JNI_GetFloatArrayElements,
4256 _Jv_JNI_GetDoubleArrayElements,
4258 _Jv_JNI_ReleaseBooleanArrayElements,
4259 _Jv_JNI_ReleaseByteArrayElements,
4260 _Jv_JNI_ReleaseCharArrayElements,
4261 _Jv_JNI_ReleaseShortArrayElements,
4262 _Jv_JNI_ReleaseIntArrayElements,
4263 _Jv_JNI_ReleaseLongArrayElements,
4264 _Jv_JNI_ReleaseFloatArrayElements,
4265 _Jv_JNI_ReleaseDoubleArrayElements,
4267 _Jv_JNI_GetBooleanArrayRegion,
4268 _Jv_JNI_GetByteArrayRegion,
4269 _Jv_JNI_GetCharArrayRegion,
4270 _Jv_JNI_GetShortArrayRegion,
4271 _Jv_JNI_GetIntArrayRegion,
4272 _Jv_JNI_GetLongArrayRegion,
4273 _Jv_JNI_GetFloatArrayRegion,
4274 _Jv_JNI_GetDoubleArrayRegion,
4275 _Jv_JNI_SetBooleanArrayRegion,
4276 _Jv_JNI_SetByteArrayRegion,
4277 _Jv_JNI_SetCharArrayRegion,
4278 _Jv_JNI_SetShortArrayRegion,
4279 _Jv_JNI_SetIntArrayRegion,
4280 _Jv_JNI_SetLongArrayRegion,
4281 _Jv_JNI_SetFloatArrayRegion,
4282 _Jv_JNI_SetDoubleArrayRegion,
4284 _Jv_JNI_RegisterNatives,
4285 _Jv_JNI_UnregisterNatives,
4287 _Jv_JNI_MonitorEnter,
4288 _Jv_JNI_MonitorExit,
4292 /* New JNI 1.2 functions. */
4294 _Jv_JNI_GetStringRegion,
4295 _Jv_JNI_GetStringUTFRegion,
4297 _Jv_JNI_GetPrimitiveArrayCritical,
4298 _Jv_JNI_ReleasePrimitiveArrayCritical,
4300 _Jv_JNI_GetStringCritical,
4301 _Jv_JNI_ReleaseStringCritical,
4303 _Jv_JNI_NewWeakGlobalRef,
4304 _Jv_JNI_DeleteWeakGlobalRef,
4306 _Jv_JNI_ExceptionCheck,
4308 /* New JNI 1.4 functions. */
4310 _Jv_JNI_NewDirectByteBuffer,
4311 _Jv_JNI_GetDirectBufferAddress,
4312 _Jv_JNI_GetDirectBufferCapacity,
4314 /* New JNI 1.6 functions. */
4316 jni_GetObjectRefType
4320 /* Invocation API Functions ***************************************************/
4322 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4324 Returns a default configuration for the Java VM.
4326 *******************************************************************************/
4328 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4330 JavaVMInitArgs *_vm_args;
4332 _vm_args = (JavaVMInitArgs *) vm_args;
4334 /* GNU classpath currently supports JNI 1.2 */
4336 switch (_vm_args->version) {
4337 case JNI_VERSION_1_1:
4338 _vm_args->version = JNI_VERSION_1_1;
4341 case JNI_VERSION_1_2:
4342 case JNI_VERSION_1_4:
4343 _vm_args->ignoreUnrecognized = JNI_FALSE;
4344 _vm_args->options = NULL;
4345 _vm_args->nOptions = 0;
4356 /* JNI_GetCreatedJavaVMs *******************************************************
4358 Returns all Java VMs that have been created. Pointers to VMs are written in
4359 the buffer vmBuf in the order they are created. At most bufLen number of
4360 entries will be written. The total number of created VMs is returned in
4363 *******************************************************************************/
4365 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4367 TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4372 /* We currently only support 1 VM running. */
4374 vmBuf[0] = (JavaVM *) _Jv_jvm;
4381 /* JNI_CreateJavaVM ************************************************************
4383 Loads and initializes a Java VM. The current thread becomes the main thread.
4384 Sets the env argument to the JNI interface pointer of the main thread.
4386 *******************************************************************************/
4388 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4390 TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4392 /* actually create the JVM */
4394 if (!vm_createjvm(p_vm, p_env, vm_args))
4402 * These are local overrides for various environment variables in Emacs.
4403 * Please do not remove this and leave it at the end of the file, where
4404 * Emacs will automagically detect them.
4405 * ---------------------------------------------------------------------
4408 * indent-tabs-mode: t
4412 * vim:noexpandtab:sw=4:ts=4: